func (l *Lexer) checkAlt(alts ...string) (alt string, ok bool) {
	for _, alt := range alts {
		if len(l.buf) >= len(alt) && string(l.buf[:len(alt)]) == alt {
			l.skipBy(len(alt))
			return alt, true
		}
	}
	return "", false
}
Check which token is currently at the beginning of the buffer.
Can be used to decide between tokens with the same beginning, e.g.
"=", "==", "=<", ">=".
Returns the first token matched, NOT the longest one, so order matters.
E.g. instead of "=", "=="; rather use "==", "=".
package have
import (
	"errors"
	"fmt"
	"unicode"
	"unicode/utf8"
	goscanner "go/scanner"
	gotoken "go/token"
)
type TokenType int
type Token struct {
	Type   TokenType
	Offset int
	Value  interface{}
	Pos    gotoken.Pos
}
func (t *Token) IsCompOp() bool {
	switch t.Type {
	case TOKEN_EQUALS, TOKEN_NEQUALS,
		TOKEN_LT, TOKEN_GT,
		TOKEN_EQ_LT, TOKEN_EQ_GT:
		return true
	}
	return false
}
func (t *Token) IsOrderOp() bool {
	switch t.Type {
	case TOKEN_LT, TOKEN_GT,
		TOKEN_EQ_LT, TOKEN_EQ_GT:
		return true
	}
	return false
}
func (t *Token) IsLogicalOp() bool {
	switch t.Type {
	case TOKEN_AND, TOKEN_OR:
		return true
	}
	return false
}
const (
	TOKEN_EOF          TokenType = iota + 1
	TOKEN_INDENT                  
	TOKEN_FOR                     
	TOKEN_WORD                    
	TOKEN_ASSIGN                  
	TOKEN_EQUALS                  
	TOKEN_NEQUALS                 
	TOKEN_GT                      
	TOKEN_LT                      
	TOKEN_EQ_LT                   
	TOKEN_EQ_GT                   
	TOKEN_NEGATE                  
	TOKEN_INT                     
	TOKEN_FLOAT                   
	TOKEN_IMAG                    
	TOKEN_STR                     
	TOKEN_RUNE                    
	TOKEN_DOT                     
	TOKEN_ELLIPSIS                
	TOKEN_LPARENTH                
	TOKEN_RPARENTH                
	TOKEN_LBRACKET                
	TOKEN_RBRACKET                
	TOKEN_LBRACE                  
	TOKEN_RBRACE                  
	TOKEN_PLUS                    
	TOKEN_PLUS_ASSIGN             
	TOKEN_INCREMENT               
	TOKEN_MINUS                   
	TOKEN_MINUS_ASSIGN            
	TOKEN_DECREMENT               
	TOKEN_VAR                     
	TOKEN_IF                      
	TOKEN_ELSE                    
	TOKEN_ELIF                    
	TOKEN_SWITCH                  
	TOKEN_CASE                    
	TOKEN_DEFAULT                 
	TOKEN_RETURN                  
	TOKEN_TRUE                    
	TOKEN_FALSE                   
	TOKEN_STRUCT                  
	TOKEN_MAP                     
	TOKEN_FUNC                    
	TOKEN_IMPORT                  
	TOKEN_AS                      
	TOKEN_TYPE                    
	TOKEN_IN                      
	TOKEN_PASS                    
	TOKEN_PACKAGE                 
	TOKEN_BREAK                   
	TOKEN_CONTINUE                
	TOKEN_FALLTHROUGH             
	TOKEN_GOTO                    
	TOKEN_INTERFACE               
	TOKEN_NIL                     
	TOKEN_CHAN                    
	TOKEN_RANGE                   
	TOKEN_WHEN                    
	TOKEN_IMPLEMENTS              
	TOKEN_IS                      
	TOKEN_MUL                     
	TOKEN_DIV                     
	TOKEN_MUL_ASSIGN              
	TOKEN_DIV_ASSIGN              
	TOKEN_SHL                     
	TOKEN_SHR                     
	TOKEN_SEND                    
	TOKEN_COMMA                   
	TOKEN_COLON                   
	TOKEN_SEMICOLON               
	TOKEN_AMP                     
	TOKEN_PIPE                    
	TOKEN_PERCENT                 
	TOKEN_AND                     
	TOKEN_OR                      
	TOKEN_SHARP                   
	TOKEN_UNEXP_CHAR              
)
type Lexer struct {
	all []rune
	buf []rune
	indentsStack []int
	tokenIndent *Token
	skipped int
	curTokenPos int
	offset int
	tfile *gotoken.File
}
func NewLexer(buf []rune, tfile *gotoken.File, offset int) *Lexer {
	return &Lexer{all: buf, buf: buf, indentsStack: []int{}, tfile: tfile, offset: offset}
}
func countWhiteChars(buf []rune) int {
	i := 0
	for i < len(buf) && (unicode.IsSpace(buf[i]) && buf[i] != '\n') {
		i++
	}
	return i
}
func (l *Lexer) skipWhiteChars() []rune {
	i := countWhiteChars(l.buf)
	whitespace := l.buf[:i]
	l.skipBy(i)
	return whitespace
}
func (l *Lexer) skipLine() []rune {
	c := 0
	for c < len(l.buf) && l.buf[c] != '\n' {
		c++
	}
	line := l.buf[0:c]
	l.skipBy(c)
	return line
}
func (l *Lexer) skipInlineComment() []rune {
	if len(l.buf) >= 2 && string(l.buf[:2]) == "//" {
		l.skipBy(2)
		return l.skipLine()
	}
	return nil
}
func (l *Lexer) skipMultilineComment() ([]rune, error) {
	c := 0
	for c < len(l.buf)-1 {
		if string(l.buf[c:c+2]) == "*/" {
			comment := l.buf[0:c]
			l.skipBy(c + 2)  
			return comment, nil
		}
		c++
	}
	return nil, errors.New("Did not close comment")
}
func (l *Lexer) skipFluff() {
	for {
		before := len(l.buf)
		l.skipWhiteChars()
		l.skipInlineComment()
		after := len(l.buf)
		if before == after {
			break
		}
	}
}
func (l *Lexer) scanWord() []rune {
	i := 0
	for i < len(l.buf) && (unicode.IsLetter(l.buf[i]) || unicode.IsNumber(l.buf[i]) || l.buf[i] == '_') {
		i++
	}
	result := l.buf[:i]
	l.skipBy(i)
	return result
}
func (l *Lexer) skip() {
	l.skipped++
	l.buf = l.buf[1:]
}
func (l *Lexer) skipBy(n int) {
	l.skipped += n
	l.buf = l.buf[n:]
}
func (l *Lexer) isEnd() bool {
	return len(l.buf) == 0
}