summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eval.c29
-rw-r--r--lexer.c32
2 files changed, 35 insertions, 26 deletions
diff --git a/eval.c b/eval.c
index 3221b4c..ab5dfc7 100644
--- a/eval.c
+++ b/eval.c
@@ -14,8 +14,7 @@ typedef Datum (*evalfn)(Datum, Datum);
Datum strand(Datum, Datum);
Datum monadfun(Datum, Datum);
Datum dyadfun(Datum, Datum);
-Datum lpar(Datum, Datum);
-Datum rpar(Datum, Datum);
+Datum parens(Datum, Datum);
Datum nameis(Datum, Datum);
Datum assign(Datum, Datum);
Datum *lookup(Datum);
@@ -28,13 +27,13 @@ int bindingstrengths[13][13] = {
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 */
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
- 5, 5, 5, 5, 5, 5, 0, 6, 5, 5, 5, 5, 5, /* ( */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ) */
+ 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, 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, 7, 0, 0, /* N */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, /* N */
};
evalfn evalfns[13][13] = {
@@ -45,7 +44,7 @@ evalfn evalfns[13][13] = {
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 */
monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* AF */
- lpar, lpar, lpar, lpar, lpar, 0, lpar, rpar, lpar, lpar, lpar, lpar, lpar, /* ( */
+ 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, 0, 0, 0, 0, 0, 0, /* [ */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ] */
@@ -191,24 +190,14 @@ dyadfun(Datum left, Datum right)
}
Datum
-lpar(Datum left, Datum right)
-{
- /* build up a parthenthesised expression */
- left.stmt.ntoks++;
- left.stmt.toks = realloc(left.stmt.toks, sizeof(Datum) * left.stmt.ntoks);
- left.stmt.toks[left.stmt.ntoks-1] = right;
- traceprint("LPAR: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
- return left;
-}
-
-Datum
-rpar(Datum left, Datum right)
+parens(Datum left, Datum right)
{
/* evaluate a parenthesis expression and return the result */
USED(right);
- traceprint("RPAR: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
+ traceprint("PARENS: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
Datum *result = eval(&left.stmt);
- result[0].array->stranded = 0;
+ if(result[0].tag == ArrayTag)
+ result[0].array->stranded = 0;
return result[0]; /* TODO handle error if ntoks != 1 */
}
diff --git a/lexer.c b/lexer.c
index 1c35f91..ceccf2f 100644
--- a/lexer.c
+++ b/lexer.c
@@ -23,10 +23,8 @@ lexline(Rune *line)
if(isspacerune(line[offset])){
offset++;
continue;
- }else if(runestrchr(L"()[]←⋄⍝", line[offset])){
+ }else if(runestrchr(L"[]←⋄⍝", line[offset])){
switch(line[offset]){
- case '(': stmt->toks[stmt->ntoks].tag = LParTag; break;
- case ')': stmt->toks[stmt->ntoks].tag = RParTag; break;
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;
@@ -34,22 +32,44 @@ lexline(Rune *line)
case L'⍝': goto end;
}
offset++;
- }else if(line[offset] == L'{'){
+ }else if(line[offset] == '{'){
Rune buf[MAX_LINE_LENGTH];
Rune *p = buf;
offset++;
- while(line[offset] != L'}' && offset < len){
+ while(line[offset] != '}' && offset < len){
*p = line[offset];
p++;
offset++;
}
- if(line[offset] != L'}')
+ if(line[offset] != '}')
goto syntax_error;
*p = 0;
offset++;
stmt->toks[stmt->ntoks].tag = FunctionTag;
stmt->toks[stmt->ntoks].func.type = FunctypeDfn;
stmt->toks[stmt->ntoks].func.dfn = runestrdup(buf);
+ }else if(line[offset] == '('){
+ int unclosed = 1;
+ Rune buf[MAX_LINE_LENGTH];
+ Rune *p = buf;
+ offset++;
+ while((line[offset] != ')' || unclosed > 1) && offset < len){
+ if(line[offset] == '(')
+ unclosed++;
+ else if(line[offset] == ')')
+ unclosed--;
+ *p = line[offset];
+ p++;
+ offset++;
+ }
+ if(line[offset] != ')')
+ goto syntax_error;
+ *p = 0;
+ offset++;
+ stmt->toks[stmt->ntoks].tag = LParTag;
+ stmt->toks[stmt->ntoks].stmt = *lexline(buf);
+ stmt->ntoks++;
+ stmt->toks[stmt->ntoks].tag = RParTag;
}else if(p = runestrchr(primfuncnames, line[offset])){
stmt->toks[stmt->ntoks].tag = FunctionTag;
stmt->toks[stmt->ntoks].func.type = FunctypePrim;