ref: da6308e5df8ed9cdf8d8f6cad73eef10f31ac4b0
dir: /scan.c/
#include <u.h> #include <libc.h> #include <thread.h> #include "dat.h" #include "fns.h" struct { Rune spelling; int id; } primspecs[] = { L'+', PrimPlus, L'-', PrimMinus, }; Token * newtok(TokenList *tokens, int tag) { Token *new; tokens->count++; tokens->tokens = allocextra(tokens, sizeof(Token) * tokens->count); new = tokens->tokens + (tokens->count-1); new->tag = tag; return new; } TokenList * scan(char *buf, char **errp) { Rune r; int n; TokenList *tokens = alloc(DataTokenList); Token *tok; char *cp = buf; while(*cp){ n = chartorune(&r, cp); int new = -1; switch(r){ case L'(': new = TokLparen; break; case L')': new = TokRparen; break; case L'[': new = TokLbrack; break; case L']': new = TokRbrack; break; case L'{': new = TokLbrace; break; case L'}': new = TokRbrace; break; case L'\n': new = TokNewline; break; case L'⋄': new = TokDiamond; break; case L'∇': new = TokDel; break; case L'←': new = TokLarrow; break; case L';': new = TokSemi; break; } if(new != -1){ newtok(tokens, new); goto next; } for(int i = 0; i < nelem(primspecs); i++){ if(r == primspecs[i].spelling){ tok = newtok(tokens, TokPrimitive); tok->prim = primspecs[i].id; tok->nameclass = NameclassFunc; goto next; } } if(isspacerune(r)) goto next; if(isdigitrune(r)){ char *rest; vlong num = strtoll(cp, &rest, 10); n = rest - cp; tok = newtok(tokens, TokNumber); tok->num = num; goto next; } if(isalpharune(r)){ char *start = cp; do{ cp += n; n = chartorune(&r, cp); }while(isalpharune(r) || isdigitrune(r)); tok = newtok(tokens, TokName); usize size = cp - start; tok->name = malloc(size + 1); memcpy(tok->name, start, size); tok->name[size] = 0; continue; } *errp = "scan error"; return nil; next: cp += n; } newtok(tokens, TokEnd); return tokens; }