diff --git a/checker/checker_test.go b/checker/checker_test.go index 417ae178e..d00c74320 100644 --- a/checker/checker_test.go +++ b/checker/checker_test.go @@ -477,6 +477,11 @@ MapOfAny[0] cannot use int to get an element from map[string]interface {} (1:10) | MapOfAny[0] | .........^ + +1 /* one */ + "2" +invalid operation: + (mismatched types int and string) (1:13) + | 1 /* one */ + "2" + | ............^ ` func TestCheck_error(t *testing.T) { diff --git a/expr_test.go b/expr_test.go index 599e57fe9..8dd39cde4 100644 --- a/expr_test.go +++ b/expr_test.go @@ -1032,6 +1032,10 @@ func TestExpr(t *testing.T) { `lowercase`, "lowercase", }, + { + `1 /* one*/ + 2 /* two */`, + 3, + }, } for _, tt := range tests { diff --git a/parser/lexer/lexer_test.go b/parser/lexer/lexer_test.go index 6939eb683..d5f2cc2c7 100644 --- a/parser/lexer/lexer_test.go +++ b/parser/lexer/lexer_test.go @@ -163,6 +163,23 @@ var lexTests = []lexTest{ {Kind: EOF}, }, }, + { + `foo // comment + bar // comment`, + []Token{ + {Kind: Identifier, Value: "foo"}, + {Kind: Identifier, Value: "bar"}, + {Kind: EOF}, + }, + }, + { + `foo /* comment */ bar`, + []Token{ + {Kind: Identifier, Value: "foo"}, + {Kind: Identifier, Value: "bar"}, + {Kind: EOF}, + }, + }, } func compareTokens(i1, i2 []Token) bool { diff --git a/parser/lexer/state.go b/parser/lexer/state.go index 779cc89fc..cc322e037 100644 --- a/parser/lexer/state.go +++ b/parser/lexer/state.go @@ -26,11 +26,13 @@ func root(l *lexer) stateFn { return number case r == '?': return questionMark + case r == '/': + return slash case strings.ContainsRune("([{", r): l.emit(Bracket) case strings.ContainsRune(")]}", r): l.emit(Bracket) - case strings.ContainsRune("#,?:%+-/^", r): // single rune operator + case strings.ContainsRune("#,?:%+-^", r): // single rune operator l.emit(Operator) case strings.ContainsRune("&|!=*<>", r): // possible double rune operator l.accept("&|=*") @@ -158,3 +160,39 @@ func questionMark(l *lexer) stateFn { l.emit(Operator) return root } + +func slash(l *lexer) stateFn { + if l.accept("/") { + return singleLineComment + } + if l.accept("*") { + return multiLineComment + } + l.emit(Operator) + return root +} + +func singleLineComment(l *lexer) stateFn { + for { + r := l.next() + if r == eof || r == '\n' { + break + } + } + l.ignore() + return root +} + +func multiLineComment(l *lexer) stateFn { + for { + r := l.next() + if r == eof { + return l.error("unclosed comment") + } + if r == '*' && l.accept("/") { + break + } + } + l.ignore() + return root +}