nitc :: AMethPropdef :: intern_call
Returns the result for a function, null
for a procedure, or error_instance
if the method is unknown.
# Interprets a intern or a shortcut extern method.
# Returns the result for a function, `null` for a procedure, or `error_instance` if the method is unknown.
private fun intern_call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
do
var pname = mpropdef.mproperty.name
var cname = mpropdef.mclassdef.mclass.name
if pname == "call" and v.routine_types.has(cname) then
var routine = args.shift
assert routine isa CallrefInstance
# Swap the receiver position with the original recv of the call form.
args.unshift routine.recv
var res = v.callsite(routine.callsite, args)
# recover the old args state
args.shift
args.unshift routine
return res
end
if pname == "output" then
var recv = args.first
recv.val.output
return null
else if pname == "object_id" then
var recv = args.first
if recv isa PrimitiveInstance[Object] then
return v.int_instance(recv.val.object_id)
else
return v.int_instance(recv.object_id)
end
else if pname == "output_class_name" then
var recv = args.first
print recv.mtype
return null
else if pname == "native_class_name" then
var recv = args.first
var txt = recv.mtype.to_s
return v.c_string_instance(txt)
else if pname == "==" then
# == is correctly redefined for instances
return v.bool_instance(args[0] == args[1])
else if pname == "!=" then
return v.bool_instance(args[0] != args[1])
else if pname == "is_same_type" then
return v.bool_instance(args[0].mtype == args[1].mtype)
else if pname == "is_same_instance" then
return v.bool_instance(args[0].eq_is(args[1]))
else if pname == "class_inheritance_metamodel_json" then
return v.c_string_instance(v.mainmodule.flatten_mclass_hierarchy.to_thin_json)
else if pname == "exit" then
exit(args[1].to_i)
abort
else if pname == "buffer_mode_full" then
return v.int_instance(sys.buffer_mode_full)
else if pname == "buffer_mode_line" then
return v.int_instance(sys.buffer_mode_line)
else if pname == "buffer_mode_none" then
return v.int_instance(sys.buffer_mode_none)
else if pname == "sys" then
return v.mainobj
else if cname == "Int" then
var recvval = args[0].to_i
if pname == "unary -" then
return v.int_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.int_instance(recvval + args[1].to_i)
else if pname == "-" then
return v.int_instance(recvval - args[1].to_i)
else if pname == "*" then
return v.int_instance(recvval * args[1].to_i)
else if pname == "%" then
return v.int_instance(recvval % args[1].to_i)
else if pname == "/" then
return v.int_instance(recvval / args[1].to_i)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_i)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_i)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_i)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_i)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_i)
else if pname == "&" then
return v.int_instance(recvval & args[1].to_i)
else if pname == "|" then
return v.int_instance(recvval | args[1].to_i)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "<<" then
return v.int_instance(recvval << args[1].to_i)
else if pname == ">>" then
return v.int_instance(recvval >> args[1].to_i)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
end
else if cname == "Byte" then
var recvval = args[0].to_b
if pname == "unary -" then
return v.byte_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.byte_instance(recvval + args[1].to_b)
else if pname == "-" then
return v.byte_instance(recvval - args[1].to_b)
else if pname == "*" then
return v.byte_instance(recvval * args[1].to_b)
else if pname == "%" then
return v.byte_instance(recvval % args[1].to_b)
else if pname == "/" then
return v.byte_instance(recvval / args[1].to_b)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_b)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_b)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_b)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_b)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_b)
else if pname == "&" then
return v.byte_instance(recvval & args[1].to_b)
else if pname == "|" then
return v.byte_instance(recvval | args[1].to_b)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "<<" then
return v.byte_instance(recvval << args[1].to_i)
else if pname == ">>" then
return v.byte_instance(recvval >> args[1].to_i)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
else if pname == "byte_to_s_len" then
return v.int_instance(recvval.to_s.length)
end
else if cname == "Char" then
var recv = args[0].val.as(Char)
if pname == "successor" then
return v.char_instance(recv.successor(args[1].to_i))
else if pname == "predecessor" then
return v.char_instance(recv.predecessor(args[1].to_i))
else if pname == "<" then
return v.bool_instance(recv < args[1].val.as(Char))
else if pname == ">" then
return v.bool_instance(recv > args[1].val.as(Char))
else if pname == "<=" then
return v.bool_instance(recv <= args[1].val.as(Char))
else if pname == ">=" then
return v.bool_instance(recv >= args[1].val.as(Char))
else if pname == "<=>" then
return v.int_instance(recv <=> args[1].val.as(Char))
end
else if cname == "Float" then
var recv = args[0].to_f
if pname == "unary -" then
return v.float_instance(-recv)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.float_instance(recv + args[1].to_f)
else if pname == "-" then
return v.float_instance(recv - args[1].to_f)
else if pname == "*" then
return v.float_instance(recv * args[1].to_f)
else if pname == "/" then
return v.float_instance(recv / args[1].to_f)
else if pname == "<" then
return v.bool_instance(recv < args[1].to_f)
else if pname == ">" then
return v.bool_instance(recv > args[1].to_f)
else if pname == "<=" then
return v.bool_instance(recv <= args[1].to_f)
else if pname == ">=" then
return v.bool_instance(recv >= args[1].to_f)
else if pname == "to_i" then
return v.int_instance(recv.to_i)
else if pname == "to_b" then
return v.byte_instance(recv.to_b)
else if pname == "to_i8" then
return v.int8_instance(recv.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recv.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recv.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recv.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recv.to_u32)
else if pname == "cos" then
return v.float_instance(args[0].to_f.cos)
else if pname == "sin" then
return v.float_instance(args[0].to_f.sin)
else if pname == "tan" then
return v.float_instance(args[0].to_f.tan)
else if pname == "acos" then
return v.float_instance(args[0].to_f.acos)
else if pname == "asin" then
return v.float_instance(args[0].to_f.asin)
else if pname == "atan" then
return v.float_instance(args[0].to_f.atan)
else if pname == "sqrt" then
return v.float_instance(args[0].to_f.sqrt)
else if pname == "exp" then
return v.float_instance(args[0].to_f.exp)
else if pname == "log" then
return v.float_instance(args[0].to_f.log)
else if pname == "pow" then
return v.float_instance(args[0].to_f.pow(args[1].to_f))
else if pname == "abs" then
return v.float_instance(args[0].to_f.abs)
else if pname == "hypot_with" then
return v.float_instance(args[0].to_f.hypot_with(args[1].to_f))
else if pname == "is_nan" then
return v.bool_instance(args[0].to_f.is_nan)
else if pname == "is_inf_extern" then
return v.bool_instance(args[0].to_f.is_inf != 0)
else if pname == "round" then
return v.float_instance(args[0].to_f.round)
end
else if cname == "CString" then
if pname == "new" then
return v.c_string_instance_len(args[1].to_i)
end
var recvval = args.first.val.as(CString)
if pname == "[]" then
var arg1 = args[1].to_i
return v.int_instance(recvval[arg1])
else if pname == "[]=" then
var arg1 = args[1].to_i
recvval[arg1] = args[2].val.as(Int)
return null
else if pname == "copy_to" then
# sig= copy_to(dest: CString, length: Int, from: Int, to: Int)
var destval = args[1].val.as(CString)
var lenval = args[2].to_i
var fromval = args[3].to_i
var toval = args[4].to_i
recvval.copy_to(destval, lenval, fromval, toval)
return null
else if pname == "atoi" then
return v.int_instance(recvval.atoi)
else if pname == "fast_cstring" then
return v.c_string_instance_fast_cstr(args[0].val.as(CString), args[1].to_i)
else if pname == "fetch_4_chars" then
return v.uint32_instance(args[0].val.as(CString).fetch_4_chars(args[1].to_i))
else if pname == "fetch_4_hchars" then
return v.uint32_instance(args[0].val.as(CString).fetch_4_hchars(args[1].to_i))
else if pname == "utf8_length" then
return v.int_instance(args[0].val.as(CString).utf8_length(args[1].to_i, args[2].to_i))
end
else if cname == "NativeArray" then
if pname == "new" then
var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
var instance = new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
v.init_instance_primitive(instance)
return instance
end
var recvval = args.first.val.as(Array[Instance])
if pname == "[]" then
return recvval[args[1].to_i]
else if pname == "[]=" then
recvval[args[1].to_i] = args[2]
return null
else if pname == "length" then
return v.int_instance(recvval.length)
else if pname == "copy_to" then
recvval.copy_to(0, args[2].to_i, args[1].val.as(Array[Instance]), 0)
return null
end
else if cname == "Int8" then
var recvval = args[0].to_i8
if pname == "unary -" then
return v.int8_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.int8_instance(recvval + args[1].to_i8)
else if pname == "-" then
return v.int8_instance(recvval - args[1].to_i8)
else if pname == "*" then
return v.int8_instance(recvval * args[1].to_i8)
else if pname == "%" then
return v.int8_instance(recvval % args[1].to_i8)
else if pname == "/" then
return v.int8_instance(recvval / args[1].to_i8)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_i8)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_i8)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_i8)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_i8)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_i8)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
else if pname == "<<" then
return v.int8_instance(recvval << (args[1].to_i))
else if pname == ">>" then
return v.int8_instance(recvval >> (args[1].to_i))
else if pname == "&" then
return v.int8_instance(recvval & args[1].to_i8)
else if pname == "|" then
return v.int8_instance(recvval | args[1].to_i8)
else if pname == "^" then
return v.int8_instance(recvval ^ args[1].to_i8)
else if pname == "unary ~" then
return v.int8_instance(~recvval)
end
else if cname == "Int16" then
var recvval = args[0].to_i16
if pname == "unary -" then
return v.int16_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.int16_instance(recvval + args[1].to_i16)
else if pname == "-" then
return v.int16_instance(recvval - args[1].to_i16)
else if pname == "*" then
return v.int16_instance(recvval * args[1].to_i16)
else if pname == "%" then
return v.int16_instance(recvval % args[1].to_i16)
else if pname == "/" then
return v.int16_instance(recvval / args[1].to_i16)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_i16)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_i16)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_i16)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_i16)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_i16)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
else if pname == "<<" then
return v.int16_instance(recvval << (args[1].to_i))
else if pname == ">>" then
return v.int16_instance(recvval >> (args[1].to_i))
else if pname == "&" then
return v.int16_instance(recvval & args[1].to_i16)
else if pname == "|" then
return v.int16_instance(recvval | args[1].to_i16)
else if pname == "^" then
return v.int16_instance(recvval ^ args[1].to_i16)
else if pname == "unary ~" then
return v.int16_instance(~recvval)
end
else if cname == "UInt16" then
var recvval = args[0].to_u16
if pname == "unary -" then
return v.uint16_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.uint16_instance(recvval + args[1].to_u16)
else if pname == "-" then
return v.uint16_instance(recvval - args[1].to_u16)
else if pname == "*" then
return v.uint16_instance(recvval * args[1].to_u16)
else if pname == "%" then
return v.uint16_instance(recvval % args[1].to_u16)
else if pname == "/" then
return v.uint16_instance(recvval / args[1].to_u16)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_u16)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_u16)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_u16)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_u16)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_u16)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
else if pname == "<<" then
return v.uint16_instance(recvval << (args[1].to_i))
else if pname == ">>" then
return v.uint16_instance(recvval >> (args[1].to_i))
else if pname == "&" then
return v.uint16_instance(recvval & args[1].to_u16)
else if pname == "|" then
return v.uint16_instance(recvval | args[1].to_u16)
else if pname == "^" then
return v.uint16_instance(recvval ^ args[1].to_u16)
else if pname == "unary ~" then
return v.uint16_instance(~recvval)
end
else if cname == "Int32" then
var recvval = args[0].to_i32
if pname == "unary -" then
return v.int32_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.int32_instance(recvval + args[1].to_i32)
else if pname == "-" then
return v.int32_instance(recvval - args[1].to_i32)
else if pname == "*" then
return v.int32_instance(recvval * args[1].to_i32)
else if pname == "%" then
return v.int32_instance(recvval % args[1].to_i32)
else if pname == "/" then
return v.int32_instance(recvval / args[1].to_i32)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_i32)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_i32)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_i32)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_i32)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_i32)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_u32" then
return v.uint32_instance(recvval.to_u32)
else if pname == "<<" then
return v.int32_instance(recvval << (args[1].to_i))
else if pname == ">>" then
return v.int32_instance(recvval >> (args[1].to_i))
else if pname == "&" then
return v.int32_instance(recvval & args[1].to_i32)
else if pname == "|" then
return v.int32_instance(recvval | args[1].to_i32)
else if pname == "^" then
return v.int32_instance(recvval ^ args[1].to_i32)
else if pname == "unary ~" then
return v.int32_instance(~recvval)
end
else if cname == "UInt32" then
var recvval = args[0].to_u32
if pname == "unary -" then
return v.uint32_instance(-recvval)
else if pname == "unary +" then
return args[0]
else if pname == "+" then
return v.uint32_instance(recvval + args[1].to_u32)
else if pname == "-" then
return v.uint32_instance(recvval - args[1].to_u32)
else if pname == "*" then
return v.uint32_instance(recvval * args[1].to_u32)
else if pname == "%" then
return v.uint32_instance(recvval % args[1].to_u32)
else if pname == "/" then
return v.uint32_instance(recvval / args[1].to_u32)
else if pname == "<" then
return v.bool_instance(recvval < args[1].to_u32)
else if pname == ">" then
return v.bool_instance(recvval > args[1].to_u32)
else if pname == "<=" then
return v.bool_instance(recvval <= args[1].to_u32)
else if pname == ">=" then
return v.bool_instance(recvval >= args[1].to_u32)
else if pname == "<=>" then
return v.int_instance(recvval <=> args[1].to_u32)
else if pname == "to_f" then
return v.float_instance(recvval.to_f)
else if pname == "to_i" then
return v.int_instance(recvval.to_i)
else if pname == "to_b" then
return v.byte_instance(recvval.to_b)
else if pname == "to_i8" then
return v.int8_instance(recvval.to_i8)
else if pname == "to_i16" then
return v.int16_instance(recvval.to_i16)
else if pname == "to_u16" then
return v.uint16_instance(recvval.to_u16)
else if pname == "to_i32" then
return v.int32_instance(recvval.to_i32)
else if pname == "<<" then
return v.uint32_instance(recvval << (args[1].to_i))
else if pname == ">>" then
return v.uint32_instance(recvval >> (args[1].to_i))
else if pname == "&" then
return v.uint32_instance(recvval & args[1].to_u32)
else if pname == "|" then
return v.uint32_instance(recvval | args[1].to_u32)
else if pname == "^" then
return v.uint32_instance(recvval ^ args[1].to_u32)
else if pname == "unary ~" then
return v.uint32_instance(~recvval)
end
else if pname == "native_argc" then
return v.int_instance(v.arguments.length)
else if pname == "native_argv" then
var txt = v.arguments[args[1].to_i]
return v.c_string_instance(txt)
else if pname == "lexer_goto" then
return v.int_instance(lexer_goto(args[1].to_i, args[2].to_i))
else if pname == "lexer_accept" then
return v.int_instance(lexer_accept(args[1].to_i))
else if pname == "parser_goto" then
return v.int_instance(parser_goto(args[1].to_i, args[2].to_i))
else if pname == "parser_action" then
return v.int_instance(parser_action(args[1].to_i, args[2].to_i))
end
return v.error_instance
end
src/interpreter/naive_interpreter.nit:978,2--1552,4