more fixes, vardecl ordering fixed
authorMart Lubbers <mart@martlubbers.net>
Thu, 18 Mar 2021 12:52:54 +0000 (13:52 +0100)
committerMart Lubbers <mart@martlubbers.net>
Thu, 18 Mar 2021 12:52:54 +0000 (13:52 +0100)
gen.c
gen.h
gen/c.c
sem/hm.c
sem/type.c
sem/vardecl.c

diff --git a/gen.c b/gen.c
index a115b3a..8b741ad 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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; i<ast->ndecls; 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; i<ast->ndecls; 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);
+               }
        }
 }
index 7e85878..30fc02a 100644 (file)
--- 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,
index e540d5f..ead0b40 100644 (file)
@@ -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));
index 48005b9..b1d83dd 100644 (file)
@@ -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);