commit 049ae43efd3e365198d94cbc8e92688372e468c0
parent 195442a2e5a780e9f0f8a5ac8ef738ec2d4e7869
Author: m21c <ho*******@gmail.com>
Date: Fri, 8 Oct 2021 17:56:18 +0200
added node pool + command processor for later (compiler) memory management
Diffstat:
| M | compiler.c | | | 224 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
1 file changed, 202 insertions(+), 22 deletions(-)
diff --git a/compiler.c b/compiler.c
@@ -638,6 +638,9 @@ static void
tryprompt(Source *source, const char ch);
static bool
+processcommand(Source *source);
+
+static bool
mygetline(Source *source)
{
int i, l, c;
@@ -704,6 +707,10 @@ advance:
goto advance;
source->line[i] = 0;
+
+ if (in == stdin && source->line[0] == ':')
+ return processcommand(source);
+
return c != EOF || i;
}
@@ -1458,16 +1465,28 @@ getunarysuffix(Source *source)
/* - ast-node - */
+Node *poolednodes;
Node nodebuf[4096];
-int nodetop;
+int nodetop, poolednodecount, totalnodecount;
#define tokennode(source, lhs) makenode(&(source)->tok, (lhs))
static Node *
makenode(Node *orig, Node *lhs)
{
- Node *node = nodebuf + nodetop++;
+ Node *node;
+
+ if (poolednodes) {
+ node = poolednodes;
+ poolednodes = poolednodes->rhs;
+ node->rhs = NULL;
+ node->lhs = NULL;
+ --poolednodecount;
+ } else {
+ node = nodebuf + nodetop++;
+ }
+ ++totalnodecount;
*node = *orig;
node->lhs = lhs;
node->rhs = NULL;
@@ -1475,6 +1494,53 @@ makenode(Node *orig, Node *lhs)
return node;
}
+static void
+deleteenv(Env *env);
+
+static void
+deletenode(Node *node)
+{
+ if (node->kind == 0)
+ return;
+
+ if (node->kind == ASCOPE) {
+ Node *curr, *next;
+
+ if (node->u.env) {
+ assert(node->u.env->stmts == node);
+ node->u.env->stmts = NULL;
+ deleteenv(node->u.env);
+ }
+
+ for (curr = node->lhs; curr; curr = next) {
+ assert(curr->kind == ASTMT);
+ next = curr->rhs;
+ deletenode(curr);
+ }
+
+ } else if (node->kind == ASTMT) {
+ if (node->lhs)
+ deletenode(node->lhs);
+ } else {
+ if (node->rhs)
+ deletenode(node->rhs);
+
+ if (node->lhs)
+ deletenode(node->lhs);
+
+ if (node->u.payload && (node->kind == KIF ||
+ node->kind == KWHILE || node->kind == ALOOPUNTIL))
+ {
+ deletenode(node->u.payload);
+ }
+ }
+
+ ++poolednodecount;
+ node->kind = 0;
+ node->rhs = poolednodes;
+ poolednodes = node;
+}
+
/* - type-strcut - */
@@ -1671,6 +1737,15 @@ deferfuncenv(Source *source, int keydeclinfunc)
return true;
}
+static void
+deleteenv(Env *env)
+{
+ if (env->stmts)
+ deletenode(env->stmts);
+
+ /* TODO(m21c): delete env */
+}
+
/* - declaration - */
@@ -2148,7 +2223,7 @@ redodeclaration:
paramlist = exprlist(source, true, NULL);
paramlist = typecheck(functionenv, paramlist);
paramtype = paramlist->type;
- /* deletenode(paramlist); */
+ deletenode(paramlist);
for (param = functionenv->head; param;
param = param->next)
@@ -2418,7 +2493,7 @@ readatom(Source *source, int flags)
Type *ty = maketype(&lhs->loc, prim + TTUPLE, NULL);
ty->target = lhs->lhs->type;
ty->u.rtarget = lhs->rhs->type;
- /* deletenode(lhs); */
+ deletenode(lhs);
skipnewline(source);
expect(source, ')', "expected ')'");
@@ -2791,8 +2866,8 @@ exprlist(Source *source, bool isparam, Type *paramtype)
lhs->lhs->type = NULL;
lhs->rhs->type = NULL;
- /* deletenode(lhs->lhs); */
- /* deletenode(lhs->rhs) */
+ deletenode(lhs->lhs);
+ deletenode(lhs->rhs);
lhs->lhs = NULL;
lhs->rhs = NULL;
@@ -3364,7 +3439,7 @@ typecheck(Env *env, Node *expr)
expr->lhs = typecheck(env, lhs);
if (rhs)
- expr->rhs = typecheck(env, lhs);
+ expr->rhs = typecheck(env, rhs);
/* TODO(m21c): find a way how we do type-checking for the
* last expression in a statement-list, which
@@ -3510,7 +3585,8 @@ foldexpr(Env *env, Node *expr)
maskint(ty->size, lhs->u.u) op \
maskint(ty->size, rhs->u.u) \
); \
- /* delete(lhs); delete(rhs) */ \
+ deletenode(lhs); \
+ deletenode(rhs); \
} while (0)
#define isvalue(expr, value) (expr->kind == 'N' && \
@@ -3534,15 +3610,16 @@ foldexpr(Env *env, Node *expr)
} else if (isvalue(lhs, 0)) {
if (expr->kind == OADD) {
*expr = *rhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
} else {
expr->kind = OMINUS;
expr->lhs = rhs;
- /* delete(lhs) */
+ deletenode(lhs);
}
} else if (isvalue(rhs, 0)) {
*expr = *lhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs); deletenode(rhs);
}
return expr;
@@ -3565,21 +3642,26 @@ foldexpr(Env *env, Node *expr)
}
} else if (isvalue(lhs, 0)) {
*expr = *lhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
} else if (expr->kind == OMUL && isvalue(rhs, 0)) {
*expr = *rhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
} else if (isvalue(rhs, 0)) {
if (rhs->u.u == 0 && isinttype(ty))
error(&expr->loc, "division by zero");
*expr = *rhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
} else if (isvalue(lhs, 1)) {
*expr = *rhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
} else if (expr->kind == OMUL && isvalue(rhs, 1)) {
*expr = *lhs;
- /* delete(lhs); delete(rhs) */
+ deletenode(lhs);
+ deletenode(rhs);
}
return expr;
@@ -3587,7 +3669,7 @@ foldexpr(Env *env, Node *expr)
case OPLUS:
*expr = *lhs;
- /* delete(lhs) */
+ deletenode(lhs);
return expr;
case OMINUS:
@@ -3595,15 +3677,15 @@ foldexpr(Env *env, Node *expr)
if (isfloattype(ty)) {
expr->kind = 'N';
expr->u.d = maskfloat(ty->size, -lhs->u.d);
- /* delete(lhs) */
+ deletenode(lhs);
} else if (isinttype(ty)) {
expr->kind = 'N';
expr->u.u = maskint(ty->size, -lhs->u.u);
- /* delete(lhs) */
+ deletenode(lhs);
}
} else if (lhs->kind == OMINUS && lhs->lhs) {
*expr = *lhs->lhs;
- /* delete(lhs) */
+ deletenode(lhs);
}
return expr;
@@ -3683,7 +3765,7 @@ foldexpr(Env *env, Node *expr)
}
}
- /* delete(lhs); */
+ deletenode(lhs);
expr->kind = 'N';
return expr;
@@ -3692,7 +3774,7 @@ foldexpr(Env *env, Node *expr)
/* TODO(m21c): implement this properly! */
lhs = foldexpr(env, lhs);
if (lhs->type->kind == expr->type->kind)
- *expr = *lhs /*, delete(lhs) */;
+ *expr = *lhs, deletenode(lhs);
return expr;
@@ -4203,6 +4285,12 @@ printexpr(FILE *out, Node *expr, int indent)
{
int n = 0;
+ if (expr->kind == 0) {
+ n += highlight(out, HLKEYWORD);
+ n += fprintf(out, "_");
+ return 0;
+ }
+
if (getnumops(expr->kind) == 2) {
n += printoperant(out, expr->lhs, getprec(expr->kind), israssoc(expr->kind), indent);
n += highlight(out, HLDELIM);
@@ -4514,6 +4602,97 @@ initsource(Source *source, const char *filename, FILE *file)
/* - main-routine - */
+const char *
+isolatecommand(char **string)
+{
+ char *commandline = *string;
+ const char *command;
+
+ while (isspace(*commandline))
+ ++commandline;
+
+ command = commandline;
+
+ while (!isspace(*commandline) && *commandline)
+ ++commandline;
+
+ if (*commandline)
+ *commandline = 0, ++commandline;
+
+ *string = commandline;
+
+ return command;
+}
+
+static bool
+processcommand(Source *source)
+{
+ char *commandline = source->line + 1;
+
+ const char *command = isolatecommand(&commandline);
+
+ if (!strcmp(command, "exit")) {
+ source->line[0] = 0;
+ return false;
+ }
+
+ if (!strcmp(command, "memory")) {
+ int i;
+
+ printf("ast-nodes: %5u, deletes: %5u, total: %5u\n",
+ nodetop, poolednodecount, totalnodecount);
+
+ printf("type-nodes: %5u\n", typetop);
+ printf("declarations: %5u\n", decltop);
+ printf("environments: %5u\n", envtop);
+
+ for (i = 0; i < nodetop; ++i) {
+ if (nodebuf[i].kind == 0)
+ continue;
+
+ highlight(stdout, HLINFO);
+ printf("node[%u]:\n", i);
+ printexpr(stdout, nodebuf + i, 0);
+ printf("\n");
+ }
+
+ goto finish;
+ }
+
+ if (!strcmp(command, "delete")) {
+ command = isolatecommand(&commandline);
+
+ if (!strcmp(command, "node") || !strcmp(command, "ast-node") ||
+ isdigit(*command))
+ {
+ if (!isdigit(*command))
+ command = isolatecommand(&commandline);
+
+ int i = atoi(command);
+
+ if (i < 4096 && i >= 0) {
+ Node *node = nodebuf + i;
+
+ if (node->kind != 0)
+ deletenode(node);
+ else
+ printf("already deleted.\n");
+ } else {
+ fprintf(stderr, "error: invalid number.\n");
+ }
+ } else {
+ fprintf(stderr, "error: unknown argument '%s'.\n",
+ command);
+ }
+
+ goto finish;
+ }
+
+ fprintf(stderr, "error: unknown command '%s'.\n", command);
+finish:
+ return mygetline(source);
+}
+
int
main(int argc, char **argv)
{
@@ -4568,6 +4747,7 @@ main(int argc, char **argv)
highlight(stdout, HLNONE);
}
printf("\n");
+ /* deletenode(ast); */
if (getkind(source) == '\n') {