diff options
-rw-r--r-- | ast.c | 69 | ||||
-rw-r--r-- | ast.h | 10 | ||||
-rw-r--r-- | driver.c | 5 |
3 files changed, 41 insertions, 43 deletions
@@ -130,15 +130,7 @@ void free_ast(ASTNode *node) { free(node); } -typedef struct Env { - char *name; - int val; - struct Env *next; -} Env; - -static Env *env = NULL; - -static int env_lookup(const char *name) { +static int env_lookup(Env *env, const char *name) { for (Env *e = env; e; e = e->next) { if (strcmp(e->name, name) == 0) return e->val; @@ -147,8 +139,8 @@ static int env_lookup(const char *name) { exit(EXIT_FAILURE); } -static void env_update(const char *name, int val) { - for (Env *e = env; e; e = e->next) { +static void env_update(Env **env, const char *name, int val) { + for (Env *e = *env; e; e = e->next) { if (strcmp(e->name, name) == 0) { e->val = val; return; @@ -157,26 +149,25 @@ static void env_update(const char *name, int val) { Env *e = malloc(sizeof(Env)); e->name = strdup(name); e->val = val; - e->next = env; - env = e; + e->next = *env; + *env = e; } -void env_print(void) { - Env *current_env = env; - while (current_env) { - printf("%s = %d\n", current_env->name, current_env->val); - current_env = current_env->next; +void env_print(Env *env) { + Env *e = env; + while (e) { + printf("%s = %d\n", e->name, e->val); + e = e->next; } } - -static int eval_aexpr(ASTNode *node) { +static int eval_aexpr(Env **env, ASTNode *node) { switch (node->type) { case NT_INT: return node->u.d_int.val; - case NT_VAR: return env_lookup(node->u.d_var.name); + case NT_VAR: return env_lookup(*env, node->u.d_var.name); case NT_AOP: { - int aexp1 = eval_aexpr(node->u.d_aop.aexp1); - int aexp2 = eval_aexpr(node->u.d_aop.aexp2); + int aexp1 = eval_aexpr(env, node->u.d_aop.aexp1); + int aexp2 = eval_aexpr(env, node->u.d_aop.aexp2); switch (node->u.d_aop.aop) { case AOP_ADD: return aexp1 + aexp2; case AOP_SUB: return aexp1 - aexp2; @@ -189,21 +180,21 @@ static int eval_aexpr(ASTNode *node) { } } -static int eval_bexpr(ASTNode *node) { +static int eval_bexpr(Env **env, ASTNode *node) { switch (node->type) { case NT_BOP: { - int bexp1 = eval_bexpr(node->u.d_bop.bexp1); - int bexp2 = eval_bexpr(node->u.d_bop.bexp2); + int bexp1 = eval_bexpr(env, node->u.d_bop.bexp1); + int bexp2 = eval_bexpr(env, node->u.d_bop.bexp2); switch (node->u.d_bop.bop) { case BOP_AND: return bexp1 && bexp2; case BOP_OR: return bexp1 || bexp2; } } case NT_NOT: - return !eval_bexpr(node->u.d_not.bexp); + return !eval_bexpr(env, node->u.d_not.bexp); case NT_ROP: { - int aexp1 = eval_aexpr(node->u.d_rop.aexp1); - int aexp2 = eval_aexpr(node->u.d_rop.aexp2); + int aexp1 = eval_aexpr(env, node->u.d_rop.aexp1); + int aexp2 = eval_aexpr(env, node->u.d_rop.aexp2); switch (node->u.d_rop.rop) { case ROP_EQ: return aexp1 == aexp2; case ROP_NE: return aexp1 != aexp2; @@ -219,30 +210,30 @@ static int eval_bexpr(ASTNode *node) { } } -void exec_stmt(ASTNode *node) { +void exec_stmt(Env **env, ASTNode *node) { while (node) { switch (node->type) { case NT_SKIP: return; case NT_ASSIGN: { char *var = node->u.d_assign.var->u.d_var.name; - int val = eval_aexpr(node->u.d_assign.aexp); - env_update(var, val); + int val = eval_aexpr(env, node->u.d_assign.aexp); + env_update(env, var, val); return; } case NT_SEQ: - exec_stmt(node->u.d_seq.stm1); - exec_stmt(node->u.d_seq.stm2); + exec_stmt(env, node->u.d_seq.stm1); + exec_stmt(env, node->u.d_seq.stm2); return; case NT_IF: - if (eval_bexpr(node->u.d_if.bexp)) - exec_stmt(node->u.d_if.stm1); + if (eval_bexpr(env, node->u.d_if.bexp)) + exec_stmt(env, node->u.d_if.stm1); else - exec_stmt(node->u.d_if.stm2); + exec_stmt(env, node->u.d_if.stm2); return; case NT_WHILE: - while (eval_bexpr(node->u.d_while.bexp)) { - exec_stmt(node->u.d_while.stm); + while (eval_bexpr(env, node->u.d_while.bexp)) { + exec_stmt(env, node->u.d_while.stm); } return; default: @@ -38,9 +38,15 @@ ASTNode *ast_bop(BOp bop, ASTNode *bexp1, ASTNode *bexp2); ASTNode *ast_not(ASTNode *bexp); ASTNode *ast_rop(ROp rop, ASTNode *aexp1, ASTNode *aexp2); -void exec_stmt(ASTNode *node); +typedef struct Env { + char *name; + int val; + struct Env *next; +} Env; + +void exec_stmt(Env **env, ASTNode *node); void free_ast(ASTNode *node); -void env_print(void); +void env_print(Env *env); #endif @@ -22,8 +22,9 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - exec_stmt(ast_root); - env_print(); + Env *env = NULL; + exec_stmt(&env, ast_root); + env_print(env); free_ast(ast_root); return EXIT_SUCCESS; |