8 static const char *binop_str
[] = {
9 [binor
] = "||", [binand
] = "&&", [eq
] = "==", [neq
] = "!=",
10 [leq
] = "<=", [le
] = "<", [geq
] = ">=", [ge
] = ">", [cons
] = ":",
11 [plus
] = "+", [minus
] = "-", [times
] = "*", [divide
] = "/",
12 [modulo
] = "%", [power
] = "^",
14 static const char *fieldspec_str
[] = {
15 [fst
] = "fst", [snd
] = "snd", [hd
] = "hd", [tl
] = "tl"};
16 static const char *unop_str
[] = { [inverse
] = "!", [negate
] = "-", };
18 struct ast
*ast(struct list
*decls
)
20 struct ast
*res
= safe_malloc(sizeof(struct ast
));
21 res
->decls
= (struct decl
**)list_to_array(decls
, &res
->ndecls
, true);
25 struct vardecl
vardecl(char *ident
, struct expr
*expr
)
27 return (struct vardecl
) {.ident
=ident
, .expr
=expr
};
30 struct decl
*decl_fun(char *ident
, struct list
*args
, struct list
*body
)
32 struct decl
*res
= safe_malloc(sizeof(struct decl
));
34 res
->data
.dfun
.ident
= ident
;
35 res
->data
.dfun
.args
= (char **)
36 list_to_array(args
, &res
->data
.dfun
.nargs
, true);
37 res
->data
.dfun
.body
= (struct stmt
**)
38 list_to_array(body
, &res
->data
.dfun
.nbody
, true);
42 struct decl
*decl_var(struct vardecl vardecl
)
44 struct decl
*res
= safe_malloc(sizeof(struct decl
));
46 res
->data
.dvar
= vardecl
;
50 struct stmt
*stmt_assign(char *ident
, struct expr
*expr
)
52 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
54 res
->data
.sassign
.ident
= ident
;
55 res
->data
.sassign
.expr
= expr
;
59 struct stmt
*stmt_if(struct expr
*pred
, struct list
*then
, struct list
*els
)
61 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
63 res
->data
.sif
.pred
= pred
;
64 res
->data
.sif
.then
= (struct stmt
**)
65 list_to_array(then
, &res
->data
.sif
.nthen
, true);
66 res
->data
.sif
.els
= (struct stmt
**)
67 list_to_array(els
, &res
->data
.sif
.nels
, true);
71 struct stmt
*stmt_return(struct expr
*rtrn
)
73 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
75 res
->data
.sreturn
= rtrn
;
79 struct stmt
*stmt_expr(struct expr
*expr
)
81 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
83 res
->data
.sexpr
= expr
;
87 struct stmt
*stmt_vardecl(struct vardecl vardecl
)
89 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
91 res
->data
.svardecl
= vardecl
;
95 struct stmt
*stmt_while(struct expr
*pred
, struct list
*body
)
97 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
99 res
->data
.swhile
.pred
= pred
;
100 res
->data
.swhile
.body
= (struct stmt
**)
101 list_to_array(body
, &res
->data
.swhile
.nbody
, true);
105 struct expr
*expr_binop(struct expr
*l
, enum binop op
, struct expr
*r
)
107 struct expr
*res
= safe_malloc(sizeof(struct expr
));
109 res
->data
.ebinop
.l
= l
;
110 res
->data
.ebinop
.op
= op
;
111 res
->data
.ebinop
.r
= r
;
115 struct expr
*expr_bool(bool b
)
117 struct expr
*res
= safe_malloc(sizeof(struct expr
));
124 if (c
>= '0' && c
<= '9')
126 if (c
>= 'a' && c
<= 'f')
128 if (c
>= 'A' && c
<= 'F')
133 struct expr
*expr_char(const char *c
)
135 struct expr
*res
= safe_malloc(sizeof(struct expr
));
139 res
->data
.echar
= c
[1];
143 case '0': res
->data
.echar
= '\0'; break;
144 case 'a': res
->data
.echar
= '\a'; break;
145 case 'b': res
->data
.echar
= '\b'; break;
146 case 't': res
->data
.echar
= '\t'; break;
147 case 'v': res
->data
.echar
= '\v'; break;
148 case 'f': res
->data
.echar
= '\f'; break;
149 case 'r': res
->data
.echar
= '\r'; break;
153 res
->data
.echar
= (fromHex(c
[3])<<4)+fromHex(c
[4]);
157 struct expr
*expr_funcall(char *ident
, struct list
*args
)
159 struct expr
*res
= safe_malloc(sizeof(struct expr
));
160 res
->type
= efuncall
;
161 res
->data
.efuncall
.ident
= ident
;
162 res
->data
.efuncall
.args
= (struct expr
**)
163 list_to_array(args
, &res
->data
.efuncall
.nargs
, true);
167 struct expr
*expr_int(int integer
)
169 struct expr
*res
= safe_malloc(sizeof(struct expr
));
171 res
->data
.eint
= integer
;
175 struct expr
*expr_ident(char *ident
, struct list
*fields
)
177 struct expr
*res
= safe_malloc(sizeof(struct expr
));
179 res
->data
.eident
.ident
= ident
;
181 void **els
= list_to_array(fields
, &res
->data
.eident
.nfields
, true);
182 res
->data
.eident
.fields
= (enum fieldspec
*)safe_malloc(
183 res
->data
.eident
.nfields
*sizeof(enum fieldspec
));
184 for (int i
= 0; i
<res
->data
.eident
.nfields
; i
++) {
186 if (strcmp(t
, "fst") == 0)
187 res
->data
.eident
.fields
[i
] = fst
;
188 else if (strcmp(t
, "snd") == 0)
189 res
->data
.eident
.fields
[i
] = snd
;
190 else if (strcmp(t
, "hd") == 0)
191 res
->data
.eident
.fields
[i
] = hd
;
192 else if (strcmp(t
, "tl") == 0)
193 res
->data
.eident
.fields
[i
] = tl
;
200 struct expr
*expr_nil()
202 struct expr
*res
= safe_malloc(sizeof(struct expr
));
207 struct expr
*expr_tuple(struct expr
*left
, struct expr
*right
)
209 struct expr
*res
= safe_malloc(sizeof(struct expr
));
211 res
->data
.etuple
.left
= left
;
212 res
->data
.etuple
.right
= right
;
216 struct expr
*expr_unop(enum unop op
, struct expr
*l
)
218 struct expr
*res
= safe_malloc(sizeof(struct expr
));
220 res
->data
.eunop
.op
= op
;
221 res
->data
.eunop
.l
= l
;
225 const char *cescapes
[] = {
226 [0] = "\\0", [1] = "\\x01", [2] = "\\x02", [3] = "\\x03",
227 [4] = "\\x04", [5] = "\\x05", [6] = "\\x06", [7] = "\\a", [8] = "\\b",
228 [9] = "\\t", [10] = "\\n", [11] = "\\v", [12] = "\\f", [13] = "\\r",
229 [14] = "\\x0E", [15] = "\\x0F", [16] = "\\x10", [17] = "\\x11",
230 [18] = "\\x12", [19] = "\\x13", [20] = "\\x14", [21] = "\\x15",
231 [22] = "\\x16", [23] = "\\x17", [24] = "\\x18", [25] = "\\x19",
232 [26] = "\\x1A", [27] = "\\x1B", [28] = "\\x1C", [29] = "\\x1D",
233 [30] = "\\x1E", [31] = "\\x1F",
237 void ast_print(struct ast
*ast
, FILE *out
)
241 for (int i
= 0; i
<ast
->ndecls
; i
++)
242 decl_print(ast
->decls
[i
], 0, out
);
245 void decl_print(struct decl
*decl
, int indent
, FILE *out
)
251 pindent(indent
, out
);
252 safe_fprintf(out
, "%s (", decl
->data
.dfun
.ident
);
253 for (int i
= 0; i
<decl
->data
.dfun
.nargs
; i
++) {
254 safe_fprintf(out
, "%s", decl
->data
.dfun
.args
[i
]);
255 if (i
< decl
->data
.dfun
.nargs
- 1)
256 safe_fprintf(out
, ", ");
258 safe_fprintf(out
, ") {\n");
259 for (int i
= 0; i
<decl
->data
.dfun
.nbody
; i
++)
260 stmt_print(decl
->data
.dfun
.body
[i
], indent
+1, out
);
261 pindent(indent
, out
);
262 safe_fprintf(out
, "}\n");
265 pindent(indent
, out
);
266 safe_fprintf(out
, "var %s = ", decl
->data
.dvar
.ident
);
267 expr_print(decl
->data
.dvar
.expr
, out
);
268 safe_fprintf(out
, ";\n");
271 die("Unsupported decl node\n");
275 void stmt_print(struct stmt
*stmt
, int indent
, FILE *out
)
281 pindent(indent
, out
);
282 fprintf(out
, "%s", stmt
->data
.sassign
.ident
);
283 safe_fprintf(out
, " = ");
284 expr_print(stmt
->data
.sassign
.expr
, out
);
285 safe_fprintf(out
, ";\n");
288 pindent(indent
, out
);
289 safe_fprintf(out
, "if (");
290 expr_print(stmt
->data
.sif
.pred
, out
);
291 safe_fprintf(out
, ") {\n");
292 for (int i
= 0; i
<stmt
->data
.sif
.nthen
; i
++)
293 stmt_print(stmt
->data
.sif
.then
[i
], indent
+1, out
);
294 pindent(indent
, out
);
295 safe_fprintf(out
, "} else {\n");
296 for (int i
= 0; i
<stmt
->data
.sif
.nels
; i
++)
297 stmt_print(stmt
->data
.sif
.els
[i
], indent
+1, out
);
298 pindent(indent
, out
);
299 safe_fprintf(out
, "}\n");
302 pindent(indent
, out
);
303 safe_fprintf(out
, "return ");
304 expr_print(stmt
->data
.sreturn
, out
);
305 safe_fprintf(out
, ";\n");
308 pindent(indent
, out
);
309 expr_print(stmt
->data
.sexpr
, out
);
310 safe_fprintf(out
, ";\n");
313 pindent(indent
, out
);
314 safe_fprintf(out
, "var %s = ", stmt
->data
.svardecl
.ident
);
315 expr_print(stmt
->data
.svardecl
.expr
, out
);
316 safe_fprintf(out
, ";\n");
319 pindent(indent
, out
);
320 safe_fprintf(out
, "while (");
321 expr_print(stmt
->data
.swhile
.pred
, out
);
322 safe_fprintf(out
, ") {\n");
323 for (int i
= 0; i
<stmt
->data
.swhile
.nbody
; i
++) {
324 stmt_print(stmt
->data
.swhile
.body
[i
], indent
+1, out
);
326 pindent(indent
, out
);
327 safe_fprintf(out
, "}\n");
330 die("Unsupported stmt node\n");
334 void expr_print(struct expr
*expr
, FILE *out
)
340 safe_fprintf(out
, "(");
341 expr_print(expr
->data
.ebinop
.l
, out
);
342 safe_fprintf(out
, "%s", binop_str
[expr
->data
.ebinop
.op
]);
343 expr_print(expr
->data
.ebinop
.r
, out
);
344 safe_fprintf(out
, ")");
347 safe_fprintf(out
, "%s", expr
->data
.ebool
? "true" : "false");
350 if (expr
->data
.echar
< 0)
351 safe_fprintf(out
, "'?'");
352 if (expr
->data
.echar
< ' ' || expr
->data
.echar
== 127)
353 safe_fprintf(out
, "'%s'",
354 cescapes
[(int)expr
->data
.echar
]);
356 safe_fprintf(out
, "'%c'", expr
->data
.echar
);
359 safe_fprintf(out
, "%s(", expr
->data
.efuncall
.ident
);
360 for(int i
= 0; i
<expr
->data
.efuncall
.nargs
; i
++) {
361 expr_print(expr
->data
.efuncall
.args
[i
], out
);
362 if (i
+1 < expr
->data
.efuncall
.nargs
)
363 safe_fprintf(out
, ", ");
365 safe_fprintf(out
, ")");
368 safe_fprintf(out
, "%d", expr
->data
.eint
);
371 fprintf(out
, "%s", expr
->data
.eident
.ident
);
372 for (int i
= 0; i
<expr
->data
.eident
.nfields
; i
++)
374 fieldspec_str
[expr
->data
.eident
.fields
[i
]]);
377 safe_fprintf(out
, "[]");
380 safe_fprintf(out
, "(");
381 expr_print(expr
->data
.etuple
.left
, out
);
382 safe_fprintf(out
, ", ");
383 expr_print(expr
->data
.etuple
.right
, out
);
384 safe_fprintf(out
, ")");
387 safe_fprintf(out
, "(%s", unop_str
[expr
->data
.eunop
.op
]);
388 expr_print(expr
->data
.eunop
.l
, out
);
389 safe_fprintf(out
, ")");
392 die("Unsupported expr node\n");
396 void ast_free(struct ast
*ast
)
400 for (int i
= 0; i
<ast
->ndecls
; i
++)
401 decl_free(ast
->decls
[i
]);
405 void decl_free(struct decl
*decl
)
411 free(decl
->data
.dfun
.ident
);
412 for (int i
= 0; i
<decl
->data
.dfun
.nargs
; i
++)
413 free(decl
->data
.dfun
.args
[i
]);
414 free(decl
->data
.dfun
.args
);
415 for (int i
= 0; i
<decl
->data
.dfun
.nbody
; i
++)
416 stmt_free(decl
->data
.dfun
.body
[i
]);
417 free(decl
->data
.dfun
.body
);
420 free(decl
->data
.dvar
.ident
);
421 expr_free(decl
->data
.dvar
.expr
);
424 die("Unsupported decl node\n");
429 void stmt_free(struct stmt
*stmt
)
435 free(stmt
->data
.sassign
.ident
);
436 expr_free(stmt
->data
.sassign
.expr
);
439 expr_free(stmt
->data
.sif
.pred
);
440 for (int i
= 0; i
<stmt
->data
.sif
.nthen
; i
++)
441 stmt_free(stmt
->data
.sif
.then
[i
]);
442 free(stmt
->data
.sif
.then
);
443 for (int i
= 0; i
<stmt
->data
.sif
.nels
; i
++)
444 stmt_free(stmt
->data
.sif
.els
[i
]);
445 free(stmt
->data
.sif
.els
);
448 expr_free(stmt
->data
.sreturn
);
451 expr_free(stmt
->data
.sexpr
);
454 free(stmt
->data
.svardecl
.ident
);
455 expr_free(stmt
->data
.svardecl
.expr
);
458 expr_free(stmt
->data
.swhile
.pred
);
459 for (int i
= 0; i
<stmt
->data
.swhile
.nbody
; i
++)
460 stmt_free(stmt
->data
.swhile
.body
[i
]);
461 free(stmt
->data
.swhile
.body
);
464 die("Unsupported stmt node\n");
469 void expr_free(struct expr
*expr
)
473 expr_free(expr
->data
.ebinop
.l
);
474 expr_free(expr
->data
.ebinop
.r
);
481 free(expr
->data
.efuncall
.ident
);
482 for (int i
= 0; i
<expr
->data
.efuncall
.nargs
; i
++)
483 expr_free(expr
->data
.efuncall
.args
[i
]);
484 free(expr
->data
.efuncall
.args
);
489 free(expr
->data
.eident
.ident
);
490 free(expr
->data
.eident
.fields
);
495 expr_free(expr
->data
.etuple
.left
);
496 expr_free(expr
->data
.etuple
.right
);
499 expr_free(expr
->data
.eunop
.l
);
502 die("Unsupported expr node\n");