mirror of
https://github.com/vlang/v.git
synced 2025-09-08 14:51:53 -04:00
eval: fix if-else; add infix op; fix func calls (#24972)
This commit is contained in:
parent
38beb23c6a
commit
e5eed5c5a4
@ -153,10 +153,14 @@ pub fn (mut e Eval) run_func(func ast.FnDecl, _args ...Object) {
|
|||||||
scope_idx: e.scope_idx
|
scope_idx: e.scope_idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
prev_executed_return_stmt := e.executed_return_stmt
|
||||||
e.executed_return_stmt = false
|
e.executed_return_stmt = false
|
||||||
|
e.returning = false
|
||||||
|
e.return_values = []
|
||||||
e.stmts(func.stmts)
|
e.stmts(func.stmts)
|
||||||
e.returning = false
|
e.returning = false
|
||||||
e.close_scope()
|
e.close_scope()
|
||||||
|
e.executed_return_stmt = prev_executed_return_stmt
|
||||||
e.scope_idx = old_scope
|
e.scope_idx = old_scope
|
||||||
e.local_vars = e.local_vars_stack.pop()
|
e.local_vars = e.local_vars_stack.pop()
|
||||||
}
|
}
|
||||||
@ -183,9 +187,12 @@ pub fn (mut e Eval) register_symbols(mut files []&ast.File) {
|
|||||||
for _, field in fields {
|
for _, field in fields {
|
||||||
e.returning = true
|
e.returning = true
|
||||||
e.return_values = []
|
e.return_values = []
|
||||||
|
prev_executed_return_stmt := e.executed_return_stmt
|
||||||
|
e.executed_return_stmt = false
|
||||||
e.mods[mod][field.name.all_after_last('.')] = e.expr(field.expr, field.typ)
|
e.mods[mod][field.name.all_after_last('.')] = e.expr(field.expr, field.typ)
|
||||||
e.returning = false
|
e.returning = false
|
||||||
e.return_values = []
|
e.return_values = []
|
||||||
|
e.executed_return_stmt = prev_executed_return_stmt
|
||||||
if mod == 'os' && field.name.all_after_last('.') == 'args' {
|
if mod == 'os' && field.name.all_after_last('.') == 'args' {
|
||||||
mut res := Array{}
|
mut res := Array{}
|
||||||
res.val << e.pref.out_name.all_after_last('/')
|
res.val << e.pref.out_name.all_after_last('/')
|
||||||
|
@ -111,10 +111,10 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
|||||||
|
|
||||||
if func is ast.FnDecl {
|
if func is ast.FnDecl {
|
||||||
e.run_func(func as ast.FnDecl, ...args)
|
e.run_func(func as ast.FnDecl, ...args)
|
||||||
if e.return_values.len == 1 {
|
return if e.return_values.len == 1 {
|
||||||
return e.return_values[0]
|
e.return_values[0]
|
||||||
} else {
|
} else {
|
||||||
return e.return_values
|
e.return_values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.error('unknown function: ${mod}.${name} at line ${expr.pos.line_nr}')
|
e.error('unknown function: ${mod}.${name} at line ${expr.pos.line_nr}')
|
||||||
@ -145,15 +145,16 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
|||||||
}
|
}
|
||||||
ast.IfExpr {
|
ast.IfExpr {
|
||||||
for i, branch in expr.branches {
|
for i, branch in expr.branches {
|
||||||
|
is_else_branch := expr.has_else && expr.branches.len == i + 1
|
||||||
result := if expr.is_comptime {
|
result := if expr.is_comptime {
|
||||||
e.comptime_cond(branch.cond)
|
e.comptime_cond(branch.cond)
|
||||||
} else if expr.branches.len != i + 1 {
|
} else if !is_else_branch {
|
||||||
e.expr(branch.cond, ast.bool_type_idx) as bool
|
e.expr(branch.cond, ast.bool_type_idx) as bool
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
if result || expr.branches.len == i + 1 {
|
if result || is_else_branch {
|
||||||
stmts := branch.stmts.filter(it is ast.ExprStmt)
|
stmts := branch.stmts.filter(it is ast.ExprStmt)
|
||||||
if stmts.len > 0 {
|
if stmts.len > 0 {
|
||||||
// a := if x == 1 { 100 } else { 200 }, we need to get expr result
|
// a := if x == 1 { 100 } else { 200 }, we need to get expr result
|
||||||
@ -501,6 +502,38 @@ pub fn (mut e Eval) expr(expr ast.Expr, expecting ast.Type) Object {
|
|||||||
.not {
|
.not {
|
||||||
return !(e.expr(expr.right, ast.bool_type) as bool)
|
return !(e.expr(expr.right, ast.bool_type) as bool)
|
||||||
}
|
}
|
||||||
|
.bit_not {
|
||||||
|
x := e.expr(expr.right, expr.right_type)
|
||||||
|
match x {
|
||||||
|
Uint {
|
||||||
|
return Uint{
|
||||||
|
val: ~x.val
|
||||||
|
size: x.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Int {
|
||||||
|
return Int{
|
||||||
|
val: ~x.val
|
||||||
|
size: x.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool {
|
||||||
|
return !(x as bool)
|
||||||
|
}
|
||||||
|
i64 {
|
||||||
|
return ~(x as i64)
|
||||||
|
}
|
||||||
|
rune {
|
||||||
|
return ~(x as rune)
|
||||||
|
}
|
||||||
|
u8 {
|
||||||
|
return ~(x as u8)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('operator `~` can only be used with integer types: ${e.table.sym(expr.right_type).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.amp {
|
.amp {
|
||||||
x := e.expr(expr.right, expr.right_type)
|
x := e.expr(expr.right, expr.right_type)
|
||||||
return Ptr{
|
return Ptr{
|
||||||
|
@ -372,6 +372,387 @@ fn (e &Eval) infix_expr(left Object, right Object, op token.Kind, expecting ast.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.amp {
|
||||||
|
match left {
|
||||||
|
Int {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to &: Int and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) & i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) & u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) & i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to &: Uint and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) & i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) & u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) & i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) & i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) & u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) & i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to &: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to &: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.pipe {
|
||||||
|
match left {
|
||||||
|
Int {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to |: Int and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) | i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) | u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) | i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to |: Uint and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) | i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) | u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) | i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) | i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) | u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) | i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to |: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to |: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.xor {
|
||||||
|
match left {
|
||||||
|
Int {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to ^: Int and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) ^ i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) ^ u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) ^ i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to ^: Uint and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) ^ i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) ^ u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) ^ i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char, u8, i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) ^ i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) ^ u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) ^ i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to &: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to ^: ${left} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.plus {
|
.plus {
|
||||||
match left {
|
match left {
|
||||||
Int {
|
Int {
|
||||||
@ -2040,6 +2421,133 @@ fn (e &Eval) infix_expr(left Object, right Object, op token.Kind, expecting ast.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.mod {
|
||||||
|
match left {
|
||||||
|
Int {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to %: Int and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left.val) % i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left.val) % u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left.val) % i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to %: Uint and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i64 {
|
||||||
|
match right {
|
||||||
|
Int {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Uint {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) % i64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) % u64(right.val), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) % i64(right.val))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i64 {
|
||||||
|
if expecting in ast.signed_integer_type_idxs {
|
||||||
|
return Int{i64(left) % i64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting in ast.unsigned_integer_type_idxs {
|
||||||
|
return Uint{u64(left) % u64(right), i8(e.type_to_size(expecting))}
|
||||||
|
} else if expecting == ast.int_literal_type_idx {
|
||||||
|
return i64(i64(left) % i64(right))
|
||||||
|
} else {
|
||||||
|
e.error('unknown infix expectation: ${e.table.sym(expecting).str()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to %: int literal and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.error('invalid operands to %: ${left.type_name()} and ${right.type_name()}')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.right_shift {
|
.right_shift {
|
||||||
match left {
|
match left {
|
||||||
Int {
|
Int {
|
||||||
|
@ -72,6 +72,10 @@ pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
|||||||
for i, expr in stmt.exprs {
|
for i, expr in stmt.exprs {
|
||||||
e.return_values << e.expr(expr, stmt.types[i])
|
e.return_values << e.expr(expr, stmt.types[i])
|
||||||
}
|
}
|
||||||
|
if e.return_values.len > stmt.exprs.len {
|
||||||
|
// keep only results
|
||||||
|
e.return_values.drop(e.return_values.len - stmt.exprs.len)
|
||||||
|
}
|
||||||
e.returning = old_returning
|
e.returning = old_returning
|
||||||
}
|
}
|
||||||
ast.ForInStmt {
|
ast.ForInStmt {
|
||||||
|
26
vlib/v/eval/tests/func_call_test.v
Normal file
26
vlib/v/eval/tests/func_call_test.v
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import v.eval
|
||||||
|
|
||||||
|
fn test_func_return() {
|
||||||
|
mut e := eval.create()
|
||||||
|
|
||||||
|
ret := e.run('
|
||||||
|
fn sub(a int) int {
|
||||||
|
if a > 105 {
|
||||||
|
return 101
|
||||||
|
}
|
||||||
|
return 5151
|
||||||
|
}
|
||||||
|
|
||||||
|
fn key(b int) int {
|
||||||
|
println(b)
|
||||||
|
if b > 100 {
|
||||||
|
return 3 + sub(sub(sub(b)))
|
||||||
|
}
|
||||||
|
return 7171
|
||||||
|
}
|
||||||
|
|
||||||
|
key(110)')!
|
||||||
|
|
||||||
|
dump(ret)
|
||||||
|
assert ret[0].int_val() == 104
|
||||||
|
}
|
@ -72,3 +72,30 @@ fn test_if_infix_return_early() {
|
|||||||
dump(ret)
|
dump(ret)
|
||||||
assert ret[0].int_val() == 107
|
assert ret[0].int_val() == 107
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_if_infix_op() {
|
||||||
|
mut e := eval.create()
|
||||||
|
|
||||||
|
ret := e.run('
|
||||||
|
fn display(a int, b int) int {
|
||||||
|
mut k := false
|
||||||
|
if !k {
|
||||||
|
k = !k
|
||||||
|
}
|
||||||
|
println(k)
|
||||||
|
mut data := u64(0xFFFF0000)
|
||||||
|
mut c := u8(0xFF)
|
||||||
|
if c & data == c {
|
||||||
|
return 3131
|
||||||
|
}
|
||||||
|
if ((data & 0xFFFF0000) | (0x3FFF ^ data)) == 0x66111 {
|
||||||
|
println(data)
|
||||||
|
return 6060
|
||||||
|
}
|
||||||
|
return 7171
|
||||||
|
}
|
||||||
|
display(200, 101)')!
|
||||||
|
|
||||||
|
dump(ret)
|
||||||
|
assert ret[0].int_val() == 7171
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user