From f36482afc79c0a0fd78ab6dbcc427df2bc1542ef Mon Sep 17 00:00:00 2001 From: me Date: Sun, 11 Jan 2026 11:08:40 +0200 Subject: [PATCH] rename env to scope, and free pointers before they leak --- first-interpreter/src/execute.c | 63 ++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/first-interpreter/src/execute.c b/first-interpreter/src/execute.c index 6252d2b..2a0b74d 100644 --- a/first-interpreter/src/execute.c +++ b/first-interpreter/src/execute.c @@ -17,7 +17,7 @@ struct Cell { typedef struct { struct Cell* next; -} Environment; +} Scope; Memory new_memory() { unsigned size = 1024; @@ -33,12 +33,12 @@ Memory new_memory() { }; } -Environment new_environment() { - return (Environment) { .next = NULL }; +Scope new_scope() { + return (Scope) { .next = NULL }; } -int lookup_env(char* name, Environment env) { - struct Cell* cell = env.next; +int lookup_scope(char* name, Scope scope) { + struct Cell* cell = scope.next; while (cell != NULL) { if (strcmp(cell->name, name) == 0) { return cell->index; @@ -49,18 +49,18 @@ int lookup_env(char* name, Environment env) { return -1; } -Environment insert(char* name, int n, Memory memory, Environment env) { +Scope insert(char* name, int n, Memory memory, Scope scope) { if (*memory.i + 1 < memory.memory.length) { ((int*)(memory.memory.elements))[*memory.i] = n; struct Cell* cell = (struct Cell*)malloc(sizeof(struct Cell)); *cell = (struct Cell) { .name = name, .index = *memory.i, - .next = env.next, + .next = scope.next, }; ++*memory.i; - Environment new_env = (Environment) {.next = cell}; - return new_env; + Scope new_scope = (Scope) {.next = cell}; + return new_scope; } fprintf(stderr, "Error: out of memory."); exit(1); @@ -73,8 +73,8 @@ int* lookup_mem(int index, Memory mem) { return NULL; } -int* lookup(char* name, Memory memory, Environment env) { - int index = lookup_env(name, env); +int* lookup(char* name, Memory memory, Scope scope) { + int index = lookup_scope(name, scope); if (index >= 0) { int* result = lookup_mem(index, memory); if (result != NULL) { @@ -84,14 +84,14 @@ int* lookup(char* name, Memory memory, Environment env) { return NULL; } -int eval_expr(Expr expr, Memory memory, Environment env) { +int eval_expr(Expr expr, Memory memory, Scope scope) { switch (expr.tag) { default: case LITERAL: { return expr.data.integer; } case VARIABLE: { - int* result = lookup(expr.data.variable, memory, env); + int* result = lookup(expr.data.variable, memory, scope); if (result == NULL) { fprintf(stderr, "Error: variable not found '%s'\n", expr.data.variable); exit(1); @@ -102,7 +102,7 @@ int eval_expr(Expr expr, Memory memory, Environment env) { case FUNCTION: { if (strcmp(expr.data.function.name, "print") == 0) { if (expr.data.function.args.length == 1) { - int arg = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, env); + int arg = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, scope); printf("%d\n", arg); return 0; } else { @@ -112,8 +112,8 @@ int eval_expr(Expr expr, Memory memory, Environment env) { } else if (strcmp(expr.data.function.name, "add") == 0) { if (expr.data.function.args.length == 2) { - int arg1 = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, env); - int arg2 = eval_expr(((Expr*)expr.data.function.args.elements)[1], memory, env); + int arg1 = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, scope); + int arg2 = eval_expr(((Expr*)expr.data.function.args.elements)[1], memory, scope); return arg1 + arg2; } else { fprintf(stderr, "Error: negate expects a single argument.\n"); @@ -122,7 +122,7 @@ int eval_expr(Expr expr, Memory memory, Environment env) { } else if (strcmp(expr.data.function.name, "negate") == 0) { if (expr.data.function.args.length == 1) { - int arg = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, env); + int arg = eval_expr(((Expr*)expr.data.function.args.elements)[0], memory, scope); return 0 - arg; } else { fprintf(stderr, "Error: negate expects a single argument.\n"); @@ -134,40 +134,47 @@ int eval_expr(Expr expr, Memory memory, Environment env) { } } -Environment interpret_stmt(Stmt stmt, Memory memory, Environment env) { +Scope interpret_stmt(Stmt stmt, Memory memory, Scope scope) { switch (stmt.tag) { case SET: { - int result = eval_expr(stmt.data.Set.expr, memory, env); - int* index = lookup(stmt.data.Set.name, memory, env); + int result = eval_expr(stmt.data.Set.expr, memory, scope); + int* index = lookup(stmt.data.Set.name, memory, scope); if (index != NULL) { *index = result; } else { - return insert(stmt.data.Set.name, result, memory, env); + return insert(stmt.data.Set.name, result, memory, scope); } break; } case WHILE: { - while (eval_expr(stmt.data.While.condition, memory, env)) { - Environment new_env = env; + while (eval_expr(stmt.data.While.condition, memory, scope)) { + Scope new_scope = scope; for (unsigned i = 0; i < stmt.data.While.block.length; ++i) { Stmt current = ((Stmt*)stmt.data.While.block.elements)[i]; - new_env = interpret_stmt(current, memory, new_env); + new_scope = interpret_stmt(current, memory, new_scope); } + // free pointers before they leak + struct Cell* next = new_scope.next; + while (next != NULL && next != scope.next) { + struct Cell* nextnext = next->next; + free(next); + next = nextnext; + } } break; } case EXPR: - eval_expr(stmt.data.Expr.expr, memory, env); + eval_expr(stmt.data.Expr.expr, memory, scope); break; } - return env; + return scope; } void execute(StmtArray stmts) { Memory memory = new_memory(); - Environment environment = new_environment(); + Scope scope = new_scope(); for (unsigned pc = 0; pc < stmts.length; ++pc) { Stmt stmt = stmts.stmts[pc]; - environment = interpret_stmt(stmt, memory, environment); + scope = interpret_stmt(stmt, memory, scope); } }