func stWhitespace(l lex.Lexer) lex.StateFn { for next := l.PeekRune(0); inMapR(next, whitespaceChars); next = l.PeekRune(0) { l.NextRune() if next == '\n' { l.NewLine() } } emit(l, Whitespace) return stStart }
func stHex(l lex.Lexer) lex.StateFn { if l.NextRune() != '0' { emitError("Hex numbers should start with 0") return nil } if unicode.ToLower(l.NextRune()) != 'x' { emitError("Malformatted hex number (no x)") return nil } baseChars := 0 for ; inMapR(l.PeekRune(0), hexdigits); baseChars++ { l.NextRune() } fmt.Println("Base Chars:", baseChars) if l.PeekRune(0) == '.' { l.NextRune() if !l.MatchOneOrMoreBytes(hexdigits_b) { emitError("Malformed hex number.") return nil } } else if baseChars == 0 { emitError("Malformed hex number (no base chars or decimal).") return nil } if unicode.ToLower(l.PeekRune(0)) == 'p' { l.NextRune() next := l.PeekRune(0) if next == '+' || next == '-' { l.NextRune() } if !l.MatchOneOrMoreBytes(digits_b) { emitError("Malformed hex number (no digits after p)") return nil } } emit(l, HexNumber) return stStart }
// longStringEquals peeks the bytestream to see if // a long string beginning is directly ahead. It returns the amount // of equals the long string has, or -1 if // no string found func longStringEquals(delim rune, l lex.Lexer) int { if l.PeekRune(0) != delim { return -1 } equalsCt := 0 for l.PeekRune(equalsCt+1) == '=' { equalsCt++ } if l.PeekRune(equalsCt+1) != delim { return -1 } return equalsCt }
func stStart(l lex.Lexer) lex.StateFn { char := l.PeekRune(0) switch true { case char == lex.RuneEOF: l.EmitEOF() return nil // Read comments case char == '-' && l.PeekRune(1) == '-': return stComment // Double-quote string case char == '"' || char == '\'': return stReadString // Read 3char symbols case inMapR(char, symbols_3c_1) && inMap(concatRunes(char, l.PeekRune(1), l.PeekRune(2)), symbols_3c): l.NextRune() l.NextRune() l.NextRune() emit(l, Symbol) return stStart // 2char symbols case inMapR(char, symbols_2c_1) && inMap(concatRunes(char, l.PeekRune(1)), symbols_2c): l.NextRune() l.NextRune() emit(l, Symbol) return stStart // 1char symbols case inMapR(char, symbols_1c): l.NextRune() emit(l, Symbol) return stStart // Read a Name identifier case inMapR(char, nameFirstChar): return stReadName // Read whitespace case inMapR(char, whitespaceChars): emit(l, Whitespace) return stWhitespace // Read Long strings case longStringEquals('[', l) >= 0: return stLongString // Read hex numbers case char == '0' && (unicode.ToLower(l.PeekRune(1)) == 'x'): return stHex // Read normal numbers case inMapR(char, digits): return stNumber } return nil }