do
var initializers = callsite.mpropdef.initializers
if not initializers.is_empty then
- assert initializers.length == arguments.length - 1 else debug("expected {initializers.length} got {arguments.length - 1}")
var recv = arguments.first
var i = 1
for p in initializers do
if p isa MMethod then
- self.send(p, [recv, arguments[i]])
+ var args = [recv]
+ for x in p.intro.msignature.mparameters do
+ args.add arguments[i]
+ i += 1
+ end
+ self.send(p, args)
else if p isa MAttribute then
assert recv isa MutableInstance
recv.attributes[p] = arguments[i]
+ i += 1
else abort
- i += 1
end
+ assert i == arguments.length
+
return send(callsite.mproperty, [recv])
end
return send(callsite.mproperty, arguments)
do
return mtype.anchor_to(self.mainmodule, self.frame.arguments.first.mtype.as(MClassType))
end
+
+ # Placebo instance used to mark internal error result when `null` already have a meaning.
+ # TODO: replace with multiple return or something better
+ var error_instance = new MutableInstance(modelbuilder.model.null_type) is lazy
end
# An instance represents a value of the executed program.
v.call_without_varargs(superpd, arguments)
end
+ if mpropdef.is_intern or mpropdef.is_extern then
+ var res = intern_call(v, mpropdef, arguments)
+ if res != v.error_instance then return res
+ end
+
if n_block != null then
v.stmt(self.n_block)
return null
+ end
+
+ if mpropdef.is_intern then
+ fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
+ else if mpropdef.is_extern then
+ fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
else
- return intern_call(v, mpropdef, arguments)
+ fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
end
+ abort
end
+ # 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
else if pname == "address_is_null" then
return v.false_instance
end
- if mpropdef.is_intern then
- fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
- else if mpropdef.is_extern then
- fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
- else
- fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
- end
- abort
+ return v.error_instance
end
end
private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
do
if mpropdef.mproperty.is_root_init then
- assert self.super_inits == null
assert args.length == 1
if not mpropdef.is_intro then
# standard call-next-method
v.call_without_varargs(superpd, args)
end
return null
+ else
+ abort
end
-
- var super_inits = self.super_inits
- if super_inits != null then
- var args_of_super = args
- if args.length > 1 then args_of_super = [args.first]
- for su in super_inits do
- v.send(su, args_of_super)
- end
- end
- var recv = args.first
- assert recv isa MutableInstance
- var i = 1
- # Collect undefined attributes
- for npropdef in self.n_propdefs do
- if npropdef isa AAttrPropdef and not npropdef.noinit and npropdef.n_expr == null then
- v.write_attribute(npropdef.mpropdef.mproperty, recv, args[i])
- i += 1
- end
- end
- return null
end
end