constant globals checking
[ccc.git] / genc.c
1 #include <stdbool.h>
2
3 #include "ast.h"
4
5 void expr_genc(struct expr *expr, FILE *cout);
6
7 void binop_genc(char *fun, struct expr *l, struct expr *r, FILE *cout)
8 {
9 safe_fprintf(cout, "%s(", fun);
10 expr_genc(l, cout);
11 safe_fprintf(cout, ", ");
12 expr_genc(r, cout);
13 safe_fprintf(cout, ")");
14 }
15
16 void expr_genc(struct expr *expr, FILE *cout)
17 {
18 char buf[] = "\\x55";
19 if (expr == NULL)
20 return;
21 switch(expr->type) {
22 case ebinop:
23 if (expr->type == ebinop && expr->data.ebinop.op == cons) {
24 binop_genc("splc_cons", expr->data.ebinop.l,
25 expr->data.ebinop.r, cout);
26 } else if (expr->type == ebinop && expr->data.ebinop.op == power) {
27 binop_genc("splc_power", expr->data.ebinop.l,
28 expr->data.ebinop.r, cout);
29 } else {
30 safe_fprintf(cout, "(");
31 expr_genc(expr->data.ebinop.l, cout);
32 safe_fprintf(cout, "%s", binop_str[expr->data.ebinop.op]);
33 expr_genc(expr->data.ebinop.r, cout);
34 safe_fprintf(cout, ")");
35 }
36 break;
37 case ebool:
38 safe_fprintf(cout, "%s", expr->data.ebool ? "true" : "false");
39 break;
40 case echar:
41 safe_fprintf(cout, "'%s'",
42 escape_char(expr->data.echar, buf, false));
43 break;
44 case efuncall:
45 safe_fprintf(cout, "%s(", expr->data.efuncall.ident);
46 for(int i = 0; i<expr->data.efuncall.nargs; i++) {
47 expr_genc(expr->data.efuncall.args[i], cout);
48 if (i+1 < expr->data.efuncall.nargs)
49 safe_fprintf(cout, ", ");
50 }
51 safe_fprintf(cout, ")");
52 for (int i = 0; i<expr->data.efuncall.nfields; i++)
53 fprintf(cout, "->%s",
54 fieldspec_str[expr->data.efuncall.fields[i]]);
55 break;
56 case eint:
57 safe_fprintf(cout, "%d", expr->data.eint);
58 break;
59 case eident:
60 fprintf(cout, "%s", expr->data.eident.ident);
61 for (int i = 0; i<expr->data.eident.nfields; i++)
62 fprintf(cout, "->%s",
63 fieldspec_str[expr->data.eident.fields[i]]);
64 break;
65 case enil:
66 safe_fprintf(cout, "NULL");
67 break;
68 case etuple:
69 binop_genc("splc_tuple", expr->data.etuple.left,
70 expr->data.etuple.right, cout);
71 break;
72 case estring:
73 safe_fprintf(cout, "\"");
74 for (int i = 0; i<expr->data.estring.nchars; i++)
75 safe_fprintf(cout, "%s", escape_char(
76 expr->data.estring.chars[i], buf, true));
77 safe_fprintf(cout, "\"");
78 break;
79 case eunop:
80 safe_fprintf(cout, "(%s", unop_str[expr->data.eunop.op]);
81 expr_genc(expr->data.eunop.l, cout);
82 safe_fprintf(cout, ")");
83 break;
84 default:
85 die("Unknown expression node\n");
86 }
87 }
88
89 void type_genc(struct type *type, FILE *cout)
90 {
91 if (type == NULL)
92 die("unresolved var type\n");
93 switch(type->type) {
94 case tbasic:
95 fprintf(cout, "WORD ");
96 break;
97 case tlist:
98 fprintf(cout, "struct splc_list *");
99 break;
100 case ttuple:
101 fprintf(cout, "struct splc_tuple *");
102 break;
103 case tvar:
104 fprintf(cout, "WORD ");
105 break;
106 default:
107 die("Unsupported type node\n");
108 }
109 }
110
111 void vardecl_genc(struct vardecl *vardecl, int indent, FILE *cout)
112 {
113 if (vardecl == NULL)
114 return;
115 pindent(indent, cout);
116 type_genc(vardecl->type, cout);
117 fprintf(cout, "%s = ", vardecl->ident);
118 expr_genc(vardecl->expr, cout);
119 fprintf(cout, ";\n");
120 }
121
122 void stmt_genc(struct stmt *stmt, int indent, FILE *cout)
123 {
124 if (stmt == NULL)
125 return;
126 switch(stmt->type) {
127 case sassign:
128 pindent(indent, cout);
129 fprintf(cout, "%s", stmt->data.sassign.ident);
130 for (int i = 0; i<stmt->data.sassign.nfields; i++)
131 fprintf(cout, "->%s", stmt->data.sassign.fields[i]);
132 safe_fprintf(cout, " = ");
133 expr_genc(stmt->data.sassign.expr, cout);
134 safe_fprintf(cout, ";\n");
135 break;
136 case sif:
137 pindent(indent, cout);
138 safe_fprintf(cout, "if (");
139 expr_genc(stmt->data.sif.pred, cout);
140 safe_fprintf(cout, ") {\n");
141 for (int i = 0; i<stmt->data.sif.nthen; i++)
142 stmt_genc(stmt->data.sif.then[i], indent+1, cout);
143 pindent(indent, cout);
144 safe_fprintf(cout, "} else {\n");
145 for (int i = 0; i<stmt->data.sif.nels; i++)
146 stmt_genc(stmt->data.sif.els[i], indent+1, cout);
147 pindent(indent, cout);
148 safe_fprintf(cout, "}\n");
149 break;
150 case sreturn:
151 pindent(indent, cout);
152 safe_fprintf(cout, "return ");
153 expr_genc(stmt->data.sreturn, cout);
154 safe_fprintf(cout, ";\n");
155 break;
156 case sexpr:
157 pindent(indent, cout);
158 expr_genc(stmt->data.sexpr, cout);
159 safe_fprintf(cout, ";\n");
160 break;
161 case svardecl:
162 vardecl_genc(stmt->data.svardecl, indent, cout);
163 break;
164 case swhile:
165 pindent(indent, cout);
166 safe_fprintf(cout, "while (");
167 expr_genc(stmt->data.swhile.pred, cout);
168 safe_fprintf(cout, ") {\n");
169 for (int i = 0; i<stmt->data.swhile.nbody; i++)
170 stmt_genc(stmt->data.swhile.body[i], indent+1, cout);
171 pindent(indent, cout);
172 safe_fprintf(cout, "}\n");
173 break;
174 default:
175 die("Unsupported stmt node\n");
176 }
177 }
178
179 void decl_genc(struct decl *decl, FILE *cout)
180 {
181 switch (decl->type) {
182 case dcomponent:
183 //TODO generate prototypes?
184 for (int i = 0; i<decl->data.dcomponent.ndecls; i++)
185 decl_genc(decl->data.dcomponent.decls[i], cout);
186 break;
187 case dfundecl:
188 type_genc(decl->data.dfun.rtype, cout);
189 safe_fprintf(cout, "%s (", decl->data.dfun.ident);
190 for (int i = 0; i<decl->data.dfun.nargs; i++) {
191 if (i < decl->data.dfun.natypes)
192 die("function with unmatched type\n");
193 safe_fprintf(cout, "%s", decl->data.dfun.args[i]);
194 if (i < decl->data.dfun.nargs - 1)
195 safe_fprintf(cout, ", ");
196 }
197 safe_fprintf(cout, ") /*");
198 if (decl->data.dfun.rtype != NULL) {
199 safe_fprintf(cout, " :: ");
200 for (int i = 0; i<decl->data.dfun.natypes; i++) {
201 type_print(decl->data.dfun.atypes[i], cout);
202 safe_fprintf(cout, " ");
203 }
204 safe_fprintf(cout, "-> ");
205 type_print(decl->data.dfun.rtype, cout);
206 }
207 safe_fprintf(cout, "*/ {\n");
208 for (int i = 0; i<decl->data.dfun.nbody; i++)
209 stmt_genc(decl->data.dfun.body[i], 1, cout);
210 safe_fprintf(cout, "}\n");
211 break;
212 case dvardecl:
213 vardecl_genc(decl->data.dvar, 0, cout);
214 break;
215 }
216 }
217
218 void genc(struct ast *ast, FILE *cout)
219 {
220 fprintf(cout,
221 "#include <stdint.h>\n"
222 "#include <stdlib.h>\n"
223 "#define WORD intptr_t\n"
224 "struct splc_tuple { WORD fst; WORD snd; };\n"
225 "struct splc_list { WORD hd; struct splc_list *tl; };\n"
226 "struct splc_tuple *splc_tuple(WORD fst, WORD snd) {\n"
227 "\tstruct splc_tuple *res = malloc(sizeof(splc_tuple));\n"
228 "\tres->fst = fst;\n"
229 "\tres->snd = snd;\n"
230 "\treturn res;\n"
231 "}\n"
232 "struct splc_list *splc_cons(WORD hd, struct splc_list *tl) {\n"
233 "\tstruct splc_list *res = malloc(sizeof(splc_tuple));\n"
234 "\tres->hd = hd;\n"
235 "\tres->tl = tl;\n"
236 "\treturn res;\n"
237 "}\n"
238 "WORD splc_power(WORD l, WORD r) {\n"
239 "\tWORD res = 1;\n"
240 "\twhile(l-- >= 0)\n"
241 "\t\tres *= r;\n"
242 "\treturn res;\n"
243 "}\n"
244 );
245 for (int i = 0; i<ast->ndecls; i++) {
246 fprintf(cout, "\n");
247 decl_genc(ast->decls[i], cout);
248 }
249 }