Initial commit
[ccc.git] / ast.c
1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "ast.h"
5
6 struct ast *ast_alloc()
7 {
8 struct ast *res = malloc(sizeof(struct ast));
9 if (res == NULL) {
10 perror("malloc");
11 exit(1);
12 }
13 return res;
14 }
15
16 struct ast *ast_cons(struct ast *el, struct ast *tail)
17 {
18 struct ast *res = ast_alloc();
19 res->type = an_cons;
20 res->data.an_cons.el = el;
21 res->data.an_cons.tail = tail;
22 return res;
23 }
24
25 struct ast *ast_binop(struct ast *l, enum binop op, struct ast *r)
26 {
27 struct ast *res = ast_alloc();
28 res->type = an_binop;
29 res->data.an_binop.l = l;
30 res->data.an_binop.op = op;
31 res->data.an_binop.r = r;
32 return res;
33 }
34
35 struct ast *ast_int(int integer)
36 {
37 struct ast *res = ast_alloc();
38 res->type = an_int;
39 res->data.an_int = integer;
40 return res;
41 }
42
43 static const char *binop_str[] = {
44 [plus] = "+",
45 [minus] = "+",
46 [times] = "+",
47 [divide] = "+",
48 };
49
50 void ast_print(struct ast * ast, FILE *out)
51 {
52 if (ast == NULL)
53 return;
54 switch(ast->type) {
55 case an_binop:
56 fprintf(out, "(");
57 ast_print(ast->data.an_binop.l, out);
58 fprintf(out, "%s", binop_str[ast->data.an_binop.op]);
59 ast_print(ast->data.an_binop.r, out);
60 fprintf(out, ")");
61 break;
62 case an_cons:
63 ast_print(ast->data.an_cons.el, out);
64 fprintf(out, ";\n");
65 ast_print(ast->data.an_cons.tail, out);
66 break;
67 case an_int:
68 fprintf(out, "%d", ast->data.an_int);
69 break;
70 default:
71 fprintf(stderr, "Unsupported AST node\n");
72 exit(1);
73 }
74 }
75
76 void ast_free(struct ast *ast)
77 {
78 if (ast == NULL)
79 return;
80 switch(ast->type) {
81 case an_binop:
82 ast_free(ast->data.an_binop.l);
83 ast_free(ast->data.an_binop.r);
84 break;
85 case an_cons:
86 ast_free(ast->data.an_cons.el);
87 ast_free(ast->data.an_cons.tail);
88 break;
89 case an_int:
90 break;
91 default:
92 fprintf(stderr, "Unsupported AST node\n");
93 exit(1);
94 }
95 free(ast);
96 }