diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-12 19:42:14 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-01-12 19:42:14 +0000 |
commit | d152639e4495089cabbbf7a16e5bc5129af78bfa (patch) | |
tree | b1f63531e0f02b850ae84721fd5799a4827f64db | |
parent | fe3ef88c4147c4188066873e570f56212ffeebfd (diff) |
Add dfn parsing, but not evaluation yet
-rw-r--r-- | apl9.h | 11 | ||||
-rw-r--r-- | eval.c | 79 | ||||
-rw-r--r-- | lexer.c | 29 | ||||
-rw-r--r-- | mkfile | 2 | ||||
-rw-r--r-- | print.c | 16 |
5 files changed, 82 insertions, 55 deletions
@@ -12,8 +12,6 @@ typedef enum BoundFunctionTag, /* Function with left arg bound */ LParTag, RParTag, - LCurlTag, - RCurlTag, LBracketTag, RBracketTag, ArrowTag, @@ -27,6 +25,12 @@ typedef enum AtypeArray, } arrayDataType; +typedef enum +{ + FunctypeDfn, + FunctypePrim, +} functionType; + /* Data types */ typedef struct Array Array; typedef struct Statement Statement; @@ -58,9 +62,10 @@ struct Statement struct Function { + functionType type; union { int code; - Statement *dfn; + Rune *dfn; }; Array *left; }; @@ -20,42 +20,38 @@ Datum nameis(Datum, Datum); Datum assign(Datum, Datum); Datum *lookup(Datum); -int bindingstrengths[15][15] = { -/* A F H MO DO AF ( ) { } [ ] ← IS N */ - 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ - 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ - 0, 0, 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, 0, 0, /* DO */ - 2, 0, 0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, /* ← */ - 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, /* N */ +int bindingstrengths[13][13] = { +/* A F H MO DO AF ( ) [ ] ← IS N */ + 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ + 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, 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 */ }; -evalfn evalfns[15][15] = { -/* A F H MO DO AF ( ) { } [ ] ← IS N */ - strand, dyadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ - monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ - 0, 0, 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, 0, 0, /* DO */ - monadfun, 0, 0, 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, lpar, lpar, /* ( */ - 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, 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, 0, 0, /* ← */ - assign, assign, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nameis, 0, 0, /* N */ +evalfn evalfns[13][13] = { +/* A F H MO DO AF ( ) [ ] ← IS N */ + strand, dyadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A */ + monadfun, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* H */ + 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, 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, 0, /* ← */ + assign, assign, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* IS */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, nameis, 0, 0, /* N */ }; Datum * @@ -155,11 +151,16 @@ monadfun(Datum left, Datum right) Datum result; result.tag = ArrayTag; - /* TODO handle undefined functions here */ - if(left.func.left) - result.array = dyadfunctiondefs[left.func.code](left.func.left, right.array); - else - result.array = monadfunctiondefs[left.func.code](right.array); + if(left.func.type == FunctypeDfn){ + print("Can't evaluate dfns yet: %S %S\n", ppdatum(left), ppdatum(right)); + exits(nil); + }else{ + /* TODO handle undefined functions here */ + if(left.func.left) + result.array = dyadfunctiondefs[left.func.code](left.func.left, right.array); + else + result.array = monadfunctiondefs[left.func.code](right.array); + } return result; } @@ -23,24 +23,36 @@ lexline(Rune *line, Symtab *symtab) 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 = LCurlTag; break; - case '}': stmt->toks[stmt->ntoks].tag = RCurlTag; 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; - case L'⋄': - stmt->next = lexline(&line[offset+1], symtab); - goto end; - case L'⍝': - goto end; + case L'⋄': stmt->next = lexline(&line[offset+1], symtab); goto end; + case L'⍝': goto end; } offset++; + }else if(line[offset] == L'{'){ + Rune buf[MAX_LINE_LENGTH]; + Rune *p = buf; + offset++; + while(line[offset] != L'}' && offset < len){ + *p = line[offset]; + p++; + offset++; + } + if(line[offset] != L'}') + 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(p = runestrchr(primfuncnames, line[offset])){ stmt->toks[stmt->ntoks].tag = FunctionTag; + stmt->toks[stmt->ntoks].func.type = FunctypePrim; stmt->toks[stmt->ntoks].func.code = p-primfuncnames; offset++; }else if(p = runestrchr(primmonopnames, line[offset])){ @@ -77,6 +89,7 @@ lexline(Rune *line, Symtab *symtab) stmt->toks[stmt->ntoks].tag = NameTag; stmt->toks[stmt->ntoks].symbol = getsym(symtab, buf); }else{ +syntax_error: print("Can't lex: %S\n", &line[offset]); free(stmt->toks); free(stmt); @@ -1,6 +1,6 @@ </$objtype/mkfile -TARG=apl9 +TARG=apl OFILES=\ main.$O\ lexer.$O\ @@ -10,15 +10,23 @@ ppdatum(Datum d) Rune *result; switch(d.tag){ case ArrayTag: result = pparray(d.array); break; - case FunctionTag: result = runesmprint("%C", primfuncnames[d.func.code]); break; + case FunctionTag: + if(d.func.type == FunctypePrim) + result = runesmprint("%C", primdyadopnames[d.func.code]); + else + result = runesmprint("{%S}", d.func.dfn); + break; case HybridTag: result = runesmprint("%C", primhybridnames[d.func.code]); break; case MonadicOpTag: result = runesmprint("%C", primmonopnames[d.func.code]); break; case DyadicOpTag: result = runesmprint("%C", primdyadopnames[d.func.code]); break; - case BoundFunctionTag: result = runesmprint("%S∘%C", pparray(d.func.left), primfuncnames[d.func.code]); break; + case BoundFunctionTag: + if(d.func.type == FunctypePrim) + result = runesmprint("%S∘%C", pparray(d.func.left), primdyadopnames[d.func.code]); + else + result = runesmprint("%S∘{%S}", pparray(d.func.left), d.func.dfn); + break; case LParTag: result = runestrdup(L"("); break; case RParTag: result = runestrdup(L")"); break; - case LCurlTag: result = runestrdup(L"{"); break; - case RCurlTag: result = runestrdup(L"}"); break; case LBracketTag: result = runestrdup(L"["); break; case RBracketTag: result = runestrdup(L"]"); break; case ArrowTag: result = runestrdup(L"←"); break; |