diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-14 00:31:03 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-14 00:31:03 +0000 |
commit | 07082593ab4abfbf9a3dd6729cb2e548ec303115 (patch) | |
tree | f6fa70b94a0bf263f2fa8af21b26aaae90e1965f /eval.c | |
parent | 454e026edc25b1d0f6b4f035d41b38a1e60e16e3 (diff) |
Implement code for running operators (both monadic and dyadic).
Also implement ⍨ and ⍥ since they are very simple
Diffstat (limited to 'eval.c')
-rw-r--r-- | eval.c | 93 |
1 files changed, 50 insertions, 43 deletions
@@ -17,32 +17,34 @@ Datum dyadfun(Datum, Datum); Datum parens(Datum, Datum); Datum nameis(Datum, Datum); Datum assign(Datum, Datum); +Datum monadop(Datum, Datum); +Datum dyadop(Datum, Datum); Datum *lookup(Datum); int bindingstrengths[13][13] = { /* A F H MO DO AF ( ) [ ] ← IS N */ - 4, 3, 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, /* F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ + 6, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ + 2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ + 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ 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, /* DO */ + 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */ - 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, /* ( */ - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /* ) */ + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, /* ( */ + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* ) */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* [ */ 0, 0, 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, /* IS */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, /* N */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, /* N */ }; evalfn evalfns[13][13] = { /* A F H MO DO AF ( ) [ ] ← IS N */ - strand, dyadfun, 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, /* F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ + strand, dyadfun, 0, monadop, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ + monadfun, 0, 0, monadop, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ + 0, 0, 0, monadop, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ 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, /* DO */ + dyadop, dyadop, dyadop, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DO */ monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */ 0, 0, 0, 0, 0, 0, 0, parens, 0, 0, 0, 0, 0, /* ( */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */ @@ -164,38 +166,7 @@ monadfun(Datum left, Datum right) Datum result; result.tag = ArrayTag; result.shy = 0; - - if(left.func.type == FunctypeDfn){ - Symtab *tmpsymtab = currentsymtab; - currentsymtab = newsymtab(); - if(left.func.left){ - Symbol *alpha = getsym(currentsymtab, L"⍺"); - alpha->value.tag = ArrayTag; - alpha->value.array = left.func.left; - /* no need to increment refs, since it was done on binding the arg */ - alpha->undefined = 0; - } - - Symbol *omega = getsym(currentsymtab, L"⍵"); - omega->value = right; - omega->undefined = 0; - incref(right.array); - - Datum *dfnres = evalline(left.func.dfn); - freesymtab(currentsymtab); - currentsymtab = tmpsymtab; - return *dfnres; /* TODO what if the evaluation failed */ - }else{ - /* TODO handle undefined functions here */ - if(left.func.left) - result.array = dyadfunctiondefs[left.func.code](left.func.left, right.array); - else - result.array = monadfunctiondefs[left.func.code](right.array); - } - - if(left.func.left) - freearray(left.func.left); - + result.array = runfunc(left.func, left.func.left, right.array); return result; } @@ -250,4 +221,40 @@ assign(Datum left, Datum right) } right.shy = 1; return right; +} + +Datum +monadop(Datum left, Datum right) +{ + traceprint("Applying left argument to operator\n"); + Datum *arg = malloc(sizeof(Datum)); + *arg = left; + + Datum result; + result.shy = 0; + result.tag = FunctionTag, + result.func.type = FunctypeOp; + result.func.operator = right.operator; + result.func.operator.left = arg; + result.func.left = nil; + if(arg->tag == ArrayTag) + incref(arg->array); + return result; +} + +Datum +dyadop(Datum left, Datum right) +{ + traceprint("Applying right argument to operator\n"); + Datum *arg = malloc(sizeof(Datum)); + *arg = right; + + Datum result; + result.shy = 0; + result.tag = MonadicOpTag, + result.operator = left.operator; + result.operator.right = arg; + if(arg->tag == ArrayTag) + incref(arg->array); + return result; }
\ No newline at end of file |