shithub: lpa

ref: ad872eeb19b4fcc41a5d34750ca6cdcf88a39795
dir: /scan.c/

View raw version
#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;
}