diff options
Diffstat (limited to 'lexer.c')
-rw-r--r-- | lexer.c | 61 |
1 files changed, 35 insertions, 26 deletions
@@ -8,40 +8,46 @@ Rune primmonopnames[] = L"¨⍨⌸⌶&"; Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺"; Rune primhybridnames[] = L"/\⌿⍀"; -Datum * -lexline(Rune *line, int *ntoks, Symtab *symtab) +Statement * +lexline(Rune *line, Symtab *symtab) { int offset = 0; int len = runestrlen(line); - Datum *tokens = mallocz(sizeof(Datum) * MAX_LINE_TOKENS, 1); - *ntoks = 0; + Statement *stmt = malloc(sizeof(Statement)); + stmt->ntoks = 0; + stmt->toks = mallocz(sizeof(Datum) * MAX_LINE_TOKENS, 1); + stmt->next = nil; + while(offset < len){ Rune *p; if(isspacerune(line[offset])){ offset++; continue; - }else if(runestrchr(L"(){}[]←", line[offset])){ + }else if(runestrchr(L"(){}[]←⋄", line[offset])){ switch(line[offset]){ - case '(': tokens[*ntoks].tag = LParTag; break; - case ')': tokens[*ntoks].tag = RParTag; break; - case '{': tokens[*ntoks].tag = LCurlTag; break; - case '}': tokens[*ntoks].tag = RCurlTag; break; - case '[': tokens[*ntoks].tag = LBracketTag; break; - case ']': tokens[*ntoks].tag = RBracketTag; break; - case L'←': tokens[*ntoks].tag = ArrowTag; break; + 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; } offset++; }else if(p = runestrchr(primfuncnames, line[offset])){ - tokens[*ntoks].tag = FunctionTag; - tokens[*ntoks].func.code = p-primfuncnames; + stmt->toks[stmt->ntoks].tag = FunctionTag; + stmt->toks[stmt->ntoks].func.code = p-primfuncnames; offset++; }else if(p = runestrchr(primmonopnames, line[offset])){ - tokens[*ntoks].tag = MonadicOpTag; - tokens[*ntoks].func.code = p-primmonopnames; + stmt->toks[stmt->ntoks].tag = MonadicOpTag; + stmt->toks[stmt->ntoks].func.code = p-primmonopnames; offset++; }else if(p = runestrchr(primdyadopnames, line[offset])){ - tokens[*ntoks].tag = DyadicOpTag; - tokens[*ntoks].func.code = p-primdyadopnames; + stmt->toks[stmt->ntoks].tag = DyadicOpTag; + stmt->toks[stmt->ntoks].func.code = p-primdyadopnames; offset++; }else if(isdigitrune(line[offset])){ char buf[64]; @@ -51,8 +57,8 @@ lexline(Rune *line, int *ntoks, Symtab *symtab) offset++; } *p = 0; - tokens[*ntoks].tag = ArrayTag; - tokens[*ntoks].array = mkscalarint(atoll(buf)); + stmt->toks[stmt->ntoks].tag = ArrayTag; + stmt->toks[stmt->ntoks].array = mkscalarint(atoll(buf)); }else if(isalpharune(line[offset]) || line[offset] == L'⎕'){ int quadname = L'⎕' == line[offset]; Rune buf[64]; @@ -66,14 +72,17 @@ lexline(Rune *line, int *ntoks, Symtab *symtab) offset++; } *p = 0; - tokens[*ntoks].tag = NameTag; - tokens[*ntoks].symbol = getsym(symtab, buf); + stmt->toks[stmt->ntoks].tag = NameTag; + stmt->toks[stmt->ntoks].symbol = getsym(symtab, buf); }else{ print("Can't lex: %S\n", &line[offset]); - *ntoks = 0; - break; + free(stmt->toks); + free(stmt); + return 0; } - (*ntoks)++; + stmt->ntoks++; } - return tokens; +end: + stmt->toks = realloc(stmt->toks, sizeof(Datum) * stmt->ntoks); + return stmt; }
\ No newline at end of file |