#include #include #include #include "apl9.h" Rune primmonopnames[] = L"¨⍨⌸⌶&"; Rune primdyadopnames[] = L"⍣.∘⍤⍥@⍠⌺"; Rune primhybridnames[] = L"/\⌿⍀"; Statement * lexline(Rune *line, Symtab *symtab) { int offset = 0; int len = runestrlen(line); 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])){ 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; } offset++; }else if(p = runestrchr(primfuncnames, line[offset])){ stmt->toks[stmt->ntoks].tag = FunctionTag; stmt->toks[stmt->ntoks].func.code = p-primfuncnames; offset++; }else if(p = runestrchr(primmonopnames, line[offset])){ stmt->toks[stmt->ntoks].tag = MonadicOpTag; stmt->toks[stmt->ntoks].func.code = p-primmonopnames; offset++; }else if(p = runestrchr(primdyadopnames, line[offset])){ stmt->toks[stmt->ntoks].tag = DyadicOpTag; stmt->toks[stmt->ntoks].func.code = p-primdyadopnames; offset++; }else if(isdigitrune(line[offset])){ char buf[64]; char *p = buf; while(isdigitrune(line[offset])){ p += runetochar(p, &line[offset]); offset++; } *p = 0; 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]; Rune *p = buf; while(isalpharune(line[offset]) || (line[offset] == L'⎕' && p == buf)){ if(quadname) *p = toupperrune(line[offset]); else *p = line[offset]; p++; offset++; } *p = 0; stmt->toks[stmt->ntoks].tag = NameTag; stmt->toks[stmt->ntoks].symbol = getsym(symtab, buf); }else{ print("Can't lex: %S\n", &line[offset]); free(stmt->toks); free(stmt); return 0; } stmt->ntoks++; } end: stmt->toks = realloc(stmt->toks, sizeof(Datum) * stmt->ntoks); return stmt; }