aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/lang/scanner/errors.go8
-rw-r--r--pkg/lang/scanner/scanner.go35
2 files changed, 43 insertions, 0 deletions
diff --git a/pkg/lang/scanner/errors.go b/pkg/lang/scanner/errors.go
index 6a6f9d9..a982b60 100644
--- a/pkg/lang/scanner/errors.go
+++ b/pkg/lang/scanner/errors.go
@@ -14,3 +14,11 @@ type ErrUnknownChar struct {
func (e ErrUnknownChar) Error() string {
return "unknown character: " + string(e.Char)
}
+
+type ErrUnknownEscapeSequence struct {
+ Char rune
+}
+
+func (e ErrUnknownEscapeSequence) Error() string {
+ return "unknown escape sequence: \\" + string(e.Char)
+}
diff --git a/pkg/lang/scanner/scanner.go b/pkg/lang/scanner/scanner.go
index 35c30cd..eb7da89 100644
--- a/pkg/lang/scanner/scanner.go
+++ b/pkg/lang/scanner/scanner.go
@@ -178,6 +178,24 @@ func (s *Scanner) scanString() (token.Token, error) {
break
}
+ if c == '\\' {
+ sequence, eof, err := s.src.Next()
+ if err != nil {
+ return token.Token{}, err
+ }
+
+ if eof {
+ return token.Token{}, ErrUnclosedString
+ }
+
+ escaped, err := escapedChar(sequence)
+ if err != nil {
+ return token.Token{}, err
+ }
+
+ c = escaped
+ }
+
buf.WriteRune(c)
}
@@ -322,3 +340,20 @@ func (s *Scanner) skipWhitespace() (bool, source.Loc, error) {
return hadNewline, firstNewline, nil
}
+
+func escapedChar(c rune) (rune, error) {
+ switch c {
+ case 'n':
+ return '\n', nil
+ case 'r':
+ return '\r', nil
+ case 't':
+ return '\t', nil
+ case '\\':
+ return '\\', nil
+ case '"':
+ return '"', nil
+ }
+
+ return c, ErrUnknownEscapeSequence{Char: c}
+}