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.

Property definitions

nitc :: naive_interpreter $ AMethPropdef :: intern_call
	# 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