From: Mart Lubbers Date: Wed, 17 Mar 2021 14:02:32 +0000 (+0100) Subject: reorder variable declarations X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=b3d38cc734df4d2d57589ab00f292e84215f15fe;p=ccc.git reorder variable declarations --- diff --git a/array.c b/array.c index 6b7d313..2905f0d 100644 --- a/array.c +++ b/array.c @@ -33,12 +33,30 @@ void array_append(struct array *a, void *x) a->el[a->nel++] = x; } +void array_remove(struct array *a, size_t idx) +{ + for (size_t i = idx; inel-1; i++) + a[i] = a[i+1]; + a->nel--; +} + void array_insert(struct array *a, size_t idx, void *x) { - array_append(a, NULL); - for (size_t i = a->nel-1; i>idx; i--) - a->el[i] = a->el[i-1]; - a->el[idx] = x; + array_append(a, x); + array_move(a, a->nel-1, idx); +} + +void array_move(struct array *a, size_t from, size_t to) +{ + void *t = a->el[from]; + if (from < to) { + for (size_t i = from; iel[i] = a->el[i+1]; + } else if (from > to) { + for (size_t i = from; i>to; i--) + a->el[i] = a->el[i-1]; + } + a->el[to] = t; } void array_free(struct array *a, void (*freefun)(void *)) diff --git a/array.h b/array.h index e53698a..0f8fb28 100644 --- a/array.h +++ b/array.h @@ -46,6 +46,15 @@ void array_free(struct array *a, void (*freefun)(void *)); //* free all element and keep the array void array_clean(struct array *a, void (*freefun)(void *)); +//* insert an item in a specific place, moving the other items +void array_insert(struct array *a, size_t idx, void *x); + +//* remove an item from an array +void array_remove(struct array *a, size_t idx); + +//* move an item from a position to another +void array_move(struct array *a, size_t from, size_t to); + //* insert an item in a sorted array void array_binsert(void *key, struct array *a, int (*cmp)(const void *, const void *)); diff --git a/ast.c b/ast.c index ccc7a46..5ae01f2 100644 --- a/ast.c +++ b/ast.c @@ -287,8 +287,11 @@ void vardecl_print(struct vardecl *decl, int indent, FILE *out) safe_fprintf(out, "var"); else type_print(decl->type, out); - safe_fprintf(out, " %s = ", decl->ident); - expr_print(decl->expr, out); + safe_fprintf(out, " %s", decl->ident); + if (decl->expr != NULL) { + safe_fprintf(out, " = "); + expr_print(decl->expr, out); + } safe_fprintf(out, ";\n"); } @@ -468,7 +471,7 @@ static void expr_print2(struct expr *expr, FILE *out, struct ctx ctx) safe_fprintf(out, ")"); break; case ebool: - safe_fprintf(out, "%s", expr->data.ebool ? "true" : "false"); + safe_fprintf(out, "%s", expr->data.ebool ? "True" : "False"); break; case echar: safe_fprintf(out, "'%s'", @@ -544,7 +547,8 @@ void vardecl_free(struct vardecl *decl) { type_free(decl->type); free(decl->ident); - expr_free(decl->expr); + if (decl->expr != NULL) + expr_free(decl->expr); free(decl); } diff --git a/gen.c b/gen.c index dfacb2b..a115b3a 100644 --- a/gen.c +++ b/gen.c @@ -100,7 +100,8 @@ static void ol_stmt(struct overload *st, struct stmt *stmt) ol_expr(st, stmt->data.sexpr); break; case svardecl: - ol_expr(st, stmt->data.svardecl->expr); + if (stmt->data.svardecl->expr != NULL) + ol_expr(st, stmt->data.svardecl->expr); break; case swhile: ol_expr(st, stmt->data.swhile.pred); diff --git a/gen/c.c b/gen/c.c index 663dbde..889bf53 100644 --- a/gen/c.c +++ b/gen/c.c @@ -134,8 +134,11 @@ static void vardecl_genc(struct vardecl *vardecl, int indent, FILE *cout) return; pindent(indent, cout); type_genc(vardecl->type, cout); - safe_fprintf(cout, "%s = ", vardecl->ident); - expr_genc(vardecl->expr, cout); + safe_fprintf(cout, "%s", vardecl->ident); + if (vardecl->expr != NULL) { + safe_fprintf(cout, " = ", vardecl->ident); + expr_genc(vardecl->expr, cout); + } safe_fprintf(cout, ";\n"); } diff --git a/gen/ssm.c b/gen/ssm.c index 2e37d57..0a94702 100644 --- a/gen/ssm.c +++ b/gen/ssm.c @@ -366,7 +366,10 @@ static void stmt_genssm(struct genssmst *st, struct stmt *stmt, FILE *cout) safe_fprintf(cout, "ajs -1\n"); break; case svardecl: - expr_genssm(st, stmt->data.svardecl->expr, cout); + if (stmt->data.svardecl->expr != NULL) + expr_genssm(st, stmt->data.svardecl->expr, cout); + else + safe_fprintf(cout, "ldc 0\n"); add_vref(st, stmt->data.svardecl->ident, local, st->vdecl++); break; case swhile: diff --git a/sem/hm/subst.c b/sem/hm/subst.c index fdea48d..c46756f 100644 --- a/sem/hm/subst.c +++ b/sem/hm/subst.c @@ -5,9 +5,17 @@ #include "../hm.h" #include "../../list.h" -#define INCAP 50 +struct subst { + size_t nvar; + size_t capacity; + struct subst_entry *entries; +}; +struct subst_entry { + struct ident var; + struct type *type; +}; -#define KEEP_LIST +#define INCAP 50 struct subst *subst_id() { diff --git a/sem/hm/subst.h b/sem/hm/subst.h index 1e3cb8e..11d7c98 100644 --- a/sem/hm/subst.h +++ b/sem/hm/subst.h @@ -5,15 +5,7 @@ #include "../hm.h" #include "../../ident.h" -struct subst { - size_t nvar; - size_t capacity; - struct subst_entry *entries; -}; -struct subst_entry { - struct ident var; - struct type *type; -}; +struct subst; struct subst *subst_id(); struct subst *subst_insert(struct subst *s, struct ident ident, struct type *t); diff --git a/sem/scc.c b/sem/scc.c index 10681c0..93327a9 100644 --- a/sem/scc.c +++ b/sem/scc.c @@ -147,15 +147,15 @@ struct components *tarjans( return tj.head; } -struct array edges_expr(int ndecls, struct decl **decls, void *parent, - struct expr *expr, struct array l) +void edges_expr(int ndecls, struct decl **decls, void *parent, + struct expr *expr, struct array *l) { if (expr == NULL) - return l; + return; switch(expr->type) { case ebinop: - l = edges_expr(ndecls, decls, parent, expr->data.ebinop.l, l); - l = edges_expr(ndecls, decls, parent, expr->data.ebinop.r, l); + edges_expr(ndecls, decls, parent, expr->data.ebinop.l, l); + edges_expr(ndecls, decls, parent, expr->data.ebinop.r, l); break; case ebool: break; @@ -163,7 +163,7 @@ struct array edges_expr(int ndecls, struct decl **decls, void *parent, break; case efuncall: ARRAY_ITER(struct expr *, e, i, &expr->data.efuncall.args ) - l = edges_expr(ndecls, decls, parent, e, l); + edges_expr(ndecls, decls, parent, e, l); AIEND bool found = false; for (int i = 0; ifrom = parent; edge->to = (void *)decls[i]; - array_append(&l, edge); + array_append(l, edge); found = true; } } @@ -187,59 +187,53 @@ struct array edges_expr(int ndecls, struct decl **decls, void *parent, case enil: break; case etuple: - l = edges_expr(ndecls, decls, parent, - expr->data.etuple.left, l); - l = edges_expr(ndecls, decls, parent, - expr->data.etuple.right, l); + edges_expr(ndecls, decls, parent, expr->data.etuple.left, l); + edges_expr(ndecls, decls, parent, expr->data.etuple.right, l); break; case estring: break; case eunop: - return edges_expr(ndecls, decls, parent, expr->data.eunop.l, l); + edges_expr(ndecls, decls, parent, expr->data.eunop.l, l); + break; default: die("Unsupported expr node\n"); } - return l; } -struct array edges_stmt(int ndecls, struct decl **decls, void *parent, - struct stmt *stmt, struct array l) +void edges_stmt(int ndecls, struct decl **decls, void *parent, + struct stmt *stmt, struct array *l) { switch(stmt->type) { case sassign: - l = edges_expr(ndecls, decls, parent, - stmt->data.sassign.expr, l); + edges_expr(ndecls, decls, parent, stmt->data.sassign.expr, l); break; case sif: - l = edges_expr(ndecls, decls, parent, stmt->data.sif.pred, l); + edges_expr(ndecls, decls, parent, stmt->data.sif.pred, l); ARRAY_ITER(struct stmt *, s, i, &stmt->data.sif.then) - l = edges_stmt(ndecls, decls, parent, s, l); + edges_stmt(ndecls, decls, parent, s, l); AIEND ARRAY_ITER(struct stmt *, s, i, &stmt->data.sif.els) - l = edges_stmt(ndecls, decls, parent, s, l); + edges_stmt(ndecls, decls, parent, s, l); AIEND break; case sreturn: - l = edges_expr(ndecls, decls, parent, stmt->data.sreturn, l); + edges_expr(ndecls, decls, parent, stmt->data.sreturn, l); break; case sexpr: - l = edges_expr(ndecls, decls, parent, stmt->data.sexpr, l); + edges_expr(ndecls, decls, parent, stmt->data.sexpr, l); break; case svardecl: - l = edges_expr(ndecls, decls, parent, - stmt->data.svardecl->expr, l); + edges_expr(ndecls, decls, parent, stmt->data.svardecl->expr, l); break; case swhile: - l = edges_expr(ndecls, decls, parent, - stmt->data.swhile.pred, l); + edges_expr(ndecls, decls, parent, stmt->data.swhile.pred, l); ARRAY_ITER(struct stmt *, s, i, &stmt->data.swhile.body) - l = edges_stmt(ndecls, decls, parent, s, l); + edges_stmt(ndecls, decls, parent, s, l); AIEND break; default: die("Unsupported stmt node\n"); } - return l; } int declcmp(const void *l, const void *r) @@ -265,7 +259,7 @@ void sem_check_scc(struct ast *ast) array_init(&edges, nfun*2); for (size_t i = 0; idata.dfun->body) - edges = edges_stmt(nfun, fundecls, fundecls[i], s, edges); + edges_stmt(nfun, fundecls, fundecls[i], s, &edges); AIEND } diff --git a/sem/vardecl.c b/sem/vardecl.c index a1215c2..48005b9 100644 --- a/sem/vardecl.c +++ b/sem/vardecl.c @@ -1,16 +1,133 @@ +#include +#include #include "../ast.h" -void fix_vars_fun(struct fundecl *d) +static inline void var_refactor_ident(char **torep, char *from, size_t idx) { - (void)d; + char *t = *torep; + //This limits scopedepth to 9999 + *torep = xalloc(strlen(from)+5, char); + sprintf(*torep, "_%s%lu", from, idx); + free(t); +} + +static void var_refactor(struct array *body, size_t ifrom, char *from, size_t rescope, size_t scope); + +static void var_refactor_expr(struct expr *expr, char *from, size_t idx) +{ + switch (expr->type) { + case ebinop: + var_refactor_expr(expr->data.ebinop.l, from, idx); + var_refactor_expr(expr->data.ebinop.r, from, idx); + break; + case efuncall: + ARRAY_ITER(struct expr *, e, i, &expr->data.efuncall.args) { + var_refactor_expr(e, from, idx); + } AIEND + break; + case eident: + if (strcmp(from, expr->data.eident) == 0) + var_refactor_ident(&expr->data.eident, from, idx); + break; + case etuple: + var_refactor_expr(expr->data.etuple.left, from, idx); + var_refactor_expr(expr->data.etuple.right, from, idx); + break; + case eunop: + var_refactor_expr(expr->data.eunop.l, from, idx); + break; + default: + break; + } +} + +static void var_refactor(struct array *body, size_t ifrom, char *from, size_t rescope, size_t scope) +{ + ARRAY_ITER(struct stmt *, s, i, body) { + if (i < ifrom) + continue; + switch (s->type) { + case sassign: + if (strcmp(s->data.sassign.ident, from) == 0) + var_refactor_ident(&s->data.sassign.ident, from, rescope); + var_refactor_expr(s->data.sassign.expr, from, rescope); + break; + case svardecl: + var_refactor_expr(s->data.svardecl->expr, from, rescope); + if (s->data.svardecl->ident[0] != '_') { + var_refactor(body, i+1, s->data.svardecl->ident, scope, scope); + var_refactor_ident(&s->data.svardecl->ident, s->data.svardecl->ident, scope); + } + break; + case sexpr: + var_refactor_expr(s->data.sexpr, from, rescope); + break; + case sreturn: + if (s->data.sreturn != NULL) + var_refactor_expr(s->data.sreturn, from, rescope); + break; + case swhile: + var_refactor_expr(s->data.swhile.pred, from, rescope); + var_refactor(&s->data.swhile.body, 0, from, rescope, scope+1); + break; + case sif: + var_refactor_expr(s->data.sif.pred, from, rescope); + var_refactor(&s->data.sif.then, 0, from, rescope, scope+1); + var_refactor(&s->data.sif.els, 0, from, rescope, scope+1); + break; + default: + break; + } + } AIEND + +} + +static void var_reorder(struct array *lp, struct array stmts, size_t *idx, bool top) +{ + 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); + } + break; + case swhile: + var_reorder(lp, s->data.swhile.body, idx, false); + break; + case sif: + var_reorder(lp, s->data.sif.then, idx, false); + var_reorder(lp, s->data.sif.els, idx, false); + break; + default: + break; + } + } AIEND } void sem_check_vardecls(struct ast *ast) { for (int i = 0; indecls; i++) { if (ast->decls[i]->type == dcomp) { - ARRAY_ITER(struct fundecl *, d, i, &ast->decls[i]->data.dcomp) - fix_vars_fun(d); + ARRAY_ITER(struct fundecl *, d, j, &ast->decls[i]->data.dcomp) + var_refactor(&d->body, 0, "", 0, 0); + size_t idx = 0; + var_reorder(&d->body, d->body, &idx, true); AIEND } } diff --git a/splc.c b/splc.c index 8a4f1f3..48311c8 100644 --- a/splc.c +++ b/splc.c @@ -96,7 +96,7 @@ int main(int argc, char *argv[]) cout = safe_fopen(cfile, "w+"); free(cfile); -// gen(result, lang, cout); + gen(result, lang, cout); safe_fclose(cout); safe_fprintf(stderr, "code generation done\n");