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

eval: support assignment operators like +=, make for a in 0..10 { more robust

This commit is contained in:
Delyan Angelov 2022-07-07 15:13:22 +03:00
parent 15ce15d41b
commit de77114593
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
5 changed files with 57 additions and 2 deletions

View File

@ -6,6 +6,20 @@ import v.util
import math import math
import strconv import strconv
fn (o Object) as_i64() !i64 {
match o {
i64 {
return o
}
Int {
return o.val
}
else {
return error('can not cast object to i64')
}
}
}
pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object { pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
match expr { match expr {
ast.CallExpr { ast.CallExpr {

View File

@ -1,6 +1,7 @@
module eval module eval
import v.ast import v.ast
import v.token
pub fn (mut e Eval) stmts(stmts []ast.Stmt) { pub fn (mut e Eval) stmts(stmts []ast.Stmt) {
e.open_scope() e.open_scope()
@ -40,6 +41,16 @@ pub fn (mut e Eval) stmt(stmt ast.Stmt) {
e.set(left, rights[i], false, stmt.left_types[i]) e.set(left, rights[i], false, stmt.left_types[i])
} }
} }
.plus_assign, .minus_assign, .mult_assign, .div_assign, .xor_assign, .mod_assign,
.or_assign, .and_assign, .right_shift_assign, .unsigned_right_shift_assign,
.left_shift_assign {
infix_op := token.assign_op_to_infix_op(stmt.op)
for i, left in stmt.left {
res := e.infix_expr(e.expr(left, stmt.left_types[i]), rights[i],
infix_op, stmt.left_types[i])
e.set(left, res, false, stmt.left_types[i])
}
}
else { else {
e.error('unknown assign statment: $stmt.op') e.error('unknown assign statment: $stmt.op')
} }
@ -64,8 +75,15 @@ pub fn (mut e Eval) stmt(stmt ast.Stmt) {
if !underscore { if !underscore {
e.set(ast.Ident{ name: stmt.val_var, scope: 0 }, Int{-1, 32}, true, stmt.val_type) e.set(ast.Ident{ name: stmt.val_var, scope: 0 }, Int{-1, 32}, true, stmt.val_type)
} }
for i in (e.expr(stmt.cond, ast.int_type_idx) as Int).val .. (e.expr(stmt.high, fstart := e.expr(stmt.cond, ast.int_type_idx).as_i64() or {
ast.int_type_idx) as Int).val { e.error('invalid integer for start of range')
0
}
fend := e.expr(stmt.high, ast.int_type_idx).as_i64() or {
e.error('invalid integer for end of range')
0
}
for i in fstart .. fend {
if !underscore { if !underscore {
e.set(ast.Ident{ name: stmt.val_var, scope: 0 }, Int{i, 32}, false, e.set(ast.Ident{ name: stmt.val_var, scope: 0 }, Int{i, 32}, false,
stmt.val_type) stmt.val_type)

View File

@ -0,0 +1 @@
45

View File

@ -0,0 +1,5 @@
mut sum := 0
for a in 0..10 {
sum += a
}
println(sum)

View File

@ -743,3 +743,20 @@ pub fn kind_from_string(s string) ?Kind {
else { error('unknown') } else { error('unknown') }
} }
} }
pub fn assign_op_to_infix_op(op Kind) Kind {
return match op {
.plus_assign { .plus }
.minus_assign { .minus }
.mult_assign { .mul }
.div_assign { .div }
.xor_assign { .xor }
.mod_assign { .mod }
.or_assign { .pipe }
.and_assign { .amp }
.right_shift_assign { .right_shift }
.unsigned_right_shift_assign { .unsigned_right_shift }
.left_shift_assign { .left_shift }
else { ._end_ }
}
}