more code generation
authorMart Lubbers <mart@martlubbers.net>
Mon, 12 Apr 2021 13:15:14 +0000 (15:15 +0200)
committerMart Lubbers <mart@martlubbers.net>
Mon, 12 Apr 2021 13:15:14 +0000 (15:15 +0200)
gen/c.c
gen/ssm.c
rts.c
rts.h
rts.ssm

diff --git a/gen/c.c b/gen/c.c
index 00def72..bb9af14 100644 (file)
--- a/gen/c.c
+++ b/gen/c.c
@@ -162,14 +162,18 @@ static void stmt_genc(struct stmt *stmt, int indent, FILE *cout)
                safe_fprintf(cout, "if (");
                expr_genc(stmt->data.sif.pred, cout);
                safe_fprintf(cout, ") {\n");
+
                ARRAY_ITER(struct stmt *, s, i, &stmt->data.sif.then)
                        stmt_genc(s, indent+1, cout);
                AIEND
-               pindent(indent, cout);
-               safe_fprintf(cout, "} else {\n");
-               ARRAY_ITER(struct stmt *, s, i, &stmt->data.sif.els)
-                       stmt_genc(s, indent+1, cout);
-               AIEND
+
+               if (ARRAY_SIZE(&stmt->data.sif.els) != 0) {
+                       pindent(indent, cout);
+                       safe_fprintf(cout, "} else {\n");
+                       ARRAY_ITER(struct stmt *, s, i, &stmt->data.sif.els)
+                               stmt_genc(s, indent+1, cout);
+                       AIEND
+               }
                pindent(indent, cout);
                safe_fprintf(cout, "}\n");
                break;
index 0a94702..dc1f94a 100644 (file)
--- a/gen/ssm.c
+++ b/gen/ssm.c
@@ -275,11 +275,11 @@ static void expr_genssm(struct genssmst *st, struct expr *expr, FILE *cout)
                        safe_fprintf(cout, "\n");
                } else {
                        safe_fprintf(cout, "bsr %s\n", expr->data.efuncall.ident);
-                       safe_fprintf(cout, "ajs -%u\n",
-                               ARRAY_SIZE(&expr->data.efuncall.args));
-                       //TODO don't do this when the function returns void
-                       safe_fprintf(cout, "ldr RR\n");
                }
+               safe_fprintf(cout, "ajs -%u\n",
+                       ARRAY_SIZE(&expr->data.efuncall.args));
+               //TODO don't do this when the function returns void
+               safe_fprintf(cout, "ldr RR\n");
                break;
        case eint:
                safe_fprintf(cout, "ldc %d\n", expr->data.eint);
@@ -335,25 +335,39 @@ static void body_genssm(struct genssmst *st, struct array body, FILE *cout)
 
 static void stmt_genssm(struct genssmst *st, struct stmt *stmt, FILE *cout)
 {
+       int l;
+       struct vref *el;
        switch(stmt->type) {
        case sassign:
-//             pindent(indent, cout);
-//             safe_fprintf(cout, "%s", stmt->data.sassign.ident);
-//             ARRAY_ITER(char *, f, i, stmt->data.sassign.fields)
-//                     safe_fprintf(cout, "->%s", f);
-//             AIEND
-//             safe_fprintf(cout, " = ");
-//             expr_genabc(st, stmt->data.sassign.expr, cout);
-//             safe_fprintf(cout, ";\n");
+               //TODO fields
+               HASH_FIND_STR(st->refs, stmt->data.sassign.ident, el);
+               if (el == NULL)
+                       die("unknown variable: %s???", stmt->data.sassign.ident);
+               switch(el->type) {
+               case global:
+                       safe_fprintf(cout, "ldr R5\n");
+                       expr_genssm(st, stmt->data.sassign.expr, cout);
+                       safe_fprintf(cout, "lda %d\n", el->num);
+                       break;
+               case arg:
+                       expr_genssm(st, stmt->data.sassign.expr, cout);
+                       safe_fprintf(cout, "stl -%d\n", el->num);
+                       break;
+               case local:
+                       expr_genssm(st, stmt->data.sassign.expr, cout);
+                       safe_fprintf(cout, "stl %d\n", el->num);
+                       break;
+               }
                break;
        case sif:
+               l = st->fresh++;
                expr_genssm(st, stmt->data.sif.pred, cout);
-               safe_fprintf(cout, "brf _else%d\n", st->fresh);
+               safe_fprintf(cout, "brf _else%d\n", l);
                body_genssm(st, stmt->data.sif.then, cout);
-               safe_fprintf(cout, "bra _endif%d\n", st->fresh);
-               safe_fprintf(cout, "_else%d:\n", st->fresh);
+               safe_fprintf(cout, "bra _endif%d\n", l);
+               safe_fprintf(cout, "_else%d:\n", l);
                body_genssm(st, stmt->data.sif.els, cout);
-               safe_fprintf(cout, "_endif%d: \n", st->fresh++);
+               safe_fprintf(cout, "_endif%d: \n", l);
                break;
        case sreturn:
                if (stmt->data.sreturn != NULL) {
@@ -373,24 +387,19 @@ static void stmt_genssm(struct genssmst *st, struct stmt *stmt, FILE *cout)
                add_vref(st, stmt->data.svardecl->ident, local, st->vdecl++);
                break;
        case swhile:
-               safe_fprintf(cout, "_while%d: \n", st->fresh);
+               l = st->fresh++;
+               safe_fprintf(cout, "_while%d: \n", l);
                expr_genssm(st, stmt->data.sif.pred, cout);
-               safe_fprintf(cout, "brf _endwhile%d\n", st->fresh);
+               safe_fprintf(cout, "brf _endwhile%d\n", l);
                body_genssm(st, stmt->data.swhile.body, cout);
-               safe_fprintf(cout, "bra _while%d\n", st->fresh);
-               safe_fprintf(cout, "_endwhile%d: \n", st->fresh++);
+               safe_fprintf(cout, "bra _while%d\n", l);
+               safe_fprintf(cout, "_endwhile%d: \n", l);
                break;
        default:
                die("Unsupported stmt node\n");
        }
 }
 
-//static void vardecl_genssm(struct genssmst *st, struct vardecl *vardecl, FILE *cout)
-//{
-//     //TODO add to dictionary
-//     expr_genssm(st, vardecl->expr, cout);
-//}
-
 static void global_genssm(int no, struct genssmst *st, struct vardecl *vardecl, FILE *cout)
 {
        add_vref(st, vardecl->ident, global, no+1);
diff --git a/rts.c b/rts.c
index c144081..0d5e5cb 100644 (file)
--- a/rts.c
+++ b/rts.c
@@ -36,3 +36,10 @@ WORD splc_power(WORD l, WORD r) {
                res *= r;
        return res;
 }
+WORD hd(struct splc_list *l)
+{
+       if (l == NULL) {
+               die("head of an empty list\n");
+       }
+       return l->hd;
+}
diff --git a/rts.h b/rts.h
index c1efb6f..32ddb99 100644 (file)
--- a/rts.h
+++ b/rts.h
@@ -5,6 +5,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdbool.h>
+#include <stdlib.h>
 
 #define WORD intptr_t
 
@@ -12,12 +13,14 @@ struct splc_tuple { WORD fst; WORD snd; };
 struct splc_list { WORD hd; struct splc_list *tl; };
 struct splc_tuple *splc_tuple(WORD fst, WORD snd);
 struct splc_list *splc_cons(WORD hd, struct splc_list *tl);
+WORD hd(struct splc_list *l);
+struct splc_list *tl(struct splc_list *l);
+#define die(...) { fprintf(stderr, __VA_ARGS__); exit(1); }
 #define isEmpty(l) ((l) == NULL)
-#define hd(l) (l)->hd
 #define tl(l) (l)->tl
 #define fst(l) (l)->fst
 #define snd(l) (l)->snd
-#define print_Int(l) printf("%d", l);
+#define print_Int(l) printf("%ld", l);
 #define print_Char(l) printf("%c", l);
 #define print_Bool(l) printf("%s", (l) ? "true" : "false");
 #define eq_Int(x, y) ((x)==(y))
diff --git a/rts.ssm b/rts.ssm
index 6c1af57..be60348 100644 (file)
--- a/rts.ssm
+++ b/rts.ssm
@@ -1,3 +1,4 @@
+; Power function
 pow:
 link 1; pow (x, y) {
 ldc 1
@@ -21,6 +22,8 @@ ldl 1; return z
 str RR
 unlink
 ret
+
+; Equality of basic types
 eqInt:
 link 0
 ldl -2
@@ -42,6 +45,8 @@ ldl -3
 eq
 unlink
 ret
+
+; Printing of basic types
 printInt:
 link 0
 ldl -2
@@ -67,6 +72,8 @@ trap 1
 printBoole:
 unlink
 ret
+
+; Field selectors
 fst:
 link 0
 ldl -2
@@ -95,6 +102,8 @@ ldh 0
 str RR
 unlink
 ret
+
+; List empty check
 isEmpty:
 link 0
 ldl -2