diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-11 23:21:05 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-11 23:21:05 +0000 |
commit | 37fe04b08b3cae7390f75eb1bb25d8fd4e958384 (patch) | |
tree | 53a6fd51258c5a7113b7bd7fa3766a47a0173070 /eval.c | |
parent | ba681c740d09deb36587b847a3307c68de933c4c (diff) |
First try at implementing variables
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 128 |
1 files changed, 95 insertions, 33 deletions
@@ -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 |