work on type inference some more
[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 fundecl_genc(struct fundecl *decl, FILE *cout)
180 {
181 type_genc(decl->rtype, cout);
182 safe_fprintf(cout, "%s (", decl->ident);
183 for (int i = 0; i<decl->nargs; i++) {
184 if (i < decl->natypes)
185 die("function with unmatched type\n");
186 safe_fprintf(cout, "%s", decl->args[i]);
187 if (i < decl->nargs - 1)
188 safe_fprintf(cout, ", ");
189 }
190 safe_fprintf(cout, ") /*");
191 if (decl->rtype != NULL) {
192 safe_fprintf(cout, " :: ");
193 for (int i = 0; i<decl->natypes; i++) {
194 type_print(decl->atypes[i], cout);
195 safe_fprintf(cout, " ");
196 }
197 safe_fprintf(cout, "-> ");
198 type_print(decl->rtype, cout);
199 }
200 safe_fprintf(cout, "*/ {\n");
201 for (int i = 0; i<decl->nbody; i++)
202 stmt_genc(decl->body[i], 1, cout);
203 safe_fprintf(cout, "}\n");
204 }
205
206 void decl_genc(struct decl *decl, FILE *cout)
207 {
208 switch (decl->type) {
209 case dcomp:
210 //TODO generate prototypes?
211 for (int i = 0; i<decl->data.dcomp.ndecls; i++)
212 fundecl_genc(decl->data.dcomp.decls[i], cout);
213 break;
214 case dfundecl:
215 fundecl_genc(decl->data.dfun, cout);
216 break;
217 case dvardecl:
218 vardecl_genc(decl->data.dvar, 0, cout);
219 break;
220 }
221 }
222
223 void genc(struct ast *ast, FILE *cout)
224 {
225 fprintf(cout,
226 "#include <stdint.h>\n"
227 "#include <stdlib.h>\n"
228 "#define WORD intptr_t\n"
229 "struct splc_tuple { WORD fst; WORD snd; };\n"
230 "struct splc_list { WORD hd; struct splc_list *tl; };\n"
231 "struct splc_tuple *splc_tuple(WORD fst, WORD snd) {\n"
232 "\tstruct splc_tuple *res = malloc(sizeof(splc_tuple));\n"
233 "\tres->fst = fst;\n"
234 "\tres->snd = snd;\n"
235 "\treturn res;\n"
236 "}\n"
237 "struct splc_list *splc_cons(WORD hd, struct splc_list *tl) {\n"
238 "\tstruct splc_list *res = malloc(sizeof(splc_tuple));\n"
239 "\tres->hd = hd;\n"
240 "\tres->tl = tl;\n"
241 "\treturn res;\n"
242 "}\n"
243 "WORD splc_power(WORD l, WORD r) {\n"
244 "\tWORD res = 1;\n"
245 "\twhile(l-- >= 0)\n"
246 "\t\tres *= r;\n"
247 "\treturn res;\n"
248 "}\n"
249 );
250 for (int i = 0; i<ast->ndecls; i++) {
251 fprintf(cout, "\n");
252 decl_genc(ast->decls[i], cout);
253 }
254 }