From c83618999227adb5e745f92205bd48e076e2d124 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Sat, 29 Jul 2023 22:22:23 +0100 Subject: th --- run.c | 97 ++++++++++++++++++++++++++++++++----------------------------------- 1 file changed, 46 insertions(+), 51 deletions(-) (limited to 'run.c') diff --git a/run.c b/run.c index eb65400..e4fa540 100644 --- a/run.c +++ b/run.c @@ -1,39 +1,10 @@ #include "run.h" #include "ast.h" +#include "ht.h" #include #include -// static int valueof(AstNode *a) { -// if (a->ty != AST_NUM) { -// printf("i need a number\n"); -// return -1; -// } else { -// return a->as.num; -// } -// } - -// void run_thing(AstNode *a) { -// if (a->ty != AST_LIST) -// printf("can only run a list\n"); -// else if (a->as.list.len < 3) -// printf("need at least 3 elements\n"); -// else { -// AstNode *fn = &a->as.list.vals[0]; -// if (fn->ty != AST_SYMBOL) -// printf("first el needs to be symbol\n"); -// else if (strcmp(fn->as.str, "+")) -// printf("can only run +\n"); -// else { -// int v1 = valueof(&a->as.list.vals[1]); -// int v2 = valueof(&a->as.list.vals[2]); -// printf("=> %d\n",v1+v2); -// } -// } -// } - -int eval (AstNode a); - // return pointer to nth subnode of AST_LIST node *l. // doesn't check that l is a list, or that it has at least n elems. #define NTH(l,n) (&(l)->as.list.vals[(n)]) @@ -42,34 +13,51 @@ int eval (AstNode a); #define CK_LEN(s, l, n) do { if(l.len-1 != n) { \ printf("%s fn requires exactly %d args (%ld provided)",\ s, n, l.len-1); return 0; } } while(0); -static int func_plus(AstVec l) { +static int func_plus(Env *s, AstVec l) { CK_LEN("+",l,2); - return eval(l.vals[1]) + eval(l.vals[2]); + return eval(s, l.vals[1]) + eval(s, l.vals[2]); } -static int func_id(AstVec l) { +static int func_id(Env *s, AstVec l) { CK_LEN("id",l,1); - return eval(l.vals[1]); + return eval(s, l.vals[1]); } -static int func_minus(AstVec l) { +static int func_minus(Env *s, AstVec l) { CK_LEN("-",l,2); - return eval(l.vals[1]) - eval(l.vals[2]); + return eval(s, l.vals[1]) - eval(s, l.vals[2]); } -static int func_mult(AstVec l) { +static int func_mult(Env *s, AstVec l) { CK_LEN("*",l,2); - return eval(l.vals[1]) * eval(l.vals[2]); + return eval(s, l.vals[1]) * eval(s, l.vals[2]); } -static int func_div(AstVec l) { +static int func_div(Env *s, AstVec l) { CK_LEN("/",l,2); - return eval(l.vals[1]) / eval(l.vals[2]); + return eval(s, l.vals[1]) / eval(s, l.vals[2]); } -static int func_print(AstVec l) { +static int func_print(Env *s, AstVec l) { CK_LEN("print",l,1); - int v = eval(l.vals[1]); + int v = eval(s, l.vals[1]); printf("%d\n",v); return v; } +static int func_set(Env *s, AstVec l) { + CK_LEN("set", l, 2); + if (l.vals[1].ty != AST_SYMBOL) { + printf("can only assign to symbols"); + return 0; + } + int v = eval(s, l.vals[2]); + printf(" %p set %s %d\n", (void*)s, l.vals[1].as.str, v); + ht_put(s, l.vals[1].as.str, v); + return v; +} +static int func_do(Env *s, AstVec l) { + for (int i = 1; i < l.len; i++) { + eval(s, l.vals[i]); + } + return 0; +} -typedef int (*builtin_func)(AstVec); +typedef int (*builtin_func)(Env*, AstVec); typedef struct { char *name; builtin_func func; @@ -82,25 +70,32 @@ BuiltinDesc builtins[] = { { "/", func_div }, { "id", func_id }, { "print", func_print }, + { "set", func_set }, + { "do", func_do }, + { NULL, NULL }, }; -static int call_builtin(char *name, AstVec arglist) { +static int call_builtin(Env *s, char *name, AstVec arglist) { for (BuiltinDesc *bd = builtins; bd->name != NULL; bd++) { if (0 == strcmp(bd->name, name)) { - return bd->func(arglist); + return bd->func(s, arglist); } } printf("couldn't find builtin fn %s\n",name); return 0; } - -int eval(AstNode a) { +int eval(Env *s, AstNode a) { switch (a.ty) { - case AST_SYMBOL: - printf("cant yet read variable [%s]\n", a.as.str); - return 0; + case AST_SYMBOL:; + int v; + if (ht_get(s, a.as.str, &v)) { + return v; + } else { + printf("unset variable %s\n",a.as.str); + return 0; + } break; case AST_NUM: return a.as.num; @@ -116,7 +111,7 @@ int eval(AstNode a) { printf("first element of list must be symbol\n"); return 0; } - return call_builtin(first->as.str, l); + return call_builtin(s, first->as.str, l); break; default: printf("???\n"); -- cgit v1.2.3