summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-24 18:58:45 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-24 18:58:45 +0000
commit07fe0f96352967457d64ff349f4383c5568bcd42 (patch)
treeca598c01a412c9af15e530b9ec22de8adbaab48c
parent65bae1869f1451253276e51fea5b808b38685bf9 (diff)
Implement Dop's
-rw-r--r--eval.c4
-rw-r--r--functions.c23
-rw-r--r--lexer.c16
3 files changed, 32 insertions, 11 deletions
diff --git a/eval.c b/eval.c
index 658dde8..60c2e0d 100644
--- a/eval.c
+++ b/eval.c
@@ -32,7 +32,7 @@ int bindingstrengths[11][11] = {
0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, /* ( */
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* ) */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ← */
- 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */
+ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* IS */
0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, /* N */
};
@@ -47,7 +47,7 @@ evalfn evalfns[11][11] = {
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, 0, 0, 0, 0, 0, 0, 0, /* ← */
- assign, assign, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */
+ assign, assign, assign, assign, assign, 0, 0, 0, 0, 0, 0, /* IS */
0, 0, 0, 0, 0, 0, 0, 0, nameis, 0, 0, /* N */
};
diff --git a/functions.c b/functions.c
index bc71fb9..37cafa1 100644
--- a/functions.c
+++ b/functions.c
@@ -126,8 +126,15 @@ Array *
runfunc(Function f, Array *left, Array *right)
{
Array *result;
- if(f.type == FunctypeDfn){
- pushdfnframe(f.dfn);
+ if(f.type == FunctypeDfn || (f.type == FunctypeOp && f.operator.type == OperatortypeDop)){
+ Rune *code;
+ if(f.type == FunctypeDfn)
+ code = f.dfn;
+ else{
+ code = f.operator.dop;
+ }
+
+ pushdfnframe(code);
if(left){
Symbol *alpha = getsym(L"⍺", 1);
alpha->value.tag = ArrayTag;
@@ -142,7 +149,17 @@ runfunc(Function f, Array *left, Array *right)
omega->undefined = 0;
incref(right);
- Datum *dfnres = evalline(f.dfn, nil, 0);
+ if(f.type == FunctypeOp){
+ if(f.operator.dyadic){
+ Symbol *omegaop = getsym(L"⍹", 1);
+ omegaop->value = *f.operator.right;
+ omegaop->undefined = 0;
+ }
+ Symbol *alphaop = getsym(L"⍶", 1);
+ alphaop->value = *f.operator.left;
+ alphaop->undefined = 0;
+ }
+ Datum *dfnres = evalline(code, nil, 0);
popdfnframe();
result = (*dfnres).array; /* TODO what if the evaluation failed */
}else if(f.type == FunctypePrim){
diff --git a/lexer.c b/lexer.c
index 4ba0a30..54e6e9b 100644
--- a/lexer.c
+++ b/lexer.c
@@ -113,8 +113,12 @@ lexline(InputStream *input, int toplevel)
stmt->toks[stmt->ntoks].tag = FunctionTag;
stmt->toks[stmt->ntoks].func.type = FunctypeDfn;
stmt->toks[stmt->ntoks].func.dfn = runestrdup(buf);
- }else
- throwerror(L"Dops not implemented yet", ESyntax);
+ }else{
+ stmt->toks[stmt->ntoks].tag = oplevel == 1 ? MonadicOpTag : DyadicOpTag;
+ stmt->toks[stmt->ntoks].operator.type = OperatortypeDop;
+ stmt->toks[stmt->ntoks].operator.dyadic = oplevel == 2;
+ stmt->toks[stmt->ntoks].operator.dop = runestrdup(buf);
+ }
}else if(peek == '('){
int unclosed = 1;
Rune buf[MAX_LINE_LENGTH];
@@ -173,7 +177,7 @@ get_digits:
ungetrune(input);
stmt->toks[stmt->ntoks].tag = ArrayTag;
stmt->toks[stmt->ntoks].array = floating ? mkscalarfloat(atof(buf)) : mkscalarint(atoll(buf));
- }else if(runestrchr(L"⍺⍵", peek)){
+ }else if(runestrchr(L"⍺⍵⍶⍹", peek)){
Rune name[2] = {peek, 0};
stmt->toks[stmt->ntoks].tag = NameTag;
stmt->toks[stmt->ntoks].symbol = getsym(name, 1);
@@ -245,7 +249,7 @@ syntax_error:
free(stmt);
throwerror(err, ESyntax);
}
- /*print("Got token: %S\n", ppdatum(stmt->toks[stmt->ntoks]));*/
+ /* print("Got token: %S\n", ppdatum(stmt->toks[stmt->ntoks])); */
stmt->ntoks++;
peek = getrune(input);
}
@@ -278,7 +282,7 @@ getrune(InputStream *i)
else
r = i->string[i->offset++];
}
- /*print("Get rune: '%C' (%d)\n", r, r);*/
+ /* print("Get rune: '%C' (%d)\n", r, r); */
i->last = r;
return r;
}
@@ -286,7 +290,7 @@ getrune(InputStream *i)
void
ungetrune(InputStream *i)
{
- /*print("Unget rune: '%C' (%d)\n", i->last, i->last);*/
+ /* print("Unget rune: '%C' (%d)\n", i->last, i->last); */
if(inputEOF(i))
return;