summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c128
1 files changed, 95 insertions, 33 deletions
diff --git a/eval.c b/eval.c
index 4f228a7..f6cdb0d 100644
--- a/eval.c
+++ b/eval.c
@@ -16,42 +16,62 @@ Datum monadfun(Datum, Datum);
Datum dyadfun(Datum, Datum);
Datum lpar(Datum, Datum);
Datum rpar(Datum, Datum);
+Datum nameis(Datum, Datum);
+Datum assign(Datum, Datum);
+Datum *lookup(Datum);
-int bindingstrengths[12][12] = {
-/* A F H MO DO AF ( ) { } [ ] */
- 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
- 4, 4, 4, 4, 4, 4, 0, 5, 4, 4, 4, 4, /* ( */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
+int bindingstrengths[15][15] = {
+/* A F H MO DO AF ( ) { } [ ] ← IS N */
+ 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
+ 5, 5, 5, 5, 5, 5, 0, 6, 5, 5, 5, 5, 5, 5, 5, /* ( */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ← */
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, /* N */
};
-evalfn evalfns[12][12] = {
-/* A F H MO DO AF ( ) { } [ ] */
- strand, dyadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
- monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
- monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
- lpar, lpar, lpar, lpar, lpar, 0, lpar, rpar, lpar, lpar, lpar, lpar, /* ( */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
+evalfn evalfns[15][15] = {
+/* A F H MO DO AF ( ) { } [ ] ← IS N */
+ strand, dyadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */
+ monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* MO */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */
+ monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
+ lpar, lpar, lpar, lpar, lpar, 0, lpar, rpar, lpar, lpar, lpar, lpar, lpar, lpar, lpar, /* ( */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* { */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* } */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ← */
+ assign, assign, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nameis, 0, 0, /* N */
};
Datum *
eval(Datum *tokens, int *ntoks)
{
+ errormsg = nil;
+
+ /* start by looking up first variable if needed */
+ if(*ntoks > 0 && tokens[(*ntoks)-1].tag == NameTag){
+ Datum *value = lookup(tokens[(*ntoks)-1]);
+ if(value == nil)
+ *ntoks = 0;
+ else
+ tokens[(*ntoks)-1] = *value;
+ }
+
while(*ntoks > 1){
int maxlevel = 0;
int offset;
@@ -59,6 +79,7 @@ eval(Datum *tokens, int *ntoks)
traceprint("CURRENT: %S\n", ppdatums(tokens, *ntoks));
for(offset = (*ntoks)-1; offset >= 0; offset--){
int level;
+retry:
if(offset == 0)
level = 0;
else{
@@ -66,11 +87,21 @@ eval(Datum *tokens, int *ntoks)
Datum right = tokens[offset];
level = bindingstrengths[left.tag][right.tag];
}
- if(level < maxlevel){
+
+ if(level == 0 && tokens[offset-1].tag == NameTag){
+ Datum *value = lookup(tokens[offset-1]);
+ if(value == nil){
+ *ntoks = 0;
+ return tokens;
+ }else{
+ tokens[offset-1] = *value;
+ goto retry;
+ }
+ }else if(level < maxlevel){
Datum left = tokens[offset];
Datum right = tokens[offset+1];
fn = evalfns[left.tag][right.tag];
- traceprint("Reducing %S and %S\n", ppdatum(left), ppdatum(right));
+ traceprint("Reducing %S and %S (fn=%p, level=%d, max=%d)\n", ppdatum(left), ppdatum(right), fn, level, maxlevel);
break;
}else if(level > maxlevel)
maxlevel = level;
@@ -88,10 +119,21 @@ eval(Datum *tokens, int *ntoks)
return tokens;
}
+Datum *
+lookup(Datum var)
+{
+ traceprint("VAR LOOKUP %S\n", var.symbol->name);
+ if(var.symbol->undefined){
+ errormsg = runesmprint("Variable undefined: %S\n", var.symbol->name);
+ return nil;
+ }else
+ return &var.symbol->value;
+}
+
Datum
strand(Datum left, Datum right)
{
- traceprint("Stranding\n");
+ traceprint("Stranding (%d %d)\n", left.array->stranded, right.array->stranded);
Datum result;
Array *leftarr = left.array->stranded ? left.array : fnEnclose(left.array);
Array *rightarr = right.array->stranded ? right.array : fnEnclose(right.array);
@@ -110,9 +152,9 @@ monadfun(Datum left, Datum right)
/* TODO handle undefined functions here */
if(left.func.left)
- result.array = dyadfunctiondefs[left.code](left.func.left, right.array);
+ result.array = dyadfunctiondefs[left.func.code](left.func.left, right.array);
else
- result.array = monadfunctiondefs[left.code](right.array);
+ result.array = monadfunctiondefs[left.func.code](right.array);
return result;
}
@@ -147,4 +189,24 @@ rpar(Datum left, Datum right)
Datum *result = eval(left.expr.toks, &left.expr.ntoks);
result[0].array->stranded = 0;
return result[0]; /* TODO handle error if ntoks != 1 */
+}
+
+Datum
+nameis(Datum left, Datum right)
+{
+ traceprint("NAME SYMBOL %p\n", left.symbol);
+ traceprint("NAMEIS %S←\n", left.symbol->name);
+ right.tag = AssignmentTag;
+ right.symbol = left.symbol;
+ return right;
+}
+
+Datum
+assign(Datum left, Datum right)
+{
+ left.symbol->value = right; /* TODO think about this*/
+ left.symbol->undefined = 0;
+ if(left.symbol->value.tag == ArrayTag)
+ left.symbol->value.array->stranded = 0;
+ return right;
} \ No newline at end of file