summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 23:07:08 +0000
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2022-01-20 23:07:08 +0000
commit230aac3c644df9d80c8eba507e6bc7c710b26b52 (patch)
treea440f14305fe71e148e6835f319869e5f04c16c4
parent56ddfd33a5564afefdf264c91f2eca2ac3c37e08 (diff)
Implement better dnfs semantics
-rw-r--r--apl9.h6
-rw-r--r--eval.c13
-rw-r--r--functions.c2
-rw-r--r--lexer.c10
-rw-r--r--main.c8
-rw-r--r--quadnames.c2
6 files changed, 22 insertions, 19 deletions
diff --git a/apl9.h b/apl9.h
index d86d659..acbfcbb 100644
--- a/apl9.h
+++ b/apl9.h
@@ -143,7 +143,7 @@ struct QuadnameDef
/* Function prototypes for the different source files */
/* main.c */
-Datum *evalline(Rune *);
+Datum *evalline(Rune *, int);
Rune *prompt(Rune *);
/* print.c */
@@ -153,7 +153,7 @@ Rune *pparray(Array *);
Rune *ppoperator(Operator);
/* lexer.c */
-Statement *lexline(Rune *);
+Statement *lexline(Rune *, int);
/* array.c */
Array *mkscalarint(vlong);
@@ -172,7 +172,7 @@ int comparearray(Array *, Array *, int);
Array *fillelement(Array *);
/* eval.c */
-Datum *eval(Statement *);
+Datum *eval(Statement *, int);
/* symbol.c */
Symbol *getsym(Symtab *, Rune *);
diff --git a/eval.c b/eval.c
index 7d9afbe..e794a38 100644
--- a/eval.c
+++ b/eval.c
@@ -52,7 +52,7 @@ evalfn evalfns[11][11] = {
};
Datum *
-eval(Statement *stmt)
+eval(Statement *stmt, int toplevel)
{
errormsg = nil;
@@ -122,6 +122,9 @@ retry:
}
}
if(stmt->ntoks == 1){
+ int stop = 0;
+ if(toplevel == 0 && !stmt->toks[0].shy)
+ stop = 1;
if(stmt->guard){
int guardOK = 1;
if(stmt->toks[0].tag != ArrayTag)
@@ -137,10 +140,10 @@ retry:
exits(nil);
}
if(stmt->toks[0].array->intdata[0] == 1)
- return eval(stmt->guard);
+ return eval(stmt->guard, toplevel);
}
- if(stmt->next)
- return eval(stmt->next);
+ if(stmt->next && !stop)
+ return eval(stmt->next, toplevel);
else
return stmt->toks;
}else
@@ -215,7 +218,7 @@ parens(Datum left, Datum right)
/* evaluate a parenthesis expression and return the result */
USED(right);
traceprint("PARENS: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
- Datum *result = eval(&left.stmt);
+ Datum *result = eval(&left.stmt, 1);
if(result[0].tag == ArrayTag)
result[0].array->stranded = 0;
result[0].shy = 0;
diff --git a/functions.c b/functions.c
index c82a9cb..7266f28 100644
--- a/functions.c
+++ b/functions.c
@@ -138,7 +138,7 @@ runfunc(Function f, Array *left, Array *right)
omega->undefined = 0;
incref(right);
- Datum *dfnres = evalline(f.dfn);
+ Datum *dfnres = evalline(f.dfn, 0);
freesymtab(currentsymtab);
currentsymtab = tmpsymtab;
return (*dfnres).array; /* TODO what if the evaluation failed */
diff --git a/lexer.c b/lexer.c
index b2990c8..f734912 100644
--- a/lexer.c
+++ b/lexer.c
@@ -7,7 +7,7 @@
Rune primhybridnames[] = L"/\⌿⍀";
Statement *
-lexline(Rune *line)
+lexline(Rune *line, int toplevel)
{
int offset = 0;
int len = runestrlen(line);
@@ -25,7 +25,7 @@ lexline(Rune *line)
}else if(runestrchr(L"←⋄⍝⍬", line[offset])){
switch(line[offset]){
case L'←': stmt->toks[stmt->ntoks].tag = ArrowTag; break;
- case L'⋄': stmt->next = lexline(&line[offset+1]); goto end;
+ case L'⋄': stmt->next = lexline(&line[offset+1], toplevel); goto end;
case L'⍝': goto end;
case L'⍬':
stmt->toks[stmt->ntoks].tag = ArrayTag;
@@ -34,7 +34,7 @@ lexline(Rune *line)
break;
}
offset++;
- }else if(line[offset] == ':'){
+ }else if(!toplevel && line[offset] == ':'){
Rune buf[MAX_LINE_LENGTH];
Rune *p = buf;
offset++;
@@ -44,7 +44,7 @@ lexline(Rune *line)
offset++;
}
*p = 0;
- stmt->guard = lexline(buf);
+ stmt->guard = lexline(buf, toplevel);
stmt->ntoks--;
}else if(line[offset] == '{'){
Rune buf[MAX_LINE_LENGTH];
@@ -81,7 +81,7 @@ lexline(Rune *line)
*p = 0;
offset++;
stmt->toks[stmt->ntoks].tag = LParTag;
- stmt->toks[stmt->ntoks].stmt = *lexline(buf);
+ stmt->toks[stmt->ntoks].stmt = *lexline(buf, toplevel);
stmt->ntoks++;
stmt->toks[stmt->ntoks].tag = RParTag;
}else if(p = runestrchr(primfuncnames, line[offset])){
diff --git a/main.c b/main.c
index ef6e948..96a6d07 100644
--- a/main.c
+++ b/main.c
@@ -30,7 +30,7 @@ main(int argc, char *argv[])
while(!off){
checkmem("main loop");
Rune *input = prompt(L"\t");
- Datum *result = evalline(input);
+ Datum *result = evalline(input, 1);
if(result == nil){
if(errormsg == nil)
off = 1;
@@ -64,10 +64,10 @@ prompt(Rune *pr)
}
Datum *
-evalline(Rune *line)
+evalline(Rune *line, int toplevel)
{
- Statement *stmts = lexline(line);
- Datum *result = eval(stmts);
+ Statement *stmts = lexline(line, toplevel);
+ Datum *result = eval(stmts, toplevel);
if(result)
return result;
else{
diff --git a/quadnames.c b/quadnames.c
index 14c431e..bb191c5 100644
--- a/quadnames.c
+++ b/quadnames.c
@@ -45,7 +45,7 @@ Datum *
getquad(void)
{
Rune *input = prompt(L"⎕:\n\t");
- Datum *result = evalline(input);
+ Datum *result = evalline(input, 1);
/* TODO check that the expression doesn't fail */
return result;
}