summaryrefslogtreecommitdiff
path: root/qbe.c
diff options
context:
space:
mode:
authorthing1 <thing1@seacrossedlovers.xyz>2025-02-18 22:00:20 +0000
committerthing1 <thing1@seacrossedlovers.xyz>2025-02-18 22:00:20 +0000
commitecfbc703dc930a20d56562451f4aa807175503e2 (patch)
tree7c1dd2742363625f59e4d9f7ba62a8d9594cd463 /qbe.c
init commitHEADmaster
Diffstat (limited to 'qbe.c')
-rw-r--r--qbe.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/qbe.c b/qbe.c
new file mode 100644
index 0000000..ed3daf9
--- /dev/null
+++ b/qbe.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#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");
+}