mirror of
https://github.com/vlang/v.git
synced 2025-08-03 09:47:15 -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
|
||||
}
|
||||
}
|
||||
prev_executed_return_stmt := e.executed_return_stmt
|
||||
e.executed_return_stmt = false
|
||||
e.returning = false
|
||||
e.return_values = []
|
||||
e.stmts(func.stmts)
|
||||
e.returning = false
|
||||
e.close_scope()
|
||||
e.executed_return_stmt = prev_executed_return_stmt
|
||||
e.scope_idx = old_scope
|
||||
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 {
|
||||
e.returning = true
|
||||
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.returning = false
|
||||
e.return_values = []
|
||||
e.executed_return_stmt = prev_executed_return_stmt
|
||||
if mod == 'os' && field.name.all_after_last('.') == 'args' {
|
||||
mut res := Array{}
|
||||
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 {
|
||||
e.run_func(func as ast.FnDecl, ...args)
|
||||
if e.return_values.len == 1 {
|
||||
return e.return_values[0]
|
||||
return if e.return_values.len == 1 {
|
||||
e.return_values[0]
|
||||
} else {
|
||||
return e.return_values
|
||||
e.return_values
|
||||
}
|
||||
}
|
||||
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 {
|
||||
for i, branch in expr.branches {
|
||||
is_else_branch := expr.has_else && expr.branches.len == i + 1
|
||||
result := if expr.is_comptime {
|
||||
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
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
if result || expr.branches.len == i + 1 {
|
||||
if result || is_else_branch {
|
||||
stmts := branch.stmts.filter(it is ast.ExprStmt)
|
||||
if stmts.len > 0 {
|
||||
// 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 {
|
||||
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 {
|
||||
x := e.expr(expr.right, expr.right_type)
|
||||
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 {
|
||||
match left {
|
||||
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 {
|
||||
match left {
|
||||
Int {
|
||||
|
@ -72,6 +72,10 @@ pub fn (mut e Eval) stmt(stmt ast.Stmt) {
|
||||
for i, expr in stmt.exprs {
|
||||
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
|
||||
}
|
||||
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)
|
||||
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