aboutsummaryrefslogtreecommitdiff
path: root/src/interpreter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpreter.c')
-rw-r--r--src/interpreter.c77
1 files changed, 32 insertions, 45 deletions
diff --git a/src/interpreter.c b/src/interpreter.c
index 4d1f8f9..93b1bdb 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -3,44 +3,31 @@
#include <stdio.h>
#include <string.h>
-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;
- }
- }
- Env *e = malloc(sizeof(Env));
- e->name = strdup(name);
- e->val = val;
- e->next = *env;
- *env = e;
+static void context_set(hashmap_t context, const char *name, int val) {
+ hashmap_insert(context, name, val);
}
-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;
- }
- env_update(env, name, 0);
- return env_lookup(env, name);
+static int context_get(hashmap_t context, const char *name) {
+ int *val = hashmap_get(context, name);
+ if (val) return *val;
+ return 0;
}
-void env_print(Env *env) {
- Env *e = env;
- while (e) {
- printf("%s = %d\n", e->name, e->val);
- e = e->next;
- }
+static void print_var(const char *name, int val) {
+ printf("%s = %d\n", name, val);
+}
+
+void context_print(hashmap_t context) {
+ hashmap_iterate(context, print_var);
}
-static int eval_aexpr(Env **env, ASTNode *node) {
+static int eval_aexpr(hashmap_t context, ASTNode *node) {
switch (node->type) {
case NT_INT: return node->u.d_int.val;
- case NT_VAR: return env_lookup(env, node->u.d_var.name);
+ case NT_VAR: return context_get(context, node->u.d_var.name);
case NT_AOP: {
- int aexp1 = eval_aexpr(env, node->u.d_aop.aexp1);
- int aexp2 = eval_aexpr(env, node->u.d_aop.aexp2);
+ int aexp1 = eval_aexpr(context, node->u.d_aop.aexp1);
+ int aexp2 = eval_aexpr(context, node->u.d_aop.aexp2);
switch (node->u.d_aop.aop) {
case AOP_ADD: return aexp1 + aexp2;
case AOP_SUB: return aexp1 - aexp2;
@@ -53,21 +40,21 @@ static int eval_aexpr(Env **env, ASTNode *node) {
}
}
-static int eval_bexpr(Env **env, ASTNode *node) {
+static int eval_bexpr(hashmap_t context, ASTNode *node) {
switch (node->type) {
case NT_BOP: {
- int bexp1 = eval_bexpr(env, node->u.d_bop.bexp1);
- int bexp2 = eval_bexpr(env, node->u.d_bop.bexp2);
+ int bexp1 = eval_bexpr(context, node->u.d_bop.bexp1);
+ int bexp2 = eval_bexpr(context, 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(env, node->u.d_not.bexp);
+ return !eval_bexpr(context, node->u.d_not.bexp);
case NT_ROP: {
- int aexp1 = eval_aexpr(env, node->u.d_rop.aexp1);
- int aexp2 = eval_aexpr(env, node->u.d_rop.aexp2);
+ int aexp1 = eval_aexpr(context, node->u.d_rop.aexp1);
+ int aexp2 = eval_aexpr(context, node->u.d_rop.aexp2);
switch (node->u.d_rop.rop) {
case ROP_EQ: return aexp1 == aexp2;
case ROP_NE: return aexp1 != aexp2;
@@ -83,30 +70,30 @@ static int eval_bexpr(Env **env, ASTNode *node) {
}
}
-void exec_stmt(Env **env, ASTNode *node) {
+void exec_stmt(hashmap_t context, 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(env, node->u.d_assign.aexp);
- env_update(env, var, val);
+ int val = eval_aexpr(context, node->u.d_assign.aexp);
+ context_set(context, var, val);
return;
}
case NT_SEQ:
- exec_stmt(env, node->u.d_seq.stm1);
- exec_stmt(env, node->u.d_seq.stm2);
+ exec_stmt(context, node->u.d_seq.stm1);
+ exec_stmt(context, node->u.d_seq.stm2);
return;
case NT_IF:
- if (eval_bexpr(env, node->u.d_if.bexp))
- exec_stmt(env, node->u.d_if.stm1);
+ if (eval_bexpr(context, node->u.d_if.bexp))
+ exec_stmt(context, node->u.d_if.stm1);
else
- exec_stmt(env, node->u.d_if.stm2);
+ exec_stmt(context, node->u.d_if.stm2);
return;
case NT_WHILE:
- while (eval_bexpr(env, node->u.d_while.bexp)) {
- exec_stmt(env, node->u.d_while.stm);
+ while (eval_bexpr(context, node->u.d_while.bexp)) {
+ exec_stmt(context, node->u.d_while.stm);
}
return;
default: