checker: fix checker enum infix error

pull/4326/head
Daniel Däschle 2020-04-10 14:44:01 +02:00 committed by GitHub
parent adb379dd63
commit 42b3b19af4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 21 deletions

View File

@ -500,9 +500,10 @@ mut:
}
pub struct EnumField {
name string
pos token.Position
exprs []Expr
name string
pos token.Position
expr Expr
has_expr bool
}
pub struct EnumDecl {

View File

@ -562,12 +562,12 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
pub fn (c mut Checker) enum_decl(decl ast.EnumDecl) {
for field in decl.fields {
for expr in field.exprs {
match expr {
if field.has_expr {
match field.expr {
ast.IntegerLiteral {}
ast.PrefixExpr {}
else {
mut pos := expr_pos(expr)
pos := expr_pos(field.expr)
if pos.pos == 0 {
pos = field.pos
}
@ -1064,7 +1064,18 @@ fn expr_pos(node ast.Expr) token.Position {
ast.IfExpr { return it.pos }
// ast.IfGuardExpr { }
ast.IndexExpr { return it.pos }
ast.InfixExpr { return it.pos }
ast.InfixExpr {
left_pos := expr_pos(it.left)
right_pos := expr_pos(it.right)
if left_pos.pos == 0 || right_pos.pos == 0 {
return it.pos
}
return token.Position{
line_nr: it.pos.line_nr
pos: left_pos.pos
len: right_pos.pos - left_pos.pos + right_pos.len
}
}
ast.IntegerLiteral { return it.pos }
ast.MapInit { return it.pos }
ast.MatchExpr { return it.pos }

View File

@ -2,5 +2,12 @@ vlib/v/checker/tests/inout/enum_err.v:2:13: error: default value for enum has to
1| enum Color {
2| green = 'green',
~~~~~~~
3| blue,
4| }
3| yellow = 1+1,
4| blue,
vlib/v/checker/tests/inout/enum_err.v:3:14: error: default value for enum has to be an integer
1| enum Color {
2| green = 'green',
3| yellow = 1+1,
~~~
4| blue,
5| }

View File

@ -1,4 +1,5 @@
enum Color {
green = 'green',
yellow = 1+1,
blue,
}

View File

@ -210,11 +210,9 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.writeln('enum $name {')
for field in it.fields {
f.write('\t$field.name')
if field.exprs.len > 0 {
if field.has_expr {
f.write(' = ')
for expr in field.exprs {
f.expr(expr)
}
f.expr(field.expr)
f.writeln(',')
} else {
f.writeln('')

View File

@ -367,12 +367,10 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.typedefs.writeln('typedef enum {')
for field in it.fields {
g.typedefs.write('\t${enum_name}_$field.name')
if field.exprs.len > 0 {
if field.has_expr {
g.typedefs.write(' = ')
}
for expr in field.exprs {
pos := g.out.len
g.expr(expr)
g.expr(field.expr)
expr_str := g.out.after(pos)
g.out.go_back(expr_str.len)
g.typedefs.write('$expr_str')

View File

@ -843,13 +843,14 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
// will fudge left shift as it makes it right assoc
// `arr << 'a'` | `arr << 'a' + 'b'`
tok := p.tok
pos := tok.position()
p.next()
right := p.expr(precedence - 1)
node = ast.InfixExpr{
left: node
right: right
op: tok.kind
pos: tok.position()
pos:pos
}
} else if p.tok.kind.is_infix() {
node = p.infix_expr(node)
@ -1876,13 +1877,15 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
pos := p.tok.position()
val := p.check_name()
vals << val
mut exprs := []ast.Expr
mut expr := ast.Expr{}
mut has_expr := false
// p.warn('enum val $val')
if p.tok.kind == .assign {
p.next()
exprs << p.expr(0)
expr = p.expr(0)
has_expr = true
}
fields << ast.EnumField{val, pos, exprs}
fields << ast.EnumField{val, pos, expr, has_expr}
// Allow commas after enum, helpful for
// enum Color {
// r,g,b