From 3dee98d7e0b342c84119471906ae91d706684679 Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Mon, 12 Apr 2021 15:15:14 +0200 Subject: [PATCH] more code generation --- gen/c.c | 14 ++++++++----- gen/ssm.c | 61 +++++++++++++++++++++++++++++++------------------------ rts.c | 7 +++++++ rts.h | 7 +++++-- rts.ssm | 9 ++++++++ 5 files changed, 65 insertions(+), 33 deletions(-) diff --git a/gen/c.c b/gen/c.c index 00def72..bb9af14 100644 --- 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; diff --git a/gen/ssm.c b/gen/ssm.c index 0a94702..dc1f94a 100644 --- 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 --- 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 --- a/rts.h +++ b/rts.h @@ -5,6 +5,7 @@ #include #include #include +#include #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 --- 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 -- 2.20.1