fix CharLit parser bug

This commit is contained in:
Daniel Kang 2019-01-10 02:45:20 -08:00
parent 52922512e5
commit 8e5657d67c
4 changed files with 60 additions and 7 deletions

View file

@ -285,13 +285,7 @@ func (p *Parser) parseOperand() ast.Expr {
return x
case token.Char:
x := &ast.CharLit{
Value: rune(p.tokenLit[1]),
ValuePos: p.pos,
Literal: p.tokenLit,
}
p.next()
return x
return p.parseCharLit()
case token.String:
v, _ := strconv.Unquote(p.tokenLit)
@ -355,6 +349,28 @@ func (p *Parser) parseOperand() ast.Expr {
return &ast.BadExpr{From: pos, To: p.pos}
}
func (p *Parser) parseCharLit() ast.Expr {
if n := len(p.tokenLit); n >= 3 {
if code, _, _, err := strconv.UnquoteChar(p.tokenLit[1:n-1], '\''); err == nil {
x := &ast.CharLit{
Value: rune(code),
ValuePos: p.pos,
Literal: p.tokenLit,
}
p.next()
return x
}
}
pos := p.pos
p.error(pos, "illegal char literal")
p.next()
return &ast.BadExpr{
From: pos,
To: p.pos,
}
}
func (p *Parser) parseFuncLit() ast.Expr {
if p.trace {
defer un(trace(p, "FuncLit"))

View file

@ -0,0 +1,24 @@
package parser_test
import (
"testing"
"github.com/d5/tengo/ast"
)
func TestChar(t *testing.T) {
expect(t, `'A'`, func(p pfn) []ast.Stmt {
return stmts(
exprStmt(
charLit('A', 1)))
})
expect(t, `'九'`, func(p pfn) []ast.Stmt {
return stmts(
exprStmt(
charLit('九', 1)))
})
expectError(t, `''`)
expectError(t, `'AB'`)
expectError(t, `'A九'`)
}

View file

@ -207,6 +207,10 @@ func stringLit(value string, pos scanner.Pos) *ast.StringLit {
return &ast.StringLit{Value: value, ValuePos: pos}
}
func charLit(value rune, pos scanner.Pos) *ast.CharLit {
return &ast.CharLit{Value: value, ValuePos: pos, Literal: fmt.Sprintf("'%c'", value)}
}
func boolLit(value bool, pos scanner.Pos) *ast.BoolLit {
return &ast.BoolLit{Value: value, ValuePos: pos}
}

9
vm/vm_char_test.go Normal file
View file

@ -0,0 +1,9 @@
package vm_test
import "testing"
func TestChar(t *testing.T) {
expect(t, `out = 'a'`, 'a')
expect(t, `out = '九'`, rune(20061))
expect(t, `out = 'Æ'`, rune(198))
}