From 8ca5cb246842b10295cbb3e12516cb1eae4efc08 Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Thu, 18 Mar 2021 13:52:54 +0100 Subject: [PATCH] more fixes, vardecl ordering fixed --- gen.c | 15 +++++++++------ gen.h | 4 ++++ gen/c.c | 38 +++++++++++++++++++++++++++++++------- sem/hm.c | 2 +- sem/type.c | 15 +++++---------- sem/vardecl.c | 36 +++++++++++++++++------------------- 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/gen.c b/gen.c index a115b3a..8b741ad 100644 --- a/gen.c +++ b/gen.c @@ -35,16 +35,19 @@ static int type_cmpv(const void *l, const void *r) return type_cmp((struct type *)l, *(void **)r); } -static void call_register(struct array *st, struct type *type) +static void call_register(YYLTYPE loc, struct array *st, struct type *type) { array_binsert(type, st, type_cmpv); switch(type->type) { case tlist: - call_register(st, type->data.tlist); + call_register(loc, st, type->data.tlist); break; case ttuple: - call_register(st, type->data.ttuple.l); - call_register(st, type->data.ttuple.r); + call_register(loc, st, type->data.ttuple.l); + call_register(loc, st, type->data.ttuple.r); + break; + case tvar: + type_error(loc, true, "cannot use overloading on a polymorf type"); break; default: break; @@ -56,13 +59,13 @@ static void ol_expr(struct overload *st, struct expr *expr) switch(expr->type) { case ebinop: if (expr->data.ebinop.op == eq || expr->data.ebinop.op == neq) - call_register(&st->eq, expr->data.ebinop.type); + call_register(expr->loc, &st->eq, expr->data.ebinop.type); ol_expr(st, expr->data.ebinop.l); ol_expr(st, expr->data.ebinop.r); break; case efuncall: if (strcmp(expr->data.efuncall.ident, "print") == 0) - call_register(&st->print, expr->data.efuncall.type); + call_register(expr->loc, &st->print, expr->data.efuncall.type); ARRAY_ITER(struct expr *, e, i, &expr->data.efuncall.args) ol_expr(st, e); AIEND diff --git a/gen.h b/gen.h index 3a55679..92a7c84 100644 --- a/gen.h +++ b/gen.h @@ -9,6 +9,10 @@ struct overload { struct array print; struct array eq; }; +struct overload_entry { + struct type *type; + YYLTYPE loc; +}; enum lang {c, ssm}; void overloaded_type(YYLTYPE loc, struct type *type, FILE *cout); diff --git a/gen/c.c b/gen/c.c index 889bf53..00def72 100644 --- a/gen/c.c +++ b/gen/c.c @@ -218,28 +218,45 @@ static void fundecl_sig(struct fundecl *decl, FILE *cout) safe_fprintf(cout, ")"); } -static void fundecl_genc(struct fundecl *decl, FILE *cout) +static void initialise_non_constant_globals(const struct ast *ast, FILE *cout) +{ + fprintf(stderr, "init globals\n"); + for (int i = 0; indecls; i++) { + if (ast->decls[i]->type == dvardecl) { + pindent(1, cout); + safe_fprintf(cout, "%s", ast->decls[i]->data.dvar->ident); + safe_fprintf(cout, " = "); + expr_genc(ast->decls[i]->data.dvar->expr, cout); + safe_fprintf(cout, ";\n"); + } + } +} + +static void fundecl_genc(const struct ast *ast, struct fundecl *decl, FILE *cout) { fundecl_sig(decl, cout); safe_fprintf(cout, "{\n"); + if (strcmp(decl->ident, "main") == 0) + initialise_non_constant_globals(ast, cout); ARRAY_ITER(struct stmt *, s, i, &decl->body) stmt_genc(s, 1, cout); AIEND safe_fprintf(cout, "}\n"); } -static void decl_genc(struct decl *decl, FILE *cout) + +static void decl_genc(const struct ast *ast, struct decl *decl, FILE *cout) { switch (decl->type) { case dcomp: if (ARRAY_SIZE(&decl->data.dcomp) > 1) { - ARRAY_ITER(struct fundecl *, d, i, &decl->data.dcomp) + ARRAY_ITER(struct fundecl *, d, i, &decl->data.dcomp) { fundecl_sig(d, cout); safe_fprintf(cout, ";\n"); - AIEND + } AIEND } ARRAY_ITER(struct fundecl *, d, i, &decl->data.dcomp) - fundecl_genc(d, cout); + fundecl_genc(ast, d, cout); AIEND break; case dfundecl: @@ -346,7 +363,14 @@ void genc(const struct ast *ast, const struct overload ol, FILE *cout) //Code for (int i = 0; indecls; i++) { - safe_fprintf(cout, "\n"); - decl_genc(ast->decls[i], cout); + //Vardecls only the type; + if (ast->decls[i]->type == dvardecl) { + type_genc(ast->decls[i]->data.dvar->type, cout); + safe_fprintf(cout, "%s", ast->decls[i]->data.dvar->ident); + safe_fprintf(cout, ";\n"); + } else { + safe_fprintf(cout, "\n"); + decl_genc(ast, ast->decls[i], cout); + } } } diff --git a/sem/hm.c b/sem/hm.c index 7e85878..30fc02a 100644 --- a/sem/hm.c +++ b/sem/hm.c @@ -147,7 +147,7 @@ struct subst *infer_expr(struct gamma *gamma, struct expr *expr, struct type *ty expr->data.efuncall.ident); s1 = infer_expr(gamma, a, t->data.tarrow.l); s0 = subst_union(s1, s0); - t = t->data.tarrow.r; + t = subst_apply_t(s0, t->data.tarrow.r); } AIEND if (t->type == tarrow) type_error(expr->loc, true, diff --git a/sem/type.c b/sem/type.c index e540d5f..ead0b40 100644 --- a/sem/type.c +++ b/sem/type.c @@ -141,25 +141,20 @@ static void type_comp(struct gamma *gamma, struct array decl) //unify against given type specification if (d->rtype != NULL) { + struct type *dt = d->rtype; // only check return type if (d->atypes == NULL) { - struct type *dt = d->rtype; for (int j = (int)ARRAY_SIZE(&d->args)-1; j>=0; j--) dt = type_arrow(gamma_fresh(gamma), dt); - struct subst *s1 = unify(d->loc, dt, t); - subst_apply_t(s1, fs[i]); - subst_free(s1); - type_free(dt); } else { - struct type *dt = d->rtype; for (int j = (int)ARRAY_SIZE(d->atypes)-1; j>=0; j--) dt = type_arrow(ARRAY_EL(struct type *, d->atypes, j), dt); - struct subst *s1 = unify(d->loc, dt, t); - subst_apply_t(s1, fs[i]); - subst_free(s1); - type_free(dt); } + struct subst *s1 = unify(d->loc, dt, t); + subst_apply_t(s1, t); + s0 = subst_union(s1, s0); + type_free(dt); } gamma_insert(gamma, ident_str(d->ident), scheme_generalise(gamma, t)); diff --git a/sem/vardecl.c b/sem/vardecl.c index 48005b9..b1d83dd 100644 --- a/sem/vardecl.c +++ b/sem/vardecl.c @@ -87,25 +87,23 @@ static void var_reorder(struct array *lp, struct array stmts, size_t *idx, bool ARRAY_ITER(struct stmt *, s, i, &stmts) { switch(s->type) { case svardecl: - if (top) { - array_move(lp, i, (*idx)++); - } else { - stmts.el[i] = stmt_assign( - safe_strdup(s->data.svardecl->ident), - array_null, s->data.svardecl->expr, s->loc); - s->data.svardecl->expr = NULL; - bool found = false; - ARRAY_ITER(struct stmt *, s1, j, lp) { - if (s1->type == svardecl && strcmp(s1->data.svardecl->ident, s->data.svardecl->ident) == 0) { - found = true; - break; - } - }AIEND - if (!found) - array_insert(lp, (*idx)++, s); - else - stmt_free(s); - } + stmts.el[i] = stmt_assign( + safe_strdup(s->data.svardecl->ident), + array_null, s->data.svardecl->expr, s->loc); + s->data.svardecl->expr = NULL; + bool found = false; + ARRAY_ITER(struct stmt *, s1, j, lp) { + if (s1->type == svardecl && strcmp(s1->data.svardecl->ident, s->data.svardecl->ident) == 0) { + found = true; + break; + } + }AIEND + if (!found) + array_insert(lp, (*idx)++, s); + else + stmt_free(s); + if (top) + i++; break; case swhile: var_reorder(lp, s->data.swhile.body, idx, false); -- 2.20.1