1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

pratt: fix precedence

This commit is contained in:
Alexander Medvednikov 2020-02-20 12:16:18 +01:00
parent 0074976636
commit c099cd8bf6
4 changed files with 40 additions and 21 deletions

View File

@ -88,6 +88,7 @@ pub fn (c mut Checker) check_struct_init(struct_init ast.StructInit) table.Type
} }
pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type { pub fn (c mut Checker) infix_expr(infix_expr ast.InfixExpr) table.Type {
// println('checker: infix expr(op $infix_expr.op.str())')
left_type := c.expr(infix_expr.left) left_type := c.expr(infix_expr.left)
right_type := c.expr(infix_expr.right) right_type := c.expr(infix_expr.right)
if !c.table.check(right_type, left_type) { if !c.table.check(right_type, left_type) {

View File

@ -127,4 +127,8 @@ void matches() {
int path_sep = 10; int path_sep = 10;
void end() { void end() {
int i = 2;
int key = 10;
bool x = i != -1 && key == 10;
int e = 2 + 3 * 4;
} }

View File

@ -134,6 +134,10 @@ const (
) )
fn end() { fn end() {
i := 2
key := 10
x := i != -1 && key == 10 // key == keys[i]
e := 2 + 3 * 4
//mut a := [1,2,3] //mut a := [1,2,3]
//(a << 4) + 2 //(a << 4) + 2

View File

@ -9,7 +9,7 @@ pub:
lit string // literal representation of the token lit string // literal representation of the token
line_nr int // the line number in the source where the token occured line_nr int // the line number in the source where the token occured
// name_idx int // name table index for O(1) lookup // name_idx int // name table index for O(1) lookup
pos int // the position of the token in scanner text pos int // the position of the token in scanner text
} }
pub enum Kind { pub enum Kind {
@ -304,21 +304,26 @@ pub fn (t Token) str() string {
} }
// Representation of highest and lowest precedence // Representation of highest and lowest precedence
/*
pub const ( pub const (
lowest_prec = 0 lowest_prec = 0
highest_prec = 8 highest_prec = 8
) )
*/
pub enum Precedence { pub enum Precedence {
lowest lowest
cond // OR or AND cond // OR or AND
in_as
assign // = assign // =
eq // == or != eq // == or !=
less_greater // > or < // less_greater // > or <
sum // + or - sum // + or -
product // * or / product // * or /
mod // % // mod // %
prefix // -X or !X prefix // -X or !X
postfix
call // func(X) or foo.method(X) call // func(X) or foo.method(X)
index // array[index], map[key] index // array[index], map[key]
} }
@ -329,10 +334,10 @@ pub fn build_precedences() []Precedence {
p[Kind.assign] = .assign p[Kind.assign] = .assign
p[Kind.eq] = .eq p[Kind.eq] = .eq
p[Kind.ne] = .eq p[Kind.ne] = .eq
p[Kind.lt] = .less_greater p[Kind.lt] = .eq // less_greater
p[Kind.gt] = .less_greater p[Kind.gt] = .eq // less_greater
p[Kind.le] = .less_greater p[Kind.le] = .eq // less_greater
p[Kind.ge] = .less_greater p[Kind.ge] = .eq // less_greater
p[Kind.plus] = .sum p[Kind.plus] = .sum
p[Kind.plus_assign] = .sum p[Kind.plus_assign] = .sum
p[Kind.minus] = .sum p[Kind.minus] = .sum
@ -341,7 +346,7 @@ pub fn build_precedences() []Precedence {
p[Kind.div_assign] = .product p[Kind.div_assign] = .product
p[Kind.mul] = .product p[Kind.mul] = .product
p[Kind.mult_assign] = .product p[Kind.mult_assign] = .product
p[Kind.mod] = .mod p[Kind.mod] = .product // mod
p[Kind.and] = .cond p[Kind.and] = .cond
p[Kind.logical_or] = .cond p[Kind.logical_or] = .cond
p[Kind.lpar] = .call p[Kind.lpar] = .call
@ -361,46 +366,51 @@ pub fn (tok Token) precedence() int {
// return int(precedences[int(tok)]) // return int(precedences[int(tok)])
match tok.kind { match tok.kind {
.lsbr { .lsbr {
return 9 return int(Precedence.index)
} }
.dot { .dot {
return 8 return int(Precedence.call)
} }
// `++` | `--` // `++` | `--`
.inc, .dec { .inc, .dec {
return int(Precedence.postfix)
// return 0 // return 0
return 7 // return 7
} }
// `*` | `/` | `%` | `<<` | `>>` | `&` // `*` | `/` | `%` | `<<` | `>>` | `&`
.mul, .div, .mod, .left_shift, .right_shift, .amp { .mul, .div, .mod, .left_shift, .right_shift, .amp {
return 6 return int(Precedence.product)
} }
// `+` | `-` | `|` | `^` // `+` | `-` | `|` | `^`
.plus, .minus, .pipe, .xor { .plus, .minus, .pipe, .xor {
return 5 return int(Precedence.sum)
} }
// `==` | `!=` | `<` | `<=` | `>` | `>=` // `==` | `!=` | `<` | `<=` | `>` | `>=`
.eq, .ne, .lt, .le, .gt, .ge { .eq, .ne, .lt, .le, .gt, .ge {
return 4 return int(Precedence.eq)
} }
// `&&` // `&&`
.and { // .and {
return 3 // return 3
} // }
// `||` // `||`
.logical_or, .assign, .plus_assign, .minus_assign, .div_assign, .mod_assign, .or_assign, // .logical_or,
.assign, .plus_assign, .minus_assign, .div_assign, .mod_assign, .or_assign,
// //
.left_shift_assign, .righ_shift_assign, .mult_assign { .left_shift_assign, .righ_shift_assign, .mult_assign {
return 2 return int(Precedence.assign)
} }
.key_in, .key_as { .key_in, .key_as {
return 1 return int(Precedence.in_as)
}
.logical_or, .and {
return int(Precedence.cond)
} }
// /.plus_assign { // /.plus_assign {
// /return 2 // /return 2
// /} // /}
else { else {
return lowest_prec return int(Precedence.lowest)
} }
} }
} }