9 static const char *ast_type_str
[] = {
10 [an_assign
] = "assign", [an_bool
] = "bool", [an_binop
] = "binop",
11 [an_char
] = "char", [an_cons
] = "cons", [an_funcall
] = "funcall",
12 [an_fundecl
] = "fundecl", [an_ident
] = "ident", [an_if
] = "if",
13 [an_int
] = "int", [an_nil
] = "nil", [an_list
] = "list",
14 [an_return
] = "return", [an_stmt_expr
] = "stmt_expr",
15 [an_tuple
] = "tuple", [an_unop
] = "unop", [an_vardecl
] = "vardecl",
19 static const char *binop_str
[] = {
20 [binor
] = "||", [binand
] = "&&", [eq
] = "==", [neq
] = "!=",
21 [leq
] = "<=", [le
] = "<", [geq
] = ">=", [ge
] = ">", [cons
] = ":",
22 [plus
] = "+", [minus
] = "-", [times
] = "*", [divide
] = "/",
23 [modulo
] = "%", [power
] = "^",
25 static const char *fieldspec_str
[] = {
26 [fst
] = "fst", [snd
] = "snd", [hd
] = "hd", [tl
] = "tl"};
27 static const char *unop_str
[] = { [inverse
] = "!", [negate
] = "-", };
30 #define must_be(node, ntype, msg) {\
31 if ((node)->type != (ntype)) {\
32 fprintf(stderr, "%s can't be %s\n",\
33 msg, ast_type_str[node->type]);\
38 #define must_be(node, ntype, msg) ;
41 #define ast_alloc() ((struct ast *)safe_malloc(sizeof(struct ast)))
43 struct ast
*ast_assign(struct ast
*ident
, struct ast
*expr
)
45 struct ast
*res
= ast_alloc();
46 res
->type
= an_assign
;
47 res
->data
.an_assign
.ident
= ident
;
48 res
->data
.an_assign
.expr
= expr
;
52 struct ast
*ast_binop(struct ast
*l
, enum binop op
, struct ast
*r
)
54 struct ast
*res
= ast_alloc();
56 res
->data
.an_binop
.l
= l
;
57 res
->data
.an_binop
.op
= op
;
58 res
->data
.an_binop
.r
= r
;
62 struct ast
*ast_bool(bool b
)
64 struct ast
*res
= ast_alloc();
66 res
->data
.an_bool
= b
;
72 if (c
>= '0' && c
<= '9')
74 if (c
>= 'a' && c
<= 'f')
76 if (c
>= 'A' && c
<= 'F')
81 struct ast
*ast_char(const char *c
)
83 struct ast
*res
= ast_alloc();
87 res
->data
.an_char
= c
[1];
91 case '0': res
->data
.an_char
= '\0'; break;
92 case 'a': res
->data
.an_char
= '\a'; break;
93 case 'b': res
->data
.an_char
= '\b'; break;
94 case 't': res
->data
.an_char
= '\t'; break;
95 case 'v': res
->data
.an_char
= '\v'; break;
96 case 'f': res
->data
.an_char
= '\f'; break;
97 case 'r': res
->data
.an_char
= '\r'; break;
101 res
->data
.an_char
= (fromHex(c
[3])<<4)+fromHex(c
[4]);
105 struct ast
*ast_cons(struct ast
*el
, struct ast
*tail
)
107 struct ast
*res
= ast_alloc();
109 res
->data
.an_cons
.el
= el
;
110 res
->data
.an_cons
.tail
= tail
;
114 struct ast
*ast_funcall(struct ast
*ident
, struct ast
*args
)
116 struct ast
*res
= ast_alloc();
117 res
->type
= an_funcall
;
120 must_be(ident
, an_ident
, "ident of a funcall");
121 res
->data
.an_funcall
.ident
= ident
->data
.an_ident
.ident
;
122 free(ident
->data
.an_ident
.fields
);
126 must_be(args
, an_list
, "args of a funcall");
127 res
->data
.an_funcall
.nargs
= args
->data
.an_list
.n
;
128 res
->data
.an_funcall
.args
= args
->data
.an_list
.ptr
;
133 struct ast
*ast_fundecl(struct ast
*ident
, struct ast
*args
, struct ast
*body
)
135 struct ast
*res
= ast_alloc();
136 res
->type
= an_fundecl
;
139 must_be(ident
, an_ident
, "ident of a fundecl");
140 res
->data
.an_fundecl
.ident
= ident
->data
.an_ident
.ident
;
141 free(ident
->data
.an_ident
.fields
);
145 must_be(args
, an_list
, "args of a fundecl");
146 res
->data
.an_fundecl
.nargs
= args
->data
.an_list
.n
;
147 res
->data
.an_fundecl
.args
= (char **)args
->data
.an_list
.ptr
;
148 for (int i
= 0; i
<args
->data
.an_list
.n
; i
++) {
149 struct ast
*e
= args
->data
.an_list
.ptr
[i
];
150 must_be(e
, an_ident
, "arg of a fundecl")
151 res
->data
.an_fundecl
.args
[i
] = e
->data
.an_ident
.ident
;
152 free(e
->data
.an_ident
.fields
);
158 must_be(body
, an_list
, "body of a fundecl");
159 res
->data
.an_fundecl
.nbody
= body
->data
.an_list
.n
;
160 res
->data
.an_fundecl
.body
= body
->data
.an_list
.ptr
;
166 struct ast
*ast_if(struct ast
*pred
, struct ast
*then
, struct ast
*els
)
168 struct ast
*res
= ast_alloc();
170 res
->data
.an_if
.pred
= pred
;
172 must_be(then
, an_list
, "body of a then");
173 res
->data
.an_if
.nthen
= then
->data
.an_list
.n
;
174 res
->data
.an_if
.then
= then
->data
.an_list
.ptr
;
177 must_be(els
, an_list
, "body of a els");
178 res
->data
.an_if
.nels
= els
->data
.an_list
.n
;
179 res
->data
.an_if
.els
= els
->data
.an_list
.ptr
;
185 struct ast
*ast_int(int integer
)
187 struct ast
*res
= ast_alloc();
189 res
->data
.an_int
= integer
;
193 struct ast
*ast_identc(char *ident
)
195 struct ast
*res
= ast_alloc();
196 res
->type
= an_ident
;
197 res
->data
.an_ident
.ident
= safe_strdup(ident
);
198 res
->data
.an_ident
.nfields
= 0;
199 res
->data
.an_ident
.fields
= NULL
;
203 struct ast
*ast_ident(struct ast
*ident
, struct ast
*fields
)
205 struct ast
*res
= ast_alloc();
206 res
->type
= an_ident
;
207 must_be(fields
, an_ident
, "ident of an ident");
208 res
->data
.an_ident
.ident
= ident
->data
.an_ident
.ident
;
211 must_be(fields
, an_list
, "fields of an ident");
212 res
->data
.an_ident
.nfields
= fields
->data
.an_list
.n
;
213 res
->data
.an_ident
.fields
= (enum fieldspec
*)safe_malloc(
214 fields
->data
.an_list
.n
*sizeof(enum fieldspec
));
215 for (int i
= 0; i
<fields
->data
.an_list
.n
; i
++) {
216 struct ast
*t
= fields
->data
.an_list
.ptr
[i
];
217 must_be(t
, an_ident
, "field of an ident");
218 if (strcmp(t
->data
.an_ident
.ident
, "fst") == 0)
219 res
->data
.an_ident
.fields
[i
] = fst
;
220 else if (strcmp(t
->data
.an_ident
.ident
, "snd") == 0)
221 res
->data
.an_ident
.fields
[i
] = snd
;
222 else if (strcmp(t
->data
.an_ident
.ident
, "hd") == 0)
223 res
->data
.an_ident
.fields
[i
] = hd
;
224 else if (strcmp(t
->data
.an_ident
.ident
, "tl") == 0)
225 res
->data
.an_ident
.fields
[i
] = tl
;
226 free(t
->data
.an_ident
.ident
);
229 free(fields
->data
.an_list
.ptr
);
234 struct ast
*ast_list(struct ast
*llist
)
236 struct ast
*res
= ast_alloc();
238 res
->data
.an_list
.n
= 0;
240 int i
= ast_llistlength(llist
);
243 res
->data
.an_list
.n
= i
;
244 res
->data
.an_list
.ptr
= (struct ast
**)safe_malloc(
245 res
->data
.an_list
.n
*sizeof(struct ast
*));
247 struct ast
*r
= llist
;
249 res
->data
.an_list
.ptr
[--i
] = r
->data
.an_cons
.el
;
251 r
= r
->data
.an_cons
.tail
;
257 struct ast
*ast_nil()
259 struct ast
*res
= ast_alloc();
264 struct ast
*ast_return(struct ast
*r
)
266 struct ast
*res
= ast_alloc();
267 res
->type
= an_return
;
268 res
->data
.an_return
= r
;
272 struct ast
*ast_stmt_expr(struct ast
*expr
)
274 struct ast
*res
= ast_alloc();
275 res
->type
= an_stmt_expr
;
276 res
->data
.an_stmt_expr
= expr
;
280 struct ast
*ast_tuple(struct ast
*left
, struct ast
*right
)
282 struct ast
*res
= ast_alloc();
283 res
->type
= an_tuple
;
284 res
->data
.an_tuple
.left
= left
;
285 res
->data
.an_tuple
.right
= right
;
290 struct ast
*ast_unop(enum unop op
, struct ast
*l
)
292 struct ast
*res
= ast_alloc();
294 res
->data
.an_unop
.op
= op
;
295 res
->data
.an_unop
.l
= l
;
299 struct ast
*ast_vardecl(struct ast
*ident
, struct ast
*l
)
301 struct ast
*res
= ast_alloc();
302 res
->type
= an_vardecl
;
303 must_be(ident
, an_ident
, "ident of a vardecl");
305 res
->data
.an_vardecl
.ident
= ident
->data
.an_ident
.ident
;
306 free(ident
->data
.an_ident
.fields
);
308 res
->data
.an_vardecl
.l
= l
;
312 struct ast
*ast_while(struct ast
*pred
, struct ast
*body
)
314 struct ast
*res
= ast_alloc();
315 res
->type
= an_while
;
316 res
->data
.an_while
.pred
= pred
;
317 must_be(body
, an_list
, "body of a while");
318 res
->data
.an_while
.nbody
= body
->data
.an_list
.n
;
319 res
->data
.an_while
.body
= body
->data
.an_list
.ptr
;
324 int ast_llistlength(struct ast
*r
)
329 if (r
->type
!= an_cons
) {
332 r
= r
->data
.an_cons
.tail
;
337 const char *cescapes
[] = {
338 [0] = "\\0", [1] = "\\x01", [2] = "\\x02", [3] = "\\x03",
339 [4] = "\\x04", [5] = "\\x05", [6] = "\\x06", [7] = "\\a", [8] = "\\b",
340 [9] = "\\t", [10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r",
341 [14] = "\\x0E", [15] = "\\x0F", [16] = "\\x10", [17] = "\\x11",
342 [18] = "\\x12", [19] = "\\x13", [20] = "\\x14", [21] = "\\x15",
343 [22] = "\\x16", [23] = "\\x17", [24] = "\\x18", [25] = "\\x19",
344 [26] = "\\x1A", [27] = "\\x1B", [28] = "\\x1C", [29] = "\\x1D",
345 [30] = "\\x1E", [31] = "\\x1F",
349 void ast_print(struct ast
*ast
, int indent
, FILE *out
)
354 fprintf(stderr
, "ast_free(%s)\n", ast_type_str
[ast
->type
]);
358 pindent(indent
, out
);
359 ast_print(ast
->data
.an_assign
.ident
, indent
, out
);
360 safe_fprintf(out
, " = ");
361 ast_print(ast
->data
.an_assign
.expr
, indent
, out
);
362 safe_fprintf(out
, ";\n");
365 safe_fprintf(out
, "(");
366 ast_print(ast
->data
.an_binop
.l
, indent
, out
);
367 safe_fprintf(out
, "%s", binop_str
[ast
->data
.an_binop
.op
]);
368 ast_print(ast
->data
.an_binop
.r
, indent
, out
);
369 safe_fprintf(out
, ")");
372 safe_fprintf(out
, "%s", ast
->data
.an_bool
? "true" : "false");
375 if (ast
->data
.an_char
< 0)
376 safe_fprintf(out
, "'?'");
377 if (ast
->data
.an_char
< ' ' || ast
->data
.an_char
== 127)
378 safe_fprintf(out
, "'%s'",
379 cescapes
[(int)ast
->data
.an_char
]);
381 safe_fprintf(out
, "'%c'", ast
->data
.an_char
);
384 safe_fprintf(out
, "%s(", ast
->data
.an_funcall
.ident
);
385 for(int i
= 0; i
<ast
->data
.an_fundecl
.nargs
; i
++) {
386 ast_print(ast
->data
.an_funcall
.args
[i
], indent
, out
);
387 if (i
+1 < ast
->data
.an_fundecl
.nargs
)
388 safe_fprintf(out
, ", ");
390 safe_fprintf(out
, ")");
393 pindent(indent
, out
);
394 safe_fprintf(out
, "%s (", ast
->data
.an_fundecl
.ident
);
395 for (int i
= 0; i
<ast
->data
.an_fundecl
.nargs
; i
++) {
396 safe_fprintf(out
, "%s", ast
->data
.an_fundecl
.args
[i
]);
397 if (i
< ast
->data
.an_fundecl
.nargs
- 1)
398 safe_fprintf(out
, ", ");
400 safe_fprintf(out
, ") {\n");
401 for (int i
= 0; i
<ast
->data
.an_fundecl
.nbody
; i
++)
402 ast_print(ast
->data
.an_fundecl
.body
[i
], indent
+1, out
);
403 pindent(indent
, out
);
404 safe_fprintf(out
, "}\n");
407 pindent(indent
, out
);
408 safe_fprintf(out
, "if (");
409 ast_print(ast
->data
.an_if
.pred
, indent
, out
);
410 safe_fprintf(out
, ") {\n");
411 for (int i
= 0; i
<ast
->data
.an_if
.nthen
; i
++)
412 ast_print(ast
->data
.an_if
.then
[i
], indent
+1, out
);
413 pindent(indent
, out
);
414 safe_fprintf(out
, "} else {\n");
415 for (int i
= 0; i
<ast
->data
.an_if
.nels
; i
++)
416 ast_print(ast
->data
.an_if
.els
[i
], indent
+1, out
);
417 pindent(indent
, out
);
418 safe_fprintf(out
, "}\n");
421 safe_fprintf(out
, "%d", ast
->data
.an_int
);
424 fprintf(out
, "%s", ast
->data
.an_ident
.ident
);
425 for (int i
= 0; i
<ast
->data
.an_ident
.nfields
; i
++)
427 fieldspec_str
[ast
->data
.an_ident
.fields
[i
]]);
430 ast_print(ast
->data
.an_cons
.el
, indent
, out
);
431 ast_print(ast
->data
.an_cons
.tail
, indent
, out
);
434 for (int i
= 0; i
<ast
->data
.an_list
.n
; i
++)
435 ast_print(ast
->data
.an_list
.ptr
[i
], indent
, out
);
438 safe_fprintf(out
, "[]");
441 pindent(indent
, out
);
442 safe_fprintf(out
, "return ");
443 ast_print(ast
->data
.an_return
, indent
, out
);
444 safe_fprintf(out
, ";\n");
447 pindent(indent
, out
);
448 ast_print(ast
->data
.an_stmt_expr
, indent
, out
);
449 safe_fprintf(out
, ";\n");
452 safe_fprintf(out
, "(");
453 ast_print(ast
->data
.an_tuple
.left
, indent
, out
);
454 safe_fprintf(out
, ", ");
455 ast_print(ast
->data
.an_tuple
.right
, indent
, out
);
456 safe_fprintf(out
, ")");
459 safe_fprintf(out
, "(%s", unop_str
[ast
->data
.an_unop
.op
]);
460 ast_print(ast
->data
.an_unop
.l
, indent
, out
);
461 safe_fprintf(out
, ")");
464 pindent(indent
, out
);
465 safe_fprintf(out
, "var %s = ", ast
->data
.an_vardecl
.ident
);
466 ast_print(ast
->data
.an_vardecl
.l
, indent
, out
);
467 safe_fprintf(out
, ";\n");
470 pindent(indent
, out
);
471 safe_fprintf(out
, "while (");
472 ast_print(ast
->data
.an_while
.pred
, indent
, out
);
473 safe_fprintf(out
, ") {\n");
474 for (int i
= 0; i
<ast
->data
.an_while
.nbody
; i
++) {
475 ast_print(ast
->data
.an_while
.body
[i
], indent
+1, out
);
477 pindent(indent
, out
);
478 safe_fprintf(out
, "}\n");
481 die("Unsupported AST node\n");
485 void ast_free(struct ast
*ast
)
490 fprintf(stderr
, "ast_free(%s)\n", ast_type_str
[ast
->type
]);
494 ast_free(ast
->data
.an_assign
.ident
);
495 ast_free(ast
->data
.an_assign
.expr
);
498 ast_free(ast
->data
.an_binop
.l
);
499 ast_free(ast
->data
.an_binop
.r
);
506 ast_free(ast
->data
.an_cons
.el
);
507 ast_free(ast
->data
.an_cons
.tail
);
510 free(ast
->data
.an_funcall
.ident
);
511 for (int i
= 0; i
<ast
->data
.an_fundecl
.nargs
; i
++)
512 ast_free(ast
->data
.an_funcall
.args
[i
]);
513 free(ast
->data
.an_funcall
.args
);
516 free(ast
->data
.an_fundecl
.ident
);
517 for (int i
= 0; i
<ast
->data
.an_fundecl
.nargs
; i
++)
518 free(ast
->data
.an_fundecl
.args
[i
]);
519 free(ast
->data
.an_fundecl
.args
);
520 for (int i
= 0; i
<ast
->data
.an_fundecl
.nbody
; i
++)
521 ast_free(ast
->data
.an_fundecl
.body
[i
]);
522 free(ast
->data
.an_fundecl
.body
);
525 ast_free(ast
->data
.an_if
.pred
);
526 for (int i
= 0; i
<ast
->data
.an_if
.nthen
; i
++)
527 ast_free(ast
->data
.an_if
.then
[i
]);
528 free(ast
->data
.an_if
.then
);
529 for (int i
= 0; i
<ast
->data
.an_if
.nels
; i
++)
530 ast_free(ast
->data
.an_if
.els
[i
]);
531 free(ast
->data
.an_if
.els
);
536 free(ast
->data
.an_ident
.ident
);
537 free(ast
->data
.an_ident
.fields
);
540 for (int i
= 0; i
<ast
->data
.an_list
.n
; i
++)
541 ast_free(ast
->data
.an_list
.ptr
[i
]);
542 free(ast
->data
.an_list
.ptr
);
547 ast_free(ast
->data
.an_return
);
550 ast_free(ast
->data
.an_stmt_expr
);
553 ast_free(ast
->data
.an_tuple
.left
);
554 ast_free(ast
->data
.an_tuple
.right
);
557 ast_free(ast
->data
.an_unop
.l
);
560 free(ast
->data
.an_vardecl
.ident
);
561 ast_free(ast
->data
.an_vardecl
.l
);
564 ast_free(ast
->data
.an_while
.pred
);
565 for (int i
= 0; i
<ast
->data
.an_while
.nbody
; i
++)
566 ast_free(ast
->data
.an_while
.body
[i
]);
567 free(ast
->data
.an_while
.body
);
570 die("Unsupported AST node: %d\n", ast
->type
);