func (l *Lexer) lexInput() { // set up to lex an input in := <-l.inputs l.str = in l.length = len(in) l.pos = 0 l.runePeeked = false // until input is done or error for { select { // abandon input case <-l.messageOut: l.messageBack <- "lexer: breaking" l.tokens <- token.New(token.EOF, "EOF") return // continue input default: t := l.lexToken() l.tokens <- t if t.Type == token.EOF { return } } } }
// lex next token of input func (l *Lexer) lexToken() token.Item { switch r := l.peekRune(); { // skip whitespace and comments, find next token case isSpace(r): l.nextRune() return l.lexToken() case r == ';': l.skipComment() return l.lexToken() // parenthesis case r == '(': l.nextRune() return token.New(token.LParen, "(") case r == ')': l.nextRune() return token.New(token.RParen, ")") // constant case r == '#': constant := l.lexConst() return token.New(token.Const, constant) // quote case r == '\'': l.nextRune() return token.New(token.Quote, "'") // end of file case r == eof: return token.New(token.EOF, "EOF") // otherwise symbol default: sym := l.lexSym() return token.New(token.Sym, sym) } }