mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
122 lines
2.8 KiB
V
122 lines
2.8 KiB
V
module eval
|
|
|
|
import v.ast
|
|
import v.token
|
|
|
|
pub fn (mut e Eval) stmts(stmts []ast.Stmt) {
|
|
if e.executed_return_stmt {
|
|
return
|
|
}
|
|
e.open_scope()
|
|
for stmt in stmts {
|
|
if !e.executed_return_stmt {
|
|
e.stmt(stmt)
|
|
}
|
|
if stmt is ast.Return {
|
|
e.executed_return_stmt = true
|
|
break
|
|
}
|
|
}
|
|
e.close_scope()
|
|
}
|
|
|
|
pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
|
match stmt {
|
|
ast.ExprStmt {
|
|
ret := e.expr(stmt.expr, stmt.typ)
|
|
if e.returning {
|
|
e.return_values << ret
|
|
}
|
|
}
|
|
ast.AssignStmt {
|
|
// if stmt.left.len != 1 {
|
|
// e.error('multiple values assignments are not supported')
|
|
// }
|
|
mut rights := []Object{}
|
|
for i, right in stmt.right {
|
|
rights << e.expr(right, stmt.right_types[i])
|
|
}
|
|
if rights[0] is []Object { // needs to be unpacked
|
|
e.error('multiple assignment from function is not supported')
|
|
}
|
|
match stmt.op {
|
|
.decl_assign {
|
|
for i, left in stmt.left {
|
|
e.set(left, rights[i], true, stmt.left_types[i])
|
|
}
|
|
}
|
|
.assign {
|
|
for i, left in stmt.left {
|
|
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 {
|
|
e.error('unknown assign statement: ${stmt.op}')
|
|
}
|
|
}
|
|
}
|
|
ast.Return {
|
|
old_returning := e.returning
|
|
e.returning = true
|
|
e.return_values = []
|
|
for i, expr in stmt.exprs {
|
|
e.return_values << e.expr(expr, stmt.types[i])
|
|
}
|
|
e.returning = old_returning
|
|
}
|
|
ast.ForInStmt {
|
|
if !stmt.is_range {
|
|
e.error('only range for in statements are supported')
|
|
}
|
|
if stmt.key_var != '' {
|
|
e.error('keys are not supported in for in statements')
|
|
}
|
|
e.open_scope()
|
|
underscore := stmt.val_var == '_'
|
|
if !underscore {
|
|
e.set(ast.Ident{ name: stmt.val_var }, Int{-1, 32}, true, stmt.val_type)
|
|
}
|
|
fstart := e.expr(stmt.cond, ast.int_type_idx).as_i64() or {
|
|
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 {
|
|
e.set(ast.Ident{ name: stmt.val_var }, Int{i, 32}, false, stmt.val_type)
|
|
}
|
|
e.stmts(stmt.stmts)
|
|
}
|
|
e.close_scope()
|
|
}
|
|
ast.ForStmt {
|
|
for {
|
|
should_break := e.expr(stmt.cond, ast.bool_type_idx)
|
|
if !(should_break as bool) {
|
|
break
|
|
}
|
|
e.stmts(stmt.stmts)
|
|
}
|
|
}
|
|
ast.Block {
|
|
e.stmts(stmt.stmts)
|
|
}
|
|
else {
|
|
e.error('unhandled statement ${stmt.type_name()}')
|
|
}
|
|
}
|
|
}
|