diff options
-rw-r--r-- | eval.c | 29 | ||||
-rw-r--r-- | lexer.c | 32 |
2 files changed, 35 insertions, 26 deletions
@@ -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 */ } @@ -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; |