#include #include "types.h" int endcount = 0; void compileexpr(FILE *f, exp *e) { switch (e->op) { case '+': if (e->var) fprintf(f, "%%%c =w add %%%c, %%%c\n", e->name, e->name, e->vv); else fprintf(f, "%%%c =w add %%%c, %d\n", e->name, e->name, e->v); break; case '-': if (e->var) fprintf(f, "%%%c =w sub %%%c, %%%c\n", e->name, e->name, e->vv); else fprintf(f, "%%%c =w sub %%%c, %d\n", e->name, e->name, e->v); break; case '*': if (e->var) fprintf(f, "%%%c =w mul %%%c, %%%c\n", e->name, e->name, e->vv); else fprintf(f, "%%%c =w mul %%%c, %d\n", e->name, e->name, e->v); break; case '/': if (e->var) fprintf(f, "%%%c =w div %%%c, %%%c\n", e->name, e->name, e->vv); else fprintf(f, "%%%c =w div %%%c, %d\n", e->name, e->name, e->v); break; case 0: fprintf(f, "%%%c =w copy 0\n", e->name); break; case '=': fprintf(f, "%%%c =w copy %d\n", e->name, e->v); break; case 'p': fprintf(f, "call $printf(l $fmt, ..., w %%%c)\n", e->name); break; case 'i': fprintf(f, "%%%c =w call $readint()\n", e->name); break; case 'r': fprintf(f, "ret %%%c\n", e->name); break; case 'l': fprintf(f, "@label%c\n", e->name); break; case 'j': fprintf(f, "jmp @label%c\n", e->name); break; case 'z': fprintf(f, "jnz %%%c, @label%c, @end%d\n@end%d\n", e->vv, e->name, endcount, endcount); endcount++; break; default: fprintf(f, "%%%c =w call $%c()\n", e->name, e->vv); break; } } void compilefunc(FILE *file, function *f) { if (f->name == 'M') fprintf(file, "export function w $main() {\n@start\n"); else fprintf(file, "export function w $%c() {\n@start\n", f->name); for (int i = 0; i < f->exprcount; i++) { compileexpr(file, f->exprs[i]); } fprintf(file, "}\n"); } void compile(FILE *file, function *f[], int count) { for (int i = 0; i < count; i++) { compilefunc(file, f[i]); } printf("data $fmt = { b \"%%d\\n\", b 0 }\n"); printf("data $fmtin = { b \"%%d\", b 0 }\n"); }