summaryrefslogtreecommitdiff
path: root/run.c
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2023-07-29 22:22:23 +0100
committerubq323 <ubq323@ubq323.website>2023-07-29 22:22:23 +0100
commitc83618999227adb5e745f92205bd48e076e2d124 (patch)
treeebd862d08180fb49bdec90b553b21c89c43467fb /run.c
parentf9f7b92fdda17efe2dca455d6f641a424a97b2db (diff)
th
Diffstat (limited to 'run.c')
-rw-r--r--run.c97
1 files changed, 46 insertions, 51 deletions
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 <stdio.h>
#include <string.h>
-// 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");