Skip to content

Commit 8eb73b7

Browse files
authored
🧵 lexer: Fix empty string lit in middle of line (#118)
Fix empty string lit in middle of line. As we advance at the beginning of reading string and then again when peekRune is `"` we overshoot for empty strings `""`. Fix this be doing the outer advance only at the end of the iteration. Pull-Request: #118
1 parent 4a70c1d commit 8eb73b7

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

pkg/lexer/lexer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ func (l *Lexer) readString() (string, error) {
193193
pos := l.pos
194194
backslashCnt := 0
195195
for {
196-
l.advance()
197196
if l.cur == '\\' {
198197
backslashCnt++
199198
} else {
@@ -207,6 +206,7 @@ func (l *Lexer) readString() (string, error) {
207206
if pr == 0 || pr == '\n' {
208207
break // error case
209208
}
209+
l.advance()
210210
}
211211
s := string(l.input[pos : l.pos+1])
212212
r, err := strconv.Unquote(s)

pkg/lexer/lexer_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,37 @@ func TestString(t *testing.T) {
353353
})
354354
}
355355
}
356+
357+
func TestStringLit(t *testing.T) {
358+
in := `fn "" 0`
359+
wantTokens := []*Token{
360+
{Type: IDENT, Literal: "fn", Offset: 0, Line: 1, Col: 1},
361+
{Type: WS, Literal: "", Offset: 2, Line: 1, Col: 3},
362+
{Type: STRING_LIT, Literal: "", Offset: 3, Line: 1, Col: 4},
363+
{Type: WS, Literal: "", Offset: 5, Line: 1, Col: 6},
364+
{Type: NUM_LIT, Literal: "0", Offset: 6, Line: 1, Col: 7},
365+
}
366+
l := New(in)
367+
for _, want := range wantTokens {
368+
got := l.Next()
369+
assert.Equal(t, want, got)
370+
}
371+
}
372+
373+
func TestStringLitErr(t *testing.T) {
374+
in := `fn "unterminated
375+
"hello"`
376+
wantTokens := []*Token{
377+
{Type: IDENT, Literal: "fn", Offset: 0, Line: 1, Col: 1},
378+
{Type: WS, Literal: "", Offset: 2, Line: 1, Col: 3},
379+
{Type: ILLEGAL, Literal: "invalid string", Offset: 3, Line: 1, Col: 4},
380+
{Type: NL, Literal: "", Offset: 16, Line: 1, Col: 17},
381+
{Type: STRING_LIT, Literal: "hello", Offset: 17, Line: 2, Col: 1},
382+
{Type: EOF, Offset: 24, Line: 2, Col: 8},
383+
}
384+
l := New(in)
385+
for _, want := range wantTokens {
386+
got := l.Next()
387+
assert.Equal(t, want, got)
388+
}
389+
}

pkg/parser/parser_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,18 @@ func TestCalledBuiltinFuncs(t *testing.T) {
11901190
assert.Equal(t, want, got)
11911191
}
11921192

1193+
func TestEmptyStringLitArg(t *testing.T) {
1194+
input := `
1195+
fn "" 0
1196+
1197+
func fn s:string n:num
1198+
print s n
1199+
end`
1200+
parser := newParser(input, testBuiltins())
1201+
parser.Parse()
1202+
assertNoParseError(t, parser, input)
1203+
}
1204+
11931205
func TestDemo(t *testing.T) {
11941206
input := `
11951207
move 10 10

0 commit comments

Comments
 (0)