a->el[a->nel++] = x;
}
+void array_remove(struct array *a, size_t idx)
+{
+ for (size_t i = idx; i<a->nel-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; i<to-1; i++)
+ a->el[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 *))
//* 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 *));
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");
}
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'",
{
type_free(decl->type);
free(decl->ident);
- expr_free(decl->expr);
+ if (decl->expr != NULL)
+ expr_free(decl->expr);
free(decl);
}
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);
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");
}
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:
#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()
{
#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);
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;
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; i<ndecls && !found; i++) {
struct edge *edge = xalloc(1, struct edge);
edge->from = parent;
edge->to = (void *)decls[i];
- array_append(&l, edge);
+ array_append(l, edge);
found = true;
}
}
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)
array_init(&edges, nfun*2);
for (size_t i = 0; i<nfun; i++) {
ARRAY_ITER(struct stmt *, s, j, &fundecls[i]->data.dfun->body)
- edges = edges_stmt(nfun, fundecls, fundecls[i], s, edges);
+ edges_stmt(nfun, fundecls, fundecls[i], s, &edges);
AIEND
}
+#include <stdio.h>
+#include <string.h>
#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; i<ast->ndecls; 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
}
}
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");