parser: parse `-1` and `-13.3` as number literals (#8321)
parent
997f56a3dc
commit
815104e5d0
|
@ -2445,26 +2445,15 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
|||
if is_decl {
|
||||
left_type = c.table.mktyp(right_type)
|
||||
if left_type == table.int_type {
|
||||
mut expr := right
|
||||
mut negative := false
|
||||
if right is ast.PrefixExpr {
|
||||
expr = right.right
|
||||
if right.op == .minus {
|
||||
negative = true
|
||||
}
|
||||
}
|
||||
if mut expr is ast.IntegerLiteral {
|
||||
mut is_large := false
|
||||
if expr.val.len > 8 {
|
||||
val := expr.val.i64()
|
||||
if (!negative && val > checker.int_max)
|
||||
|| (negative && -val < checker.int_min) {
|
||||
is_large = true
|
||||
}
|
||||
if right is ast.IntegerLiteral {
|
||||
mut is_large := right.val.len > 13
|
||||
if !is_large && right.val.len > 8 {
|
||||
val := right.val.i64()
|
||||
is_large = val > checker.int_max || val < checker.int_min
|
||||
}
|
||||
if is_large {
|
||||
c.error('overflow in implicit type `int`, use explicit type casting instead',
|
||||
expr.pos)
|
||||
right.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4886,12 +4875,9 @@ fn (mut c Checker) check_index(typ_sym &table.TypeSymbol, index ast.Expr, index_
|
|||
}
|
||||
c.error('$type_str', pos)
|
||||
}
|
||||
if index is ast.PrefixExpr {
|
||||
if index.op == .minus && index.right is ast.IntegerLiteral {
|
||||
val := (index.right as ast.IntegerLiteral).val
|
||||
if val.int() > 0 {
|
||||
c.error('invalid index `-$val` (index must be non-negative)', index.pos)
|
||||
}
|
||||
if index is ast.IntegerLiteral {
|
||||
if index.val.starts_with('-') {
|
||||
c.error('invalid index `$index.val` (index must be non-negative)', index.pos)
|
||||
}
|
||||
}
|
||||
if index_type.has_flag(.optional) {
|
||||
|
|
|
@ -16,7 +16,7 @@ vlib/v/checker/tests/index_expr.vv:7:8: error: invalid index `-1` (index must be
|
|||
5 | a := [2]
|
||||
6 | _ = a[a]
|
||||
7 | _ = a[-1]
|
||||
| ^
|
||||
| ~~
|
||||
8 | }
|
||||
9 |
|
||||
vlib/v/checker/tests/index_expr.vv:12:7: error: type `int` does not support indexing
|
||||
|
@ -51,19 +51,19 @@ vlib/v/checker/tests/index_expr.vv:18:8: error: invalid index `-1` (index must b
|
|||
16 | _ = a[a..]
|
||||
17 | _ = a[..a]
|
||||
18 | _ = a[-1..]
|
||||
| ^
|
||||
| ~~
|
||||
19 | _ = a[..-1]
|
||||
20 | _ = a[-1..-2]
|
||||
vlib/v/checker/tests/index_expr.vv:19:10: error: invalid index `-1` (index must be non-negative)
|
||||
17 | _ = a[..a]
|
||||
18 | _ = a[-1..]
|
||||
19 | _ = a[..-1]
|
||||
| ^
|
||||
| ~~
|
||||
20 | _ = a[-1..-2]
|
||||
21 | }
|
||||
vlib/v/checker/tests/index_expr.vv:20:8: error: invalid index `-1` (index must be non-negative)
|
||||
18 | _ = a[-1..]
|
||||
19 | _ = a[..-1]
|
||||
20 | _ = a[-1..-2]
|
||||
| ^
|
||||
| ~~
|
||||
21 | }
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
vlib/v/checker/tests/overflow_int_err.vv:4:8: error: overflow in implicit type `int`, use explicit type casting instead
|
||||
vlib/v/checker/tests/overflow_int_err.vv:4:7: error: overflow in implicit type `int`, use explicit type casting instead
|
||||
2 | a := -2147483648
|
||||
3 | b := 2147483647
|
||||
4 | c := -2147483649
|
||||
| ~~~~~~~~~~
|
||||
| ~~~~~~~~~~~
|
||||
5 | d := 2147483648
|
||||
6 | println(a)
|
||||
vlib/v/checker/tests/overflow_int_err.vv:5:7: error: overflow in implicit type `int`, use explicit type casting instead
|
||||
|
|
|
@ -2612,10 +2612,13 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
}
|
||||
g.write('(${cast_label}(')
|
||||
g.expr(node.expr)
|
||||
if node.expr is ast.IntegerLiteral
|
||||
&& node.typ in [table.u64_type, table.u32_type, table.u16_type] {
|
||||
if node.expr is ast.IntegerLiteral {
|
||||
if node.typ in [table.u64_type, table.u32_type, table.u16_type] {
|
||||
if !node.expr.val.starts_with('-') {
|
||||
g.write('U')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.write('))')
|
||||
}
|
||||
}
|
||||
|
@ -2691,6 +2694,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
if node.val.starts_with('0o') {
|
||||
g.write('0')
|
||||
g.write(node.val[2..])
|
||||
} else if node.val.starts_with('-0o') {
|
||||
g.write('-0')
|
||||
g.write(node.val[3..])
|
||||
} else {
|
||||
g.write(node.val) // .int().str())
|
||||
}
|
||||
|
|
|
@ -1726,17 +1726,23 @@ fn (mut p Parser) string_expr() ast.Expr {
|
|||
}
|
||||
|
||||
fn (mut p Parser) parse_number_literal() ast.Expr {
|
||||
mut pos := p.tok.position()
|
||||
is_neg := p.tok.kind == .minus
|
||||
if is_neg {
|
||||
p.next()
|
||||
pos = pos.extend(p.tok.position())
|
||||
}
|
||||
lit := p.tok.lit
|
||||
pos := p.tok.position()
|
||||
full_lit := if is_neg { '-' + lit } else { lit }
|
||||
mut node := ast.Expr{}
|
||||
if lit.index_any('.eE') >= 0 && lit[..2] !in ['0x', '0X', '0o', '0O', '0b', '0B'] {
|
||||
node = ast.FloatLiteral{
|
||||
val: lit
|
||||
val: full_lit
|
||||
pos: pos
|
||||
}
|
||||
} else {
|
||||
node = ast.IntegerLiteral{
|
||||
val: lit
|
||||
val: full_lit
|
||||
pos: pos
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,10 +74,17 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
|
|||
}
|
||||
p.next()
|
||||
}
|
||||
.minus, .amp, .mul, .not, .bit_not, .arrow {
|
||||
.amp, .mul, .not, .bit_not, .arrow {
|
||||
// -1, -a, !x, &x, ~x, <-a
|
||||
node = p.prefix_expr()
|
||||
}
|
||||
.minus {
|
||||
if p.peek_tok.kind == .number {
|
||||
node = p.parse_number_literal()
|
||||
} else {
|
||||
node = p.prefix_expr()
|
||||
}
|
||||
}
|
||||
.key_true, .key_false {
|
||||
node = ast.BoolLiteral{
|
||||
val: p.tok.kind == .key_true
|
||||
|
|
|
@ -175,6 +175,48 @@ fn test_parse_expr() {
|
|||
}
|
||||
}
|
||||
|
||||
fn test_num_literals() {
|
||||
inputs := [
|
||||
'a := -1',
|
||||
'b := -12.e17'
|
||||
'c := -12.'
|
||||
'd := -a'
|
||||
]
|
||||
table := table.new_table()
|
||||
mut scope := &ast.Scope{
|
||||
start_pos: 0
|
||||
parent: 0
|
||||
}
|
||||
mut rhs_types := []string{}
|
||||
for input in inputs {
|
||||
stmt := parser.parse_stmt(input, table, scope)
|
||||
r := (stmt as ast.AssignStmt).right
|
||||
match r[0] {
|
||||
ast.IntegerLiteral {
|
||||
rhs_types << 'int literal'
|
||||
}
|
||||
ast.FloatLiteral {
|
||||
rhs_types << 'float literal'
|
||||
}
|
||||
ast.PrefixExpr {
|
||||
rhs_types << 'prefix expression'
|
||||
}
|
||||
else {
|
||||
rhs_types << 'something else'
|
||||
}
|
||||
}
|
||||
}
|
||||
mut rhs_type := rhs_types[0]
|
||||
assert rhs_type == 'int literal'
|
||||
rhs_type = rhs_types[1]
|
||||
assert rhs_type == 'float literal'
|
||||
rhs_type = rhs_types[2]
|
||||
assert rhs_type == 'float literal'
|
||||
rhs_type = rhs_types[3]
|
||||
assert rhs_type == 'prefix expression'
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
table := &table.Table{}
|
||||
for s in text_expr {
|
||||
|
|
|
@ -94,7 +94,7 @@ fn test_propagation() {
|
|||
17
|
||||
}
|
||||
n := get_arr_el_direct(0) or {
|
||||
int(-73)
|
||||
-73
|
||||
}
|
||||
assert testvar1 == -34
|
||||
assert testvar2 == 99
|
||||
|
|
Loading…
Reference in New Issue