fix CharLit parser bug
This commit is contained in:
parent
52922512e5
commit
8e5657d67c
4 changed files with 60 additions and 7 deletions
|
@ -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"))
|
||||
|
|
24
parser/parser_char_test.go
Normal file
24
parser/parser_char_test.go
Normal 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九'`)
|
||||
}
|
|
@ -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
9
vm/vm_char_test.go
Normal 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))
|
||||
}
|
Loading…
Reference in a new issue