11 const char *binop_str
[] = {
12 [binor
] = "||", [binand
] = "&&", [eq
] = "==", [neq
] = "!=",
13 [leq
] = "<=", [le
] = "<", [geq
] = ">=", [ge
] = ">", [cons
] = ":",
14 [plus
] = "+", [minus
] = "-", [times
] = "*", [divide
] = "/",
15 [modulo
] = "%", [power
] = "^",
17 const char *fieldspec_str
[] = {
18 [fst
] = "fst", [snd
] = "snd", [hd
] = "hd", [tl
] = "tl"};
19 const char *unop_str
[] = { [inverse
] = "!", [negate
] = "-", };
21 struct ast
*ast(struct list
*decls
)
23 struct ast
*res
= safe_malloc(sizeof(struct ast
));
24 res
->decls
= (struct decl
**)list_to_array(decls
, &res
->ndecls
, true);
28 struct vardecl
*vardecl(struct type
*type
, char *ident
, struct expr
*expr
)
30 struct vardecl
*res
= safe_malloc(sizeof(struct vardecl
));
36 struct fundecl
*fundecl(char *ident
, struct list
*args
, struct list
*atypes
,
37 struct type
*rtype
, struct list
*body
)
39 struct fundecl
*res
= safe_malloc(sizeof(struct fundecl
));
41 res
->args
= (char **)list_to_array(args
, &res
->nargs
, true);
42 res
->atypes
= (struct type
**)list_to_array(atypes
, &res
->natypes
, true);
44 res
->body
= (struct stmt
**)list_to_array(body
, &res
->nbody
, true);
48 struct decl
*decl_fun(struct fundecl
*fundecl
)
50 struct decl
*res
= safe_malloc(sizeof(struct decl
));
52 res
->data
.dfun
= fundecl
;
56 struct decl
*decl_var(struct vardecl
*vardecl
)
58 struct decl
*res
= safe_malloc(sizeof(struct decl
));
60 res
->data
.dvar
= vardecl
;
64 struct stmt
*stmt_assign(char *ident
, struct list
*fields
, struct expr
*expr
)
66 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
68 res
->data
.sassign
.ident
= ident
;
69 res
->data
.sassign
.fields
= (char **)
70 list_to_array(fields
, &res
->data
.sassign
.nfields
, true);
71 res
->data
.sassign
.expr
= expr
;
75 struct stmt
*stmt_if(struct expr
*pred
, struct list
*then
, struct list
*els
)
77 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
79 res
->data
.sif
.pred
= pred
;
80 res
->data
.sif
.then
= (struct stmt
**)
81 list_to_array(then
, &res
->data
.sif
.nthen
, true);
82 res
->data
.sif
.els
= (struct stmt
**)
83 list_to_array(els
, &res
->data
.sif
.nels
, true);
87 struct stmt
*stmt_return(struct expr
*rtrn
)
89 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
91 res
->data
.sreturn
= rtrn
;
95 struct stmt
*stmt_expr(struct expr
*expr
)
97 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
99 res
->data
.sexpr
= expr
;
103 struct stmt
*stmt_vardecl(struct vardecl
*vardecl
)
105 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
106 res
->type
= svardecl
;
107 res
->data
.svardecl
= vardecl
;
111 struct stmt
*stmt_while(struct expr
*pred
, struct list
*body
)
113 struct stmt
*res
= safe_malloc(sizeof(struct stmt
));
115 res
->data
.swhile
.pred
= pred
;
116 res
->data
.swhile
.body
= (struct stmt
**)
117 list_to_array(body
, &res
->data
.swhile
.nbody
, true);
121 struct expr
*expr_binop(struct expr
*l
, enum binop op
, struct expr
*r
)
123 struct expr
*res
= safe_malloc(sizeof(struct expr
));
125 res
->data
.ebinop
.l
= l
;
126 res
->data
.ebinop
.op
= op
;
127 res
->data
.ebinop
.r
= r
;
131 struct expr
*expr_bool(bool b
)
133 struct expr
*res
= safe_malloc(sizeof(struct expr
));
139 struct expr
*expr_char(char *c
)
141 struct expr
*res
= safe_malloc(sizeof(struct expr
));
143 res
->data
.echar
= unescape_char(c
)[0];
147 static void set_fields(enum fieldspec
**farray
, int *n
, struct list
*fields
)
149 void **els
= list_to_array(fields
, n
, true);
150 *farray
= (enum fieldspec
*)safe_malloc(*n
*sizeof(enum fieldspec
));
151 for (int i
= 0; i
<*n
; i
++) {
153 if (strcmp(t
, "fst") == 0)
155 else if (strcmp(t
, "snd") == 0)
157 else if (strcmp(t
, "hd") == 0)
159 else if (strcmp(t
, "tl") == 0)
167 struct expr
*expr_funcall(char *ident
, struct list
*args
, struct list
*fields
)
169 struct expr
*res
= safe_malloc(sizeof(struct expr
));
170 res
->type
= efuncall
;
171 res
->data
.efuncall
.ident
= ident
;
172 res
->data
.efuncall
.args
= (struct expr
**)
173 list_to_array(args
, &res
->data
.efuncall
.nargs
, true);
174 set_fields(&res
->data
.efuncall
.fields
,
175 &res
->data
.efuncall
.nfields
, fields
);
179 struct expr
*expr_int(int integer
)
181 struct expr
*res
= safe_malloc(sizeof(struct expr
));
183 res
->data
.eint
= integer
;
187 struct expr
*expr_ident(char *ident
, struct list
*fields
)
189 struct expr
*res
= safe_malloc(sizeof(struct expr
));
191 res
->data
.eident
.ident
= ident
;
192 set_fields(&res
->data
.eident
.fields
, &res
->data
.eident
.nfields
, fields
);
196 struct expr
*expr_nil()
198 struct expr
*res
= safe_malloc(sizeof(struct expr
));
203 struct expr
*expr_tuple(struct expr
*left
, struct expr
*right
)
205 struct expr
*res
= safe_malloc(sizeof(struct expr
));
207 res
->data
.etuple
.left
= left
;
208 res
->data
.etuple
.right
= right
;
212 struct expr
*expr_string(char *str
)
214 struct expr
*res
= safe_malloc(sizeof(struct expr
));
216 res
->data
.estring
.nchars
= 0;
217 res
->data
.estring
.chars
= safe_malloc(strlen(str
)+1);
218 char *p
= res
->data
.estring
.chars
;
219 while(*str
!= '\0') {
220 str
= unescape_char(str
);
222 res
->data
.estring
.nchars
++;
228 struct expr
*expr_unop(enum unop op
, struct expr
*l
)
230 struct expr
*res
= safe_malloc(sizeof(struct expr
));
232 res
->data
.eunop
.op
= op
;
233 res
->data
.eunop
.l
= l
;
237 void ast_print(struct ast
*ast
, FILE *out
)
241 for (int i
= 0; i
<ast
->ndecls
; i
++)
242 decl_print(ast
->decls
[i
], out
);
245 void vardecl_print(struct vardecl
*decl
, int indent
, FILE *out
)
247 pindent(indent
, out
);
248 if (decl
->type
== NULL
)
249 safe_fprintf(out
, "var");
251 type_print(decl
->type
, out
);
252 safe_fprintf(out
, " %s = ", decl
->ident
);
253 expr_print(decl
->expr
, out
);
254 safe_fprintf(out
, ";\n");
257 void fundecl_print(struct fundecl
*decl
, FILE *out
)
259 safe_fprintf(out
, "%s (", decl
->ident
);
260 for (int i
= 0; i
<decl
->nargs
; i
++) {
261 safe_fprintf(out
, "%s", decl
->args
[i
]);
262 if (i
< decl
->nargs
- 1)
263 safe_fprintf(out
, ", ");
265 safe_fprintf(out
, ")");
266 if (decl
->rtype
!= NULL
) {
267 safe_fprintf(out
, " :: ");
268 for (int i
= 0; i
<decl
->natypes
; i
++) {
269 type_print(decl
->atypes
[i
], out
);
270 safe_fprintf(out
, " ");
272 safe_fprintf(out
, "-> ");
273 type_print(decl
->rtype
, out
);
275 safe_fprintf(out
, " {\n");
276 for (int i
= 0; i
<decl
->nbody
; i
++)
277 stmt_print(decl
->body
[i
], 1, out
);
278 safe_fprintf(out
, "}\n");
281 void decl_print(struct decl
*decl
, FILE *out
)
287 fundecl_print(decl
->data
.dfun
, out
);
290 vardecl_print(decl
->data
.dvar
, 0, out
);
293 fprintf(out
, "//<<<comp\n");
294 for (int i
= 0; i
<decl
->data
.dcomp
.ndecls
; i
++)
295 fundecl_print(decl
->data
.dcomp
.decls
[i
], out
);
296 fprintf(out
, "//>>>comp\n");
299 die("Unsupported decl node\n");
303 void stmt_print(struct stmt
*stmt
, int indent
, FILE *out
)
309 pindent(indent
, out
);
310 fprintf(out
, "%s", stmt
->data
.sassign
.ident
);
311 for (int i
= 0; i
<stmt
->data
.sassign
.nfields
; i
++)
312 fprintf(out
, ".%s", stmt
->data
.sassign
.fields
[i
]);
313 safe_fprintf(out
, " = ");
314 expr_print(stmt
->data
.sassign
.expr
, out
);
315 safe_fprintf(out
, ";\n");
318 pindent(indent
, out
);
319 safe_fprintf(out
, "if (");
320 expr_print(stmt
->data
.sif
.pred
, out
);
321 safe_fprintf(out
, ") {\n");
322 for (int i
= 0; i
<stmt
->data
.sif
.nthen
; i
++)
323 stmt_print(stmt
->data
.sif
.then
[i
], indent
+1, out
);
324 pindent(indent
, out
);
325 safe_fprintf(out
, "} else {\n");
326 for (int i
= 0; i
<stmt
->data
.sif
.nels
; i
++)
327 stmt_print(stmt
->data
.sif
.els
[i
], indent
+1, out
);
328 pindent(indent
, out
);
329 safe_fprintf(out
, "}\n");
332 pindent(indent
, out
);
333 safe_fprintf(out
, "return ");
334 expr_print(stmt
->data
.sreturn
, out
);
335 safe_fprintf(out
, ";\n");
338 pindent(indent
, out
);
339 expr_print(stmt
->data
.sexpr
, out
);
340 safe_fprintf(out
, ";\n");
343 vardecl_print(stmt
->data
.svardecl
, indent
, out
);
346 pindent(indent
, out
);
347 safe_fprintf(out
, "while (");
348 expr_print(stmt
->data
.swhile
.pred
, out
);
349 safe_fprintf(out
, ") {\n");
350 for (int i
= 0; i
<stmt
->data
.swhile
.nbody
; i
++)
351 stmt_print(stmt
->data
.swhile
.body
[i
], indent
+1, out
);
352 pindent(indent
, out
);
353 safe_fprintf(out
, "}\n");
356 die("Unsupported stmt node\n");
360 void expr_print(struct expr
*expr
, FILE *out
)
364 char buf
[] = "\\xff";
367 safe_fprintf(out
, "(");
368 expr_print(expr
->data
.ebinop
.l
, out
);
369 safe_fprintf(out
, "%s", binop_str
[expr
->data
.ebinop
.op
]);
370 expr_print(expr
->data
.ebinop
.r
, out
);
371 safe_fprintf(out
, ")");
374 safe_fprintf(out
, "%s", expr
->data
.ebool
? "true" : "false");
377 safe_fprintf(out
, "'%s'",
378 escape_char(expr
->data
.echar
, buf
, false));
381 safe_fprintf(out
, "%s(", expr
->data
.efuncall
.ident
);
382 for(int i
= 0; i
<expr
->data
.efuncall
.nargs
; i
++) {
383 expr_print(expr
->data
.efuncall
.args
[i
], out
);
384 if (i
+1 < expr
->data
.efuncall
.nargs
)
385 safe_fprintf(out
, ", ");
387 safe_fprintf(out
, ")");
388 for (int i
= 0; i
<expr
->data
.efuncall
.nfields
; i
++)
390 fieldspec_str
[expr
->data
.efuncall
.fields
[i
]]);
393 safe_fprintf(out
, "%d", expr
->data
.eint
);
396 fprintf(out
, "%s", expr
->data
.eident
.ident
);
397 for (int i
= 0; i
<expr
->data
.eident
.nfields
; i
++)
399 fieldspec_str
[expr
->data
.eident
.fields
[i
]]);
402 safe_fprintf(out
, "[]");
405 safe_fprintf(out
, "(");
406 expr_print(expr
->data
.etuple
.left
, out
);
407 safe_fprintf(out
, ", ");
408 expr_print(expr
->data
.etuple
.right
, out
);
409 safe_fprintf(out
, ")");
412 safe_fprintf(out
, "\"");
413 for (int i
= 0; i
<expr
->data
.estring
.nchars
; i
++)
414 safe_fprintf(out
, "%s", escape_char(
415 expr
->data
.estring
.chars
[i
], buf
, true));
416 safe_fprintf(out
, "\"");
419 safe_fprintf(out
, "(%s", unop_str
[expr
->data
.eunop
.op
]);
420 expr_print(expr
->data
.eunop
.l
, out
);
421 safe_fprintf(out
, ")");
424 die("Unsupported expr node\n");
428 void ast_free(struct ast
*ast
)
432 for (int i
= 0; i
<ast
->ndecls
; i
++)
433 decl_free(ast
->decls
[i
]);
438 void vardecl_free(struct vardecl
*decl
)
440 type_free(decl
->type
);
442 expr_free(decl
->expr
);
446 void fundecl_free(struct fundecl
*decl
)
449 for (int i
= 0; i
<decl
->nargs
; i
++)
452 for (int i
= 0; i
<decl
->natypes
; i
++)
453 type_free(decl
->atypes
[i
]);
455 type_free(decl
->rtype
);
456 for (int i
= 0; i
<decl
->nbody
; i
++)
457 stmt_free(decl
->body
[i
]);
462 void decl_free(struct decl
*decl
)
468 for (int i
= 0; i
<decl
->data
.dcomp
.ndecls
; i
++)
469 fundecl_free(decl
->data
.dcomp
.decls
[i
]);
470 free(decl
->data
.dcomp
.decls
);
473 fundecl_free(decl
->data
.dfun
);
476 vardecl_free(decl
->data
.dvar
);
479 die("Unsupported decl node\n");
484 void stmt_free(struct stmt
*stmt
)
490 free(stmt
->data
.sassign
.ident
);
491 for (int i
= 0; i
<stmt
->data
.sassign
.nfields
; i
++)
492 free(stmt
->data
.sassign
.fields
[i
]);
493 free(stmt
->data
.sassign
.fields
);
494 expr_free(stmt
->data
.sassign
.expr
);
497 expr_free(stmt
->data
.sif
.pred
);
498 for (int i
= 0; i
<stmt
->data
.sif
.nthen
; i
++)
499 stmt_free(stmt
->data
.sif
.then
[i
]);
500 free(stmt
->data
.sif
.then
);
501 for (int i
= 0; i
<stmt
->data
.sif
.nels
; i
++)
502 stmt_free(stmt
->data
.sif
.els
[i
]);
503 free(stmt
->data
.sif
.els
);
506 expr_free(stmt
->data
.sreturn
);
509 expr_free(stmt
->data
.sexpr
);
512 expr_free(stmt
->data
.swhile
.pred
);
513 for (int i
= 0; i
<stmt
->data
.swhile
.nbody
; i
++)
514 stmt_free(stmt
->data
.swhile
.body
[i
]);
515 free(stmt
->data
.swhile
.body
);
518 vardecl_free(stmt
->data
.svardecl
);
521 die("Unsupported stmt node\n");
526 void expr_free(struct expr
*expr
)
532 expr_free(expr
->data
.ebinop
.l
);
533 expr_free(expr
->data
.ebinop
.r
);
540 free(expr
->data
.efuncall
.ident
);
541 for (int i
= 0; i
<expr
->data
.efuncall
.nargs
; i
++)
542 expr_free(expr
->data
.efuncall
.args
[i
]);
543 free(expr
->data
.efuncall
.fields
);
544 free(expr
->data
.efuncall
.args
);
549 free(expr
->data
.eident
.ident
);
550 free(expr
->data
.eident
.fields
);
555 expr_free(expr
->data
.etuple
.left
);
556 expr_free(expr
->data
.etuple
.right
);
559 free(expr
->data
.estring
.chars
);
562 expr_free(expr
->data
.eunop
.l
);
565 die("Unsupported expr node\n");