func (l *lexer) nextState() stateFn {
	l.trimLeft()
	return l.state(l)
}
helper for state transtions that also trims whitespace
package cparse
import (
	"fmt"
	"unicode"
)
type token struct {
	typ tokenType
	pos int
	val string
}
var nullToken = token{
	typ: tokenNone,
}
type tokenType int
type ascii int8
const eof = -1
const (
	tokenNone tokenType = iota
	tokenError
	tokenString
	tokenNumber
	tokenSymbol
	tokenPlus
	tokenMinus
	tokenBoolNot
	tokenNot
	tokenMult
	tokenDiv
	tokenMod
	tokenLeftShift
	tokenRightShift
	tokenLess
	tokenLessEqual
	tokenGreater
	tokenGreaterEqual
	tokenEqual
	tokenNotEqual
	tokenAnd
	tokenXor
	tokenOr
	tokenBoolAnd
	tokenBoolOr
	tokenQuestion
	tokenColon
	tokenLeftParen
	tokenRightParen
	tokenComma
	tokenLeftBracket
	tokenRightBracket
)
var stringToToken = map[string]tokenType{
	"+": tokenPlus,
	"-": tokenMinus,
	"!": tokenBoolNot,
	"~": tokenNot,
	"*": tokenMult,
	"/": tokenDiv,
	"%": tokenMod,
	"<<": tokenLeftShift,
	">>": tokenRightShift,
	"<":  tokenLess,
	"<=": tokenLessEqual,
	">":  tokenGreater,
	">=": tokenGreaterEqual,
	"==": tokenEqual,
	"!=": tokenNotEqual,
	"&": tokenAnd,
	"^": tokenXor,
	"|": tokenOr,
	"&&": tokenBoolAnd,
	"||": tokenBoolOr,
	"?": tokenQuestion,
	":": tokenColon,
	"(": tokenLeftParen,
	")": tokenRightParen,
	",": tokenComma,
	"{": tokenLeftBracket,
	"}": tokenRightBracket,
}
type lexer struct {
	input  string      
	tokens chan token  
	state  stateFn     
	pos    int         
	start  int         
}
func NewLexer(input string) *lexer {
	l := &lexer{
		input:  input,
		tokens: make(chan token),
	}
	go l.run()
	return l
}
func (l *lexer) nextToken() token {
	return <-l.tokens
}
func (l *lexer) allTokens() []token {
	tokens := []token{}
	for t := range l.tokens {
		tokens = append(tokens, t)
	}
	return tokens
}