summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-12 20:09:05 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-12 20:09:05 +0000
commit55ca6248ffff6d9e1669fc49fe9de8489adeb7f9 (patch)
tree1bd23b6c91cb0c792ac1072cfe005cf2f5581551
parentd152639e4495089cabbbf7a16e5bc5129af78bfa (diff)
Add dfn evaluation, and localized ⎕IO
-rw-r--r--apl9.h5
-rw-r--r--eval.c19
-rw-r--r--lexer.c12
-rw-r--r--main.c2
-rw-r--r--symbol.c3
5 files changed, 33 insertions, 8 deletions
diff --git a/apl9.h b/apl9.h
index f30c6e8..64f7eba 100644
--- a/apl9.h
+++ b/apl9.h
@@ -99,13 +99,16 @@ typedef Array* (*fnmonad)(Array*);
typedef Array* (*fndyad)(Array*, Array*);
/* Function prototypes for the different source files */
+/* main.c */
+Datum *evalline(Rune *);
+
/* print.c */
Rune *ppdatum(Datum);
Rune *ppdatums(Datum *, int);
Rune *pparray(Array *);
/* lexer.c */
-Statement *lexline(Rune *, Symtab *);
+Statement *lexline(Rune *);
/* array.c */
Array *mkarray(int, int, int);
diff --git a/eval.c b/eval.c
index 4d0d497..3221b4c 100644
--- a/eval.c
+++ b/eval.c
@@ -150,10 +150,25 @@ monadfun(Datum left, Datum right)
traceprint("Monadic function application\n");
Datum result;
result.tag = ArrayTag;
+ result.shy = 0;
if(left.func.type == FunctypeDfn){
- print("Can't evaluate dfns yet: %S %S\n", ppdatum(left), ppdatum(right));
- exits(nil);
+ Symtab *tmpsymtab = currentsymtab;
+ currentsymtab = newsymtab();
+ if(left.func.left){
+ Symbol *alpha = getsym(currentsymtab, L"⍺");
+ alpha->value.tag = ArrayTag;
+ alpha->value.array = left.func.left;
+ alpha->undefined = 0;
+ }
+
+ Symbol *omega = getsym(currentsymtab, L"⍵");
+ omega->value = right;
+ omega->undefined = 0;
+
+ Datum *dfnres = evalline(left.func.dfn);
+ currentsymtab = tmpsymtab;
+ return *dfnres; /* TODO what if the evaluation failed */
}else{
/* TODO handle undefined functions here */
if(left.func.left)
diff --git a/lexer.c b/lexer.c
index eb5a3c4..1c35f91 100644
--- a/lexer.c
+++ b/lexer.c
@@ -9,7 +9,7 @@ Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺";
Rune primhybridnames[] = L"/\⌿⍀";
Statement *
-lexline(Rune *line, Symtab *symtab)
+lexline(Rune *line)
{
int offset = 0;
int len = runestrlen(line);
@@ -30,7 +30,7 @@ lexline(Rune *line, Symtab *symtab)
case '[': stmt->toks[stmt->ntoks].tag = LBracketTag; break;
case ']': stmt->toks[stmt->ntoks].tag = RBracketTag; break;
case L'←': stmt->toks[stmt->ntoks].tag = ArrowTag; break;
- case L'⋄': stmt->next = lexline(&line[offset+1], symtab); goto end;
+ case L'⋄': stmt->next = lexline(&line[offset+1]); goto end;
case L'⍝': goto end;
}
offset++;
@@ -73,6 +73,12 @@ lexline(Rune *line, Symtab *symtab)
*p = 0;
stmt->toks[stmt->ntoks].tag = ArrayTag;
stmt->toks[stmt->ntoks].array = mkscalarint(atoll(buf));
+ }else if(runestrchr(L"⍺⍵", line[offset])){
+ Rune *name = L"?";
+ name[0] = line[offset];
+ stmt->toks[stmt->ntoks].tag = NameTag;
+ stmt->toks[stmt->ntoks].symbol = getsym(currentsymtab, name);
+ offset++;
}else if(isalpharune(line[offset]) || line[offset] == L'⎕'){
int quadname = L'⎕' == line[offset];
Rune buf[64];
@@ -87,7 +93,7 @@ lexline(Rune *line, Symtab *symtab)
}
*p = 0;
stmt->toks[stmt->ntoks].tag = NameTag;
- stmt->toks[stmt->ntoks].symbol = getsym(symtab, buf);
+ stmt->toks[stmt->ntoks].symbol = getsym(currentsymtab, buf);
}else{
syntax_error:
print("Can't lex: %S\n", &line[offset]);
diff --git a/main.c b/main.c
index 9e9dfa9..2e12fff 100644
--- a/main.c
+++ b/main.c
@@ -59,7 +59,7 @@ prompt(Rune *pr)
Datum *
evalline(Rune *line)
{
- Statement *stmts = lexline(line, globalsymtab);
+ Statement *stmts = lexline(line);
Datum *result = eval(stmts);
if(result)
return result;
diff --git a/symbol.c b/symbol.c
index 6cdbffe..55e3f15 100644
--- a/symbol.c
+++ b/symbol.c
@@ -31,7 +31,8 @@ newsymtab(void)
Symbol *io = getsym(tab, L"⎕IO");
io->value.tag = ArrayTag;
- io->value.array = mkscalarint(1);
+ io->value.array = mkscalarint(currentsymtab ? globalIO() : 1);
+ io->value.shy = 0;
io->undefined = 0;
return tab;