diff --git a/lexer/error.go b/lexer/error.go index 6ffd479..541c7f8 100644 --- a/lexer/error.go +++ b/lexer/error.go @@ -1,6 +1,7 @@ package lexer import ( + "errors" "fmt" "strings" ) @@ -9,6 +10,14 @@ var ( _ error = (*Error)(nil) ) +var ( + // ErrUnacceptableRune indicates the read rune isn't acceptable in the context + ErrUnacceptableRune = errors.New("rune not acceptable in context") + + // ErrNotImplemented indicates something hasn't been implemented yet + ErrNotImplemented = errors.New("not implemented") +) + // Error represents a generic parsing error type Error struct { Filename string diff --git a/lexer/runes.go b/lexer/runes.go new file mode 100644 index 0000000..a69992d --- /dev/null +++ b/lexer/runes.go @@ -0,0 +1,41 @@ +package lexer + +import ( + "strings" + "unicode" +) + +// NewIsNot generates a rune condition checker that reverses the +// decision of the given checker. +func NewIsNot(cond func(rune) bool) func(rune) bool { + return func(r rune) bool { + return !cond(r) + } +} + +// NewIsIn generates a rune condition checker that accepts runes +// contained on the provided string +func NewIsIn(s string) func(rune) bool { + return func(r rune) bool { + return strings.ContainsRune(s, r) + } +} + +// NewIsOneOf generates a run condition checker that accepts runes +// accepted by any of the given checkers +func NewIsOneOf(s ...func(rune) bool) func(rune) bool { + return func(r rune) bool { + for _, cond := range s { + if cond(r) { + return true + } + } + return false + } +} + +// IsSpace reports whether the rune is a space character as +// defined by Unicode's White Space property +func IsSpace(r rune) bool { + return unicode.IsSpace(r) +}