ref: ad872eeb19b4fcc41a5d34750ca6cdcf88a39795
dir: /scan.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"
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);
switch(r){
case '(':
newtok(tokens, TokLparen);
goto next;
case ')':
newtok(tokens, TokRparen);
goto next;
case '[':
newtok(tokens, TokLbrack);
goto next;
case ']':
newtok(tokens, TokRbrack);
goto next;
case '\n':
newtok(tokens, TokNewline);
goto next;
case L'⋄':
newtok(tokens, TokDiamond);
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;
}
*errp = "scan error";
return nil;
next:
cp += n;
}
return tokens;
}