summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c93
1 files changed, 50 insertions, 43 deletions
diff --git a/eval.c b/eval.c
index 6b59c74..e7b0a13 100644
--- a/eval.c
+++ b/eval.c
@@ -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