Evaluate the node as a possible expression.

Return a possible value NOTE: Do not call this method directly, but use v.expr This method is here to be implemented by subclasses.

Property definitions

nitc :: naive_interpreter $ AExpr :: expr
	# Evaluate the node as a possible expression.
	# Return a possible value
	# NOTE: Do not call this method directly, but use `v.expr`
	# This method is here to be implemented by subclasses.
	protected fun expr(v: NaiveInterpreter): nullable Instance
	do
		fatal(v, "NOT YET IMPLEMENTED expr {class_name}")
		abort
	end
src/interpreter/naive_interpreter.nit:1670,2--1678,4

nitc :: naive_interpreter $ ABlockExpr :: expr
	redef fun expr(v)
	do
		var last = self.n_expr.last
		for e in self.n_expr do
			if e == last then break
			v.stmt(e)
			if v.is_escaping then return null
		end
		return last.expr(v)
	end
src/interpreter/naive_interpreter.nit:1691,2--1700,4

nitc :: naive_interpreter $ AVardeclExpr :: expr
	redef fun expr(v)
	do
		var ne = self.n_expr
		if ne != null then
			var i = v.expr(ne)
			if i == null then return null
			v.write_variable(self.variable.as(not null), i)
			return i
		end
		return null
	end
src/interpreter/naive_interpreter.nit:1712,2--1722,4

nitc :: naive_interpreter $ ASelfExpr :: expr
	redef fun expr(v)
	do
		return v.frame.arguments.first
	end
src/interpreter/naive_interpreter.nit:1756,2--1759,4

nitc :: naive_interpreter $ AIfExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		if cond.is_true then
			return v.expr(self.n_then.as(not null))
		else
			return v.expr(self.n_else.as(not null))
		end
	end
src/interpreter/naive_interpreter.nit:1794,2--1803,4

nitc :: naive_interpreter $ AIfexprExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		if cond.is_true then
			return v.expr(self.n_then)
		else
			return v.expr(self.n_else)
		end
	end
src/interpreter/naive_interpreter.nit:1818,2--1827,4

nitc :: naive_interpreter $ AIntegerExpr :: expr
	redef fun expr(v)
	do
		if value isa Int then return v.int_instance(value.as(Int))
		if value isa Byte then return v.byte_instance(value.as(Byte))
		if value isa Int8 then return v.int8_instance(value.as(Int8))
		if value isa Int16 then return v.int16_instance(value.as(Int16))
		if value isa UInt16 then return v.uint16_instance(value.as(UInt16))
		if value isa Int32 then return v.int32_instance(value.as(Int32))
		if value isa UInt32 then return v.uint32_instance(value.as(UInt32))
		return null
	end
src/interpreter/naive_interpreter.nit:2033,2--2043,4

nitc :: naive_interpreter $ AFloatExpr :: expr
	redef fun expr(v)
	do
		return v.float_instance(self.value.as(not null))
	end
src/interpreter/naive_interpreter.nit:2047,2--2050,4

nitc :: naive_interpreter $ AArrayExpr :: expr
	redef fun expr(v)
	do
		var val = new Array[Instance]
		var old_comprehension = v.frame.comprehension
		v.frame.comprehension = val
		for nexpr in self.n_exprs do
			if nexpr isa AForExpr then
				v.stmt(nexpr)
			else
				var i = v.expr(nexpr)
				if i == null then return null
				val.add(i)
			end
		end
		v.frame.comprehension = old_comprehension
		var mtype = v.unanchor_type(self.mtype.as(not null)).as(MClassType)
		var elttype = mtype.arguments.first
		return v.array_instance(val, elttype)
	end
src/interpreter/naive_interpreter.nit:2064,2--2082,4

nitc :: naive_interpreter $ ANullExpr :: expr
	redef fun expr(v)
	do
		return v.null_instance
	end
src/interpreter/naive_interpreter.nit:2215,2--2218,4

nitc :: naive_interpreter $ AParExpr :: expr
	redef fun expr(v)
	do
		return v.expr(self.n_expr)
	end
src/interpreter/naive_interpreter.nit:2258,2--2261,4

nitc :: naive_interpreter $ AOnceExpr :: expr
	redef fun expr(v)
	do
		if v.onces.has_key(self) then
			return v.onces[self]
		else
			var res = v.expr(self.n_expr)
			if res == null then return null
			v.onces[self] = res
			return res
		end
	end
src/interpreter/naive_interpreter.nit:2265,2--2275,4

nitc :: naive_interpreter $ ASendExpr :: expr
	redef fun expr(v)
	do
		var recv = v.expr(self.n_expr)
		if recv == null then return null

		# Safe call shortcut if recv is null
		if is_safe and recv.is_null then
			return recv
		end

		var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments)
		if args == null then return null
		var res = v.callsite(callsite, args)
		return res
	end
src/interpreter/naive_interpreter.nit:2279,2--2293,4

nitc :: naive_interpreter $ ASuperExpr :: expr
	redef fun expr(v)
	do
		var recv = v.frame.arguments.first

		var callsite = self.callsite
		if callsite != null then
			var args
			if self.n_args.n_exprs.is_empty then
				# Add automatic arguments for the super init call
				args = [recv]
				for i in [0..callsite.msignature.arity[ do
					args.add(v.frame.arguments[i+1])
				end
			else
				args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs)
				if args == null then return null
			end

			# Super init call
			var res = v.callsite(callsite, args)
			return res
		end

		# Standard call-next-method
		var mpropdef = self.mpropdef
		mpropdef = mpropdef.lookup_next_definition(v.mainmodule, recv.mtype)

		var args
		if self.n_args.n_exprs.is_empty then
			args = v.frame.arguments
		else
			args = v.varargize(mpropdef, signaturemap, recv, self.n_args.n_exprs)
			if args == null then return null
		end

		var res = v.call(mpropdef, args)
		return res
	end
src/interpreter/naive_interpreter.nit:2334,2--2371,4

nitc :: naive_interpreter $ ANewExpr :: expr
	redef fun expr(v)
	do
		var mtype = v.unanchor_type(self.recvtype.as(not null))
		var recv: Instance = new MutableInstance(mtype)
		v.init_instance(recv)
		var callsite = self.callsite
		if callsite == null then return recv

		var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.n_args.n_exprs)
		if args == null then return null
		var res2 = v.callsite(callsite, args)
		if res2 != null then
			#self.debug("got {res2} from {mproperty}. drop {recv}")
			return res2
		end
		return recv
	end
src/interpreter/naive_interpreter.nit:2375,2--2391,4

nitc :: naive_interpreter $ AVarargExpr :: expr
	redef fun expr(v)
	do
		return v.expr(self.n_expr)
	end
src/interpreter/naive_interpreter.nit:2446,2--2449,4

nitc :: naive_interpreter $ ASafeExpr :: expr
	redef fun expr(v)
	do
		return v.expr(self.n_expr)
	end
src/interpreter/naive_interpreter.nit:2453,2--2456,4

nitc :: naive_interpreter $ ANamedargExpr :: expr
	redef fun expr(v)
	do
		return v.expr(self.n_expr)
	end
src/interpreter/naive_interpreter.nit:2460,2--2463,4

nitc :: naive_interpreter $ AVarExpr :: expr
	redef fun expr(v)
	do
		return v.read_variable(self.variable.as(not null))
	end
src/interpreter/naive_interpreter.nit:1726,2--1729,4

nitc :: naive_interpreter $ AImplicitSelfExpr :: expr
	redef fun expr(v)
	do
		if not is_sys then return super
		return v.mainobj
	end
src/interpreter/naive_interpreter.nit:1763,2--1767,4

nitc :: naive_interpreter $ ANotExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		return v.bool_instance(not cond.is_true)
	end
src/interpreter/naive_interpreter.nit:2014,2--2019,4

nitc :: naive_interpreter $ ACharExpr :: expr
	redef fun expr(v)
	do
		if is_code_point then
			return v.int_instance(self.value.as(not null).code_point)
		end
		return v.char_instance(self.value.as(not null))
	end
src/interpreter/naive_interpreter.nit:2054,2--2060,4

nitc :: naive_interpreter $ ACrangeExpr :: expr
	redef fun expr(v)
	do
		var e1 = v.expr(self.n_expr)
		if e1 == null then return null
		var e2 = v.expr(self.n_expr2)
		if e2 == null then return null
		var mtype = v.unanchor_type(self.mtype.as(not null))
		var res = new MutableInstance(mtype)
		v.init_instance(res)
		v.callsite(init_callsite, [res, e1, e2])
		return res
	end
src/interpreter/naive_interpreter.nit:2171,2--2182,4

nitc :: naive_interpreter $ AOrangeExpr :: expr
	redef fun expr(v)
	do
		var e1 = v.expr(self.n_expr)
		if e1 == null then return null
		var e2 = v.expr(self.n_expr2)
		if e2 == null then return null
		var mtype = v.unanchor_type(self.mtype.as(not null))
		var res = new MutableInstance(mtype)
		v.init_instance(res)
		v.callsite(init_callsite, [res, e1, e2])
		return res
	end
src/interpreter/naive_interpreter.nit:2186,2--2197,4

nitc :: naive_interpreter $ ATrueExpr :: expr
	redef fun expr(v)
	do
		return v.bool_instance(true)
	end
src/interpreter/naive_interpreter.nit:2201,2--2204,4

nitc :: naive_interpreter $ AFalseExpr :: expr
	redef fun expr(v)
	do
		return v.bool_instance(false)
	end
src/interpreter/naive_interpreter.nit:2208,2--2211,4

nitc :: naive_interpreter $ AIsaExpr :: expr
	redef fun expr(v)
	do
		var i = v.expr(self.n_expr)
		if i == null then return null
		var mtype = v.unanchor_type(self.cast_type.as(not null))
		return v.bool_instance(v.is_subtype(i.mtype, mtype))
	end
src/interpreter/naive_interpreter.nit:2222,2--2228,4

nitc :: vm_optimizations $ AIsaExpr :: expr
	redef fun expr(v)
	do
		# TODO : a workaround for now
		if not v isa VirtualMachine then return super

		var recv = v.expr(self.n_expr)
		if recv == null then return null

		optimize(v, recv.mtype, self.cast_type.as(not null))
		var mtype = v.unanchor_type(self.cast_type.as(not null))

		# If this test can be optimized, directly call appropriate subtyping methods
		if status == 1 and recv.mtype isa MClassType then
			# Direct access
			return v.bool_instance(v.inter_is_subtype_sst(id, position, recv.mtype.as(MClassType).mclass.vtable.internal_vtable))
		else if status == 2 and recv.mtype isa MClassType then
			# Perfect hashing
			return v.bool_instance(v.inter_is_subtype_ph(id, recv.vtable.mask, recv.mtype.as(MClassType).mclass.vtable.internal_vtable))
		else
			# Use the slow path (default)
			return v.bool_instance(v.is_subtype(recv.mtype, mtype))
		end
	end
src/vm/vm_optimizations.nit:206,2--228,4

nitc :: naive_interpreter $ AAsCastExpr :: expr
	redef fun expr(v)
	do
		var i = v.expr(self.n_expr)
		if i == null then return null
		var mtype = self.mtype.as(not null)
		var amtype = v.unanchor_type(mtype)
		if not v.is_subtype(i.mtype, amtype) then
			fatal(v, "Cast failed. Expected `{amtype}`, got `{i.mtype}`")
		end
		return i
	end
src/interpreter/naive_interpreter.nit:2232,2--2242,4

nitc :: vm_optimizations $ AAsCastExpr :: expr
	redef fun expr(v)
	do
		# TODO : a workaround for now
		if not v isa VirtualMachine then return super

		var recv = v.expr(self.n_expr)
		if recv == null then return null

		optimize(v, recv.mtype, self.mtype.as(not null))

		var mtype = self.mtype.as(not null)
		var amtype = v.unanchor_type(mtype)

		var res: Bool
		if status == 1 and recv.mtype isa MClassType then
			# Direct access
			res = v.inter_is_subtype_sst(id, position, recv.mtype.as(MClassType).mclass.vtable.internal_vtable)
		else if status == 2 and recv.mtype isa MClassType then
			# Perfect hashing
			res = v.inter_is_subtype_ph(id, recv.vtable.mask, recv.mtype.as(MClassType).mclass.vtable.internal_vtable)
		else
			# Use the slow path (default)
			res = v.is_subtype(recv.mtype, amtype)
		end

		if not res then
			fatal(v, "Cast failed. Expected `{amtype}`, got `{recv.mtype}`")
		end
		return recv
	end
src/vm/vm_optimizations.nit:271,2--300,4

nitc :: naive_interpreter $ AAsNotnullExpr :: expr
	redef fun expr(v)
	do
		var i = v.expr(self.n_expr)
		if i == null then return null
		if i.is_null then
			fatal(v, "Cast failed")
		end
		return i
	end
src/interpreter/naive_interpreter.nit:2246,2--2254,4

nitc :: naive_interpreter $ AAttrExpr :: expr
	redef fun expr(v)
	do
		var recv = v.expr(self.n_expr)
		if recv == null then return null
		if recv.is_null then fatal(v, "Receiver is null")
		var mproperty = self.mproperty.as(not null)
		return v.read_attribute(mproperty, recv)
	end
src/interpreter/naive_interpreter.nit:2395,2--2402,4

nitc :: vm_optimizations $ AAttrExpr :: expr
	redef fun expr(v)
	do
		# TODO : a workaround for now
		if not v isa VirtualMachine then return super

		var recv = v.expr(self.n_expr)
		if recv == null then return null
		if recv.mtype isa MNullType then fatal(v, "Receiver is null")
		var mproperty = self.mproperty.as(not null)

		assert recv isa MutableInstance
		if status == 0 then optimize(mproperty, recv)

		var i: Instance
		if status == 1 then
			# SST
			i = v.read_attribute_sst(recv.internal_attributes, offset)
		else
			# PH
			i = v.read_attribute_ph(recv.internal_attributes, recv.vtable.internal_vtable, recv.vtable.mask, id, offset)
		end

		# If we get a `MInit` value, throw an error
		if i == v.initialization_value then
			v.fatal("Uninitialized attribute {mproperty.name}")
			abort
		end

		#TODO : we need recompilations here
		status = 0

		return i
	end
src/vm/vm_optimizations.nit:91,2--123,4

nitc :: naive_interpreter $ AIssetAttrExpr :: expr
	redef fun expr(v)
	do
		var recv = v.expr(self.n_expr)
		if recv == null then return null
		if recv.is_null then fatal(v, "Receiver is null")
		var mproperty = self.mproperty.as(not null)
		return v.bool_instance(v.isset_attribute(mproperty, recv))
	end
src/interpreter/naive_interpreter.nit:2435,2--2442,4

nitc :: naive_interpreter $ AVarAssignExpr :: expr
	redef fun expr(v)
	do
		var i = v.expr(self.n_value)
		if i == null then return null
		v.write_variable(self.variable.as(not null), i)
		return i
	end
src/interpreter/naive_interpreter.nit:1733,2--1739,4

nitc :: naive_interpreter $ AOrElseExpr :: expr
	redef fun expr(v)
	do
		var i = v.expr(self.n_expr)
		if i == null then return null
		if i != v.null_instance then return i
		return v.expr(self.n_expr2)
	end
src/interpreter/naive_interpreter.nit:2023,2--2029,4

nitc :: naive_interpreter $ AStringFormExpr :: expr
	redef fun expr(v) do return v.string_instance(value)
src/interpreter/naive_interpreter.nit:2123,2--53

nitc :: naive_interpreter $ ASuperstringExpr :: expr
	redef fun expr(v)
	do
		var array = new Array[Instance]
		for nexpr in n_exprs do
			var i = v.expr(nexpr)
			if i == null then return null
			array.add(i)
		end
		var i = v.array_instance(array, v.mainmodule.object_type)
		var res = v.send(v.force_get_primitive_method("plain_to_s", i.mtype), [i])
		assert res != null
		if is_re then res = make_re(v, res)
		return res
	end
src/interpreter/naive_interpreter.nit:2154,2--2167,4

nitc :: naive_interpreter $ ACallrefExpr :: expr
	redef fun expr(v)
	do
		var recv = v.expr(self.n_expr)
		if recv == null then return null
		var mtype = self.mtype
		assert mtype != null
		# In case we are in generic class where formal parameter can not
		# be resolved.
		var mtype2 = v.unanchor_type(mtype)
		var inst = new CallrefInstance(mtype2, recv, callsite.as(not null))
		return inst
	end
src/interpreter/naive_interpreter.nit:2297,2--2308,4

nitc :: naive_interpreter $ AOrExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		if cond.is_true then return cond
		return v.expr(self.n_expr2)
	end
src/interpreter/naive_interpreter.nit:1984,2--1990,4

nitc :: naive_interpreter $ AImpliesExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		if not cond.is_true then return v.true_instance
		return v.expr(self.n_expr2)
	end
src/interpreter/naive_interpreter.nit:1994,2--2000,4

nitc :: naive_interpreter $ AAndExpr :: expr
	redef fun expr(v)
	do
		var cond = v.expr(self.n_expr)
		if cond == null then return null
		if not cond.is_true then return cond
		return v.expr(self.n_expr2)
	end
src/interpreter/naive_interpreter.nit:2004,2--2010,4

nitc :: naive_interpreter $ AStringExpr :: expr
	redef fun expr(v) do
		var s = v.string_instance(value)
		if is_string then return s
		if is_bytestring then
			var ns = v.c_string_instance_from_ns(bytes.items, bytes.length)
			var ln = v.int_instance(bytes.length)
			var prop = to_bytes_with_copy
			assert prop != null
			var res = v.callsite(prop, [ns, ln])
			if res == null then
				print "Cannot call property `to_bytes` on {self}"
				abort
			end
			s = res
		else if is_re then
			var res = make_re(v, s)
			assert res != null
			s = res
		else
			print "Unimplemented prefix or suffix for {self}"
			abort
		end
		return s
	end
src/interpreter/naive_interpreter.nit:2127,2--2150,4