From 42b3b19af4c0538277ab1cbae37145bba3070329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Fri, 10 Apr 2020 14:44:01 +0200 Subject: [PATCH] checker: fix checker enum infix error --- vlib/v/ast/ast.v | 7 ++++--- vlib/v/checker/checker.v | 19 +++++++++++++++---- vlib/v/checker/tests/inout/enum_err.out | 11 +++++++++-- vlib/v/checker/tests/inout/enum_err.vv | 1 + vlib/v/fmt/fmt.v | 6 ++---- vlib/v/gen/cgen.v | 6 ++---- vlib/v/parser/parser.v | 11 +++++++---- 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 5b13a31fd9..908c7f86ac 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 09f6b32b52..b4c8097b35 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 } diff --git a/vlib/v/checker/tests/inout/enum_err.out b/vlib/v/checker/tests/inout/enum_err.out index 99ded8c240..2e3b665fe4 100644 --- a/vlib/v/checker/tests/inout/enum_err.out +++ b/vlib/v/checker/tests/inout/enum_err.out @@ -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| } \ No newline at end of file + 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| } \ No newline at end of file diff --git a/vlib/v/checker/tests/inout/enum_err.vv b/vlib/v/checker/tests/inout/enum_err.vv index ec6b14fc29..35d7a7df3f 100644 --- a/vlib/v/checker/tests/inout/enum_err.vv +++ b/vlib/v/checker/tests/inout/enum_err.vv @@ -1,4 +1,5 @@ enum Color { green = 'green', + yellow = 1+1, blue, } diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v index 6ba25283d8..269c2ba168 100644 --- a/vlib/v/fmt/fmt.v +++ b/vlib/v/fmt/fmt.v @@ -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('') diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index bab53411bc..a036c6ad10 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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') diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index b26846b658..322681bf78 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -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