From d07953b0f0d6823274931a3fba278bc610caccb3 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Tue, 31 Dec 2019 01:06:56 +1100 Subject: [PATCH] v: fix postfix unary `++` `--` operators & some cleanup --- vlib/v/gen/cgen.v | 2 +- vlib/v/gen/tests/1.c | 1 + vlib/v/gen/tests/1.vv | 1 + vlib/v/parser/parser.v | 45 +++++++++++++++++++++++------------------- vlib/v/token/token.v | 34 +++++++++++++++++++++---------- 5 files changed, 52 insertions(+), 31 deletions(-) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 0de87a4407..4569881157 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -111,7 +111,7 @@ fn (g mut Gen) expr(node ast.Expr) { } ast.UnaryExpr { g.expr(it.left) - g.write(' $it.op ') + g.write(it.op.str()) } ast.StringLiteral { g.write('tos3("$it.val")') diff --git a/vlib/v/gen/tests/1.c b/vlib/v/gen/tests/1.c index 2d3020b2b4..f2f9a0d061 100644 --- a/vlib/v/gen/tests/1.c +++ b/vlib/v/gen/tests/1.c @@ -1,4 +1,5 @@ int main() { int a = 10; +a++; return 0; } diff --git a/vlib/v/gen/tests/1.vv b/vlib/v/gen/tests/1.vv index 2b684716cb..29ae4d536b 100644 --- a/vlib/v/gen/tests/1.vv +++ b/vlib/v/gen/tests/1.vv @@ -1,3 +1,4 @@ fn main() { a := 10 + a++ } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 1f3b38087c..8e6317fe02 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -28,8 +28,7 @@ pub fn parse_stmt(text string, table &table.Table) ast.Stmt { scanner: s table: table } - p.next() - p.next() + p.read_first_token() return p.stmt() } @@ -304,13 +303,10 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { p.check(.rpar) } else { - p.next() if p.tok.is_unary() { expr,_ := p.expr(token.highest_prec) node = ast.UnaryExpr{ - // left: p.expr(token.highest_prec) left: expr - op: p.tok.kind } } else { @@ -323,7 +319,7 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { prev_tok := p.tok p.next() mut t2 := types.Type{} - // left denotation (infix) + // left denotation (infix / postfix) if prev_tok.is_right_assoc() { mut expr := ast.Expr{} expr,t2 = p.expr(prev_tok.precedence() - 1) @@ -334,24 +330,33 @@ pub fn (p mut Parser) expr(rbp int) (ast.Expr,types.Type) { } // println(t2.name + 'OOO') if !types.check(&typ, &t2) { + println('tok: $prev_tok.str()') p.error('cannot convert `$t2.name` to `$typ.name`') } } else if prev_tok.is_left_assoc() { - mut expr := ast.Expr{} - expr,t2 = p.expr(prev_tok.precedence()) - op := prev_tok.kind - if op in [.gt, .lt, .ge, .le] { - typ = types.bool_type - } - else { - typ = t2 - } - // println(t2.name + '222') - node = ast.BinaryExpr{ - left: node - op: prev_tok.kind - right: expr + // postfix (`++` | `--`) + if prev_tok.kind in [.inc, .dec] { + node = ast.UnaryExpr{ + left: node + op: prev_tok.kind + } + } else { + mut expr := ast.Expr{} + expr,t2 = p.expr(prev_tok.precedence()) + op := prev_tok.kind + if prev_tok.is_relational() { + typ = types.bool_type + } + else { + typ = t2 + } + // println(t2.name + '222') + node = ast.BinaryExpr{ + left: node + op: prev_tok.kind + right: expr + } } } } diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 440b12ddc2..db39a2dea1 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -306,30 +306,34 @@ pub fn (t Token) str() string { // Representation of highest and lowest precedence pub const ( lowest_prec = 0 - highest_prec = 7 + highest_prec = 8 ) // Precedence returns a tokens precedence if defined, otherwise lowest_prec pub fn (tok Token) precedence() int { match tok.kind { + // `++` | `--` + .inc, .dec { + return 7 + } // `*` | `/` | `%` | `<<` | `>>` | `&` .mul, .div, .left_shift, .righ_shift, .amp { - return 7 + return 6 } // `+` | `-` | `|` | `^` .plus, .minus, .pipe, .xor { - return 6 + return 5 } // `==` | `!=` | `<` | `<=` | `>` | `>=` .eq, .ne, .lt, .le, .gt, .ge { - return 5 + return 4 } // `&&` .and { - return 4 + return 3 } // `||` .logical_or { - return 3 + return 2 } // /.plus_assign { // /return 2 @@ -358,10 +362,14 @@ pub fn (tok Token) is_unary() bool { pub fn (tok Token) is_left_assoc() bool { return tok.kind in [ // .number, + // `++` | `--` + .inc, .dec, // `*` | `/` | `%` .mul, .div, .mod, - // `^` | `||` | `&` < > <= >= - .xor, .logical_or, .and, .gt, .lt, .le, .ge, + // `^` | `||` | `&` + .xor, .logical_or, .and, + // `<` | `<=` | `>` | `>=` + .lt, .le, .gt, .ge, // `,` .comma] } @@ -369,8 +377,8 @@ pub fn (tok Token) is_left_assoc() bool { // is_right_assoc returns true if the token is right associative pub fn (tok Token) is_right_assoc() bool { return tok.kind in [ - // `+` | `-` | `!` | `++` | `--` - .plus, .minus, .not, .inc, .dec, + // `+` | `-` | `!` + .plus, .minus, .not, // `=` | `+=` | `-=` | `*=` | `/=` .assign, .plus_assign, .minus_assign, .mult_assign, .div_assign, // `%=` | `>>=` | `<<=` @@ -378,3 +386,9 @@ pub fn (tok Token) is_right_assoc() bool { // `&=` | `^=` | `|=` .and_assign, .xor_assign, .or_assign] } + +pub fn (tok Token) is_relational() bool { + return tok.kind in [ + // `<` | `<=` | `>` | `>=` + .lt, .le, .gt, .ge] +}