# Return the integer instance associated with `val`.
fun int_instance(val: Int): Instance
do
- var ic = get_primitive_class("Int")
- var instance = new PrimitiveInstance[Int](ic.mclass_type, val)
+ var t = mainmodule.int_type
+ var instance = new PrimitiveInstance[Int](t, val)
init_instance_primitive(instance)
return instance
end
# Return the char instance associated with `val`.
fun char_instance(val: Char): Instance
do
- var ic = get_primitive_class("Char")
- var instance = new PrimitiveInstance[Char](ic.mclass_type, val)
+ var t = mainmodule.char_type
+ var instance = new PrimitiveInstance[Char](t, val)
init_instance_primitive(instance)
return instance
end
# Return the float instance associated with `val`.
fun float_instance(val: Float): Instance
do
- var ic = get_primitive_class("Float")
- var instance = new PrimitiveInstance[Float](ic.mclass_type, val)
+ var t = mainmodule.float_type
+ var instance = new PrimitiveInstance[Float](t, val)
init_instance_primitive(instance)
return instance
end
fun array_instance(values: Array[Instance], elttype: MType): Instance
do
assert not elttype.need_anchor
- var nat = new PrimitiveInstance[Array[Instance]](get_primitive_class("NativeArray").get_mtype([elttype]), values)
+ var nat = new PrimitiveInstance[Array[Instance]](mainmodule.native_array_type(elttype), values)
init_instance_primitive(nat)
- var mtype = get_primitive_class("Array").get_mtype([elttype])
+ var mtype = mainmodule.array_type(elttype)
var res = new MutableInstance(mtype)
self.init_instance(res)
self.send(self.force_get_primitive_method("with_native", mtype), [res, nat, self.int_instance(values.length)])
do
var val = new FlatBuffer.from(txt)
val.add('\0')
- var ic = get_primitive_class("NativeString")
- var instance = new PrimitiveInstance[Buffer](ic.mclass_type, val)
+ var t = mainmodule.native_string_type
+ var instance = new PrimitiveInstance[Buffer](t, val)
init_instance_primitive(instance)
return instance
end
# This method is used to manage varargs in signatures and returns the real array
# of instances to use in the call.
# Return `null` if one of the evaluation of the arguments return null.
- fun varargize(mpropdef: MMethodDef, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance]
+ fun varargize(mpropdef: MMethodDef, map: nullable SignatureMap, recv: Instance, args: SequenceRead[AExpr]): nullable Array[Instance]
do
var msignature = mpropdef.new_msignature or else mpropdef.msignature.as(not null)
var res = new Array[Instance]
res.add(recv)
- if args.is_empty then return res
+ if msignature.arity == 0 then return res
+
+ if map == null then
+ assert args.length == msignature.arity else debug("Expected {msignature.arity} args, got {args.length}")
+ for ne in args do
+ var e = self.expr(ne)
+ if e == null then return null
+ res.add e
+ end
+ return res
+ end
+
+ # Eval in order of arguments, not parameters
+ var exprs = new Array[Instance].with_capacity(args.length)
+ for ne in args do
+ var e = self.expr(ne)
+ if e == null then return null
+ exprs.add e
+ end
- var vararg_rank = msignature.vararg_rank
- var vararg_len = args.length - msignature.arity
- if vararg_len < 0 then vararg_len = 0
+ # Fill `res` with the result of the evaluation according to the mapping
for i in [0..msignature.arity[ do
- if i == vararg_rank then
- var ne = args[i]
- if ne isa AVarargExpr then
- var e = self.expr(ne.n_expr)
- if e == null then return null
- res.add(e)
- continue
- end
- var vararg = new Array[Instance]
- for j in [vararg_rank..vararg_rank+vararg_len] do
- var e = self.expr(args[j])
- if e == null then return null
- vararg.add(e)
- end
- var elttype = msignature.mparameters[vararg_rank].mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType))
- res.add(self.array_instance(vararg, elttype))
- else
- var j = i
- if i > vararg_rank then j += vararg_len
- var e = self.expr(args[j])
- if e == null then return null
- res.add(e)
+ var param = msignature.mparameters[i]
+ var j = map.map.get_or_null(i)
+ if j == null then
+ # default value
+ res.add(null_instance)
+ continue
end
+ if param.is_vararg and map.vararg_decl > 0 then
+ var vararg = exprs.sub(j, map.vararg_decl)
+ var elttype = param.mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType))
+ var arg = self.array_instance(vararg, elttype)
+ res.add(arg)
+ continue
+ end
+ res.add exprs[j]
end
return res
end
# A hook to initialize a `PrimitiveInstance`
fun init_instance_primitive(recv: Instance) do end
- # Return the primitive `MClass` corresponding to the `name` given in parameter
- # `name` : name of the primitive class
- fun get_primitive_class(name: String): MClass
- do
- return mainmodule.get_primitive_class(name)
- end
-
# This function determines the correct type according to the receiver of the current propdef (self).
fun unanchor_type(mtype: MType): MType
do
var recvval = args[0].to_i
if pname == "unary -" then
return v.int_instance(-args[0].to_i)
+ else if pname == "unary +" then
+ return args[0]
else if pname == "+" then
return v.int_instance(args[0].to_i + args[1].to_i)
else if pname == "-" 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
else if pname == "file_exists" then
return v.bool_instance(recvval.to_s.file_exists)
else if pname == "file_mkdir" then
- recvval.to_s.mkdir
- return null
+ var res = recvval.to_s.mkdir
+ return v.bool_instance(res == null)
else if pname == "file_chdir" then
- recvval.to_s.chdir
- return null
+ var res = recvval.to_s.chdir
+ return v.bool_instance(res == null)
else if pname == "file_realpath" then
return v.native_string_instance(recvval.to_s.realpath)
else if pname == "get_environ" then
return v.int_instance(res)
else if pname == "atof" then
return v.float_instance(recvval.to_f)
+ else if pname == "fast_cstring" then
+ var ns = recvval.to_cstring.to_s.substring_from(args[1].to_i)
+ return v.native_string_instance(ns)
end
else if cname == "String" then
var cs = v.send(v.force_get_primitive_method("to_cstring", args.first.mtype), [args.first])
if pname == "files" then
var res = new Array[Instance]
for f in str.files do res.add v.string_instance(f)
- return v.array_instance(res, v.get_primitive_class("String").mclass_type)
+ return v.array_instance(res, v.mainmodule.string_type)
end
else if pname == "calloc_string" then
return v.native_string_instance("!" * args[1].to_i)
else if pname == "set_buffering_type" then
return v.int_instance(recvval.as(PrimitiveNativeFile).set_buffering_type(args[1].to_i, args[2].to_i))
end
- else if pname == "calloc_array" then
- var recvtype = args.first.mtype.as(MClassType)
- var mtype: MType
- mtype = recvtype.supertype_to(v.mainmodule, recvtype, v.get_primitive_class("ArrayCapable"))
- mtype = mtype.arguments.first
- var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
- var instance = new PrimitiveInstance[Array[Instance]](v.get_primitive_class("NativeArray").get_mtype([mtype]), val)
- v.init_instance_primitive(instance)
- return instance
else if pname == "native_argc" then
return v.int_instance(v.arguments.length)
else if pname == "native_argv" then
end
redef class AVardeclExpr
- redef fun stmt(v)
+ redef fun expr(v)
do
var ne = self.n_expr
if ne != null then
var i = v.expr(ne)
- if i == null then return
+ if i == null then return null
v.write_variable(self.variable.as(not null), i)
+ return i
end
+ return null
end
end
end
end
+redef class AImplicitSelfExpr
+ redef fun expr(v)
+ do
+ if not is_sys then return super
+ return v.mainobj
+ end
+end
+
redef class AEscapeExpr
redef fun stmt(v)
do
end
end
+redef class AWithExpr
+ redef fun stmt(v)
+ do
+ var expr = v.expr(self.n_expr)
+ if expr == null then return
+
+ v.callsite(method_start, [expr])
+ v.stmt(self.n_block)
+ v.is_escape(self.break_mark) # Clear the break
+ v.callsite(method_finish, [expr])
+ end
+end
+
redef class AAssertExpr
redef fun stmt(v)
do
if i == null then return null
array.add(i)
end
- var i = v.array_instance(array, v.get_primitive_class("Object").mclass_type)
+ var i = v.array_instance(array, v.mainmodule.object_type)
var res = v.send(v.force_get_primitive_method("to_s", i.mtype), [i])
assert res != null
return res
do
var recv = v.expr(self.n_expr)
if recv == null then return null
- var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments)
+ var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments)
if args == null then return null
var res = v.callsite(callsite, args)
do
var recv = v.expr(self.n_expr)
if recv == null then return
- var args = v.varargize(callsite.mpropdef, recv, self.raw_arguments)
+ var args = v.varargize(callsite.mpropdef, callsite.signaturemap, recv, self.raw_arguments)
if args == null then return
var value = v.expr(self.n_value)
if value == null then return
var callsite = self.callsite
if callsite != null then
- var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs)
- if args == null then return null
- # Add additional arguments for the super init call
- if args.length == 1 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
+ # Standard call-next-method
var mpropdef = self.mpropdef
mpropdef = mpropdef.lookup_next_definition(v.mainmodule, recv.mtype)
- var args = v.varargize(mpropdef, recv, self.n_args.n_exprs)
- if args == null then return null
-
- if args.length == 1 then
+ 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
var mtype = v.unanchor_type(self.recvtype.as(not null))
var recv: Instance = new MutableInstance(mtype)
v.init_instance(recv)
- var args = v.varargize(callsite.mpropdef, recv, self.n_args.n_exprs)
+ 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
end
end
+redef class AVarargExpr
+ redef fun expr(v)
+ do
+ return v.expr(self.n_expr)
+ end
+end
+
+redef class ANamedargExpr
+ redef fun expr(v)
+ do
+ return v.expr(self.n_expr)
+ end
+end
+
redef class ADebugTypeExpr
redef fun stmt(v)
do