+
+struct ast *ast_vardecl(struct ast *ident, struct ast *l)
+{
+ struct ast *res = ast_alloc();
+ res->type = an_vardecl;
+ must_be(ident, an_ident, "ident of a vardecl");
+
+ res->data.an_vardecl.ident = ident->data.an_ident;
+ free(ident);
+ res->data.an_vardecl.l = l;
+ return res;
+}
+
+struct ast *ast_while(struct ast *pred, struct ast *body)
+{
+ struct ast *res = ast_alloc();
+ res->type = an_while;
+ res->data.an_while.pred = pred;
+ res->data.an_while.body = body;
+ return res;
+}
+
+int ast_llistlength(struct ast *r)
+{
+ int i = 0;
+ while(r != NULL) {
+ i++;
+ if (r->type != an_cons) {
+ return 1;
+ }
+ r = r->data.an_cons.tail;
+ }
+ return i;
+}
+
+const char *cescapes[] = {
+ [0] = "\\0", [1] = "\\x01", [2] = "\\x02", [3] = "\\x03",
+ [4] = "\\x04", [5] = "\\x05", [6] = "\\x06", [7] = "\\a", [8] = "\\b",
+ [9] = "\\t", [10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r",
+ [14] = "\\x0E", [15] = "\\x0F", [16] = "\\x10", [17] = "\\x11",
+ [18] = "\\x12", [19] = "\\x13", [20] = "\\x14", [21] = "\\x15",
+ [22] = "\\x16", [23] = "\\x17", [24] = "\\x18", [25] = "\\x19",
+ [26] = "\\x1A", [27] = "\\x1B", [28] = "\\x1C", [29] = "\\x1D",
+ [30] = "\\x1E", [31] = "\\x1F",
+ [127] = "\\x7F"