redef class ToolContext
# --discover-call-trace
- var opt_discover_call_trace = new OptionBool("Trace calls of the first invocation of a method", "--discover-call-trace")
+ var opt_discover_call_trace = new OptionBool("Trace calls of the first invocation of methods", "--discover-call-trace")
redef init
do
n.debug("inconsitance: no value and not escaping.")
end
var implicit_cast_to = n.implicit_cast_to
- if implicit_cast_to != null then
+ if i != null and implicit_cast_to != null then
var mtype = self.unanchor_type(implicit_cast_to)
if not self.is_subtype(i.mtype, mtype) then n.fatal(self, "Cast failed. Expected `{implicit_cast_to}`, got `{i.mtype}`")
end
return instance
end
+ # Return the int8 instance associated with `val`.
+ fun int8_instance(val: Int8): Instance
+ do
+ var t = mainmodule.int8_type
+ var instance = new PrimitiveInstance[Int8](t, val)
+ init_instance_primitive(instance)
+ return instance
+ end
+
+ # Return the int16 instance associated with `val`.
+ fun int16_instance(val: Int16): Instance
+ do
+ var t = mainmodule.int16_type
+ var instance = new PrimitiveInstance[Int16](t, val)
+ init_instance_primitive(instance)
+ return instance
+ end
+
+ # Return the uint16 instance associated with `val`.
+ fun uint16_instance(val: UInt16): Instance
+ do
+ var t = mainmodule.uint16_type
+ var instance = new PrimitiveInstance[UInt16](t, val)
+ init_instance_primitive(instance)
+ return instance
+ end
+
+ # Return the int32 instance associated with `val`.
+ fun int32_instance(val: Int32): Instance
+ do
+ var t = mainmodule.int32_type
+ var instance = new PrimitiveInstance[Int32](t, val)
+ init_instance_primitive(instance)
+ return instance
+ end
+
+ # Return the uint32 instance associated with `val`.
+ fun uint32_instance(val: UInt32): Instance
+ do
+ var t = mainmodule.uint32_type
+ var instance = new PrimitiveInstance[UInt32](t, val)
+ init_instance_primitive(instance)
+ return instance
+ end
+
# Return the char instance associated with `val`.
fun char_instance(val: Char): Instance
do
fun string_instance(txt: String): Instance
do
var nat = native_string_instance(txt)
- var res = self.send(self.force_get_primitive_method("to_s_with_length", nat.mtype), [nat, self.int_instance(txt.bytelen)])
+ var res = self.send(self.force_get_primitive_method("to_s_full", nat.mtype), [nat, self.int_instance(txt.bytelen), self.int_instance(txt.length)])
assert res != null
return res
end
# Return `null` if one of the evaluation of the arguments return null.
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 msignature = mpropdef.msignature.as(not null)
var res = new Array[Instance]
res.add(recv)
res.add(null_instance)
continue
end
- if param.is_vararg and map.vararg_decl > 0 then
- var vararg = exprs.sub(j, map.vararg_decl)
+ if param.is_vararg and args[i].vararg_decl > 0 then
+ var vararg = exprs.sub(j, args[i].vararg_decl)
var elttype = param.mtype.anchor_to(self.mainmodule, recv.mtype.as(MClassType))
var arg = self.array_instance(vararg, elttype)
res.add(arg)
# Execute type checks of covariant parameters
fun parameter_check(node: ANode, mpropdef: MMethodDef, args: Array[Instance])
do
- var msignature = mpropdef.msignature
+ var msignature = mpropdef.msignature.as(not null)
for i in [0..msignature.arity[ do
+ var mp = msignature.mparameters[i]
+
# skip test for vararg since the array is instantiated with the correct polymorphic type
- if msignature.vararg_rank == i then continue
+ if mp.is_vararg then continue
# skip if the cast is not required
var origmtype = mpropdef.mproperty.intro.msignature.mparameters[i].mtype
#print "{mpropdef}: {mpropdef.mproperty.intro.msignature.mparameters[i]}"
# get the parameter type
- var mtype = msignature.mparameters[i].mtype
+ var mtype = mp.mtype
var anchor = args.first.mtype.as(MClassType)
var amtype = mtype.anchor_to(self.mainmodule, anchor)
if not args[i+1].mtype.is_subtype(self.mainmodule, anchor, amtype) then
# Use this method, instead of `send` to execute and control the additional behavior of the call-sites
fun callsite(callsite: nullable CallSite, arguments: Array[Instance]): nullable Instance
do
- var initializers = callsite.mpropdef.initializers
- if not initializers.is_empty then
- var recv = arguments.first
- var i = 1
- for p in initializers do
- if p isa MMethod then
- 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
- write_attribute(p, recv, arguments[i])
- i += 1
- else abort
- end
- assert i == arguments.length
-
- return send(callsite.mproperty, [recv])
- end
+ if callsite == null then return null
return send(callsite.mproperty, arguments)
end
# else aborts
fun to_b: Byte do abort
+ # Return the integer value if the instance is a int8.
+ # else aborts
+ fun to_i8: Int8 do abort
+
+ # Return the integer value if the instance is a int16.
+ # else aborts
+ fun to_i16: Int16 do abort
+
+ # Return the integer value if the instance is a uint16.
+ # else aborts
+ fun to_u16: UInt16 do abort
+
+ # Return the integer value if the instance is a int32.
+ # else aborts
+ fun to_i32: Int32 do abort
+
+ # Return the integer value if the instance is a uint32.
+ # else aborts
+ fun to_u32: UInt32 do abort
+
# The real value encapsulated if the instance is primitive.
# Else aborts.
fun val: nullable Object do abort
redef fun to_f do return val.as(Float)
redef fun to_b do return val.as(Byte)
+
+ redef fun to_i8 do return val.as(Int8)
+
+ redef fun to_i16 do return val.as(Int16)
+
+ redef fun to_u16 do return val.as(UInt16)
+
+ redef fun to_i32 do return val.as(Int32)
+
+ redef fun to_u32 do return val.as(UInt32)
end
# Information about local variables in a running method
v.call(superpd, arguments)
end
+ # First, try intern
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
-
+ # Then, try extern
+ if mpropdef.is_extern then
+ var res = call_extern(v, mpropdef, arguments, f)
+ if res != v.error_instance then return res
+ end
+ # Else try block
if n_block != null then
v.stmt(self.n_block)
return null
end
+ # Fail if nothing succeed
if mpropdef.is_intern then
fatal(v, "NOT YET IMPLEMENTED intern {mpropdef}")
else if mpropdef.is_extern then
- var res = call_extern(v, mpropdef, arguments, f)
- if res != v.error_instance then return res
+ fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
else
fatal(v, "NOT YET IMPLEMENTED <wat?> {mpropdef}")
end
# Call this extern method
protected fun call_extern(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance], f: Frame): nullable Instance
do
- fatal(v, "NOT YET IMPLEMENTED extern {mpropdef}")
return v.error_instance
end
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 == "ascii" then
- return v.char_instance(recvval.ascii)
+ 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.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)
else if pname == "rand" then
var res = recvval.rand
return v.int_instance(res)
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.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 == "ascii" then
- return v.int_instance(recv.ascii)
- else if pname == "successor" then
+ 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))
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
else if pname == "atoi" then
return v.int_instance(recvval.atoi)
else if pname == "fast_cstring" then
- var ns = recvval.to_s.substring_from(args[1].to_i)
- return v.native_string_instance(ns)
+ var ns = recvval.fast_cstring(args[1].to_i)
+ return v.native_string_instance(ns.to_s)
+ else if pname == "fetch_4_chars" then
+ return v.int_instance(args[0].val.as(NativeString).fetch_4_chars(args[1].to_i))
+ else if pname == "fetch_4_hchars" then
+ return v.int_instance(args[0].val.as(NativeString).fetch_4_hchars(args[1].to_i))
+ else if pname == "utf8_length" then
+ return v.int_instance(args[0].val.as(NativeString).utf8_length(args[1].to_i, args[2].to_i))
end
else if pname == "calloc_string" then
return v.native_string_instance_len(args[1].to_i)
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
redef class AClassdef
# Execute an implicit `mpropdef` associated with the current node.
- private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance
+ private fun call(v: NaiveInterpreter, mpropdef: MMethodDef, arguments: Array[Instance]): nullable Instance
do
if mpropdef.mproperty.is_root_init then
- assert args.length == 1
+ assert arguments.length == 1
if not mpropdef.is_intro then
# standard call-next-method
- var superpd = mpropdef.lookup_next_definition(v.mainmodule, args.first.mtype)
- v.call(superpd, args)
+ var superpd = mpropdef.lookup_next_definition(v.mainmodule, arguments.first.mtype)
+ v.call(superpd, arguments)
+ end
+ return null
+ else if mclassdef.auto_init == mpropdef then
+ var recv = arguments.first
+ var initializers = mpropdef.initializers
+ var no_init = false
+ if not initializers.is_empty then
+ var i = 1
+ for p in initializers do
+ if p isa MMethod then
+ var args = [recv]
+ for x in p.intro.msignature.mparameters do
+ args.add arguments[i]
+ i += 1
+ end
+ v.send(p, args)
+ if p.intro.is_calling_init then no_init = true
+ else if p isa MAttribute then
+ assert recv isa MutableInstance
+ v.write_attribute(p, recv, arguments[i])
+ i += 1
+ else abort
+ end
+ assert i == arguments.length
end
+ if not no_init then v.send(mclass.the_root_init_mmethod.as(not null), [recv])
return null
else
abort
redef class AForExpr
redef fun stmt(v)
do
- var col = v.expr(self.n_expr)
- if col == null then return
- if col.mtype isa MNullType then fatal(v, "Receiver is null")
+ var iters = new Array[Instance]
+
+ for g in n_groups do
+ var col = v.expr(g.n_expr)
+ if col == null then return
+ if col.mtype isa MNullType then fatal(v, "Receiver is null")
+
+ var iter = v.callsite(g.method_iterator, [col]).as(not null)
+ iters.add iter
+ end
- #self.debug("col {col}")
- var iter = v.callsite(method_iterator, [col]).as(not null)
- #self.debug("iter {iter}")
loop
- var isok = v.callsite(method_is_ok, [iter]).as(not null)
- if not isok.is_true then break
- if self.variables.length == 1 then
- var item = v.callsite(method_item, [iter]).as(not null)
- #self.debug("item {item}")
- v.write_variable(self.variables.first, item)
- else if self.variables.length == 2 then
- var key = v.callsite(method_key, [iter]).as(not null)
- v.write_variable(self.variables[0], key)
- var item = v.callsite(method_item, [iter]).as(not null)
- v.write_variable(self.variables[1], item)
- else
- abort
+ for g in n_groups, iter in iters do
+ var isok = v.callsite(g.method_is_ok, [iter]).as(not null)
+ if not isok.is_true then break label
+ if g.variables.length == 1 then
+ var item = v.callsite(g.method_item, [iter]).as(not null)
+ #self.debug("item {item}")
+ v.write_variable(g.variables.first, item)
+ else if g.variables.length == 2 then
+ var key = v.callsite(g.method_key, [iter]).as(not null)
+ v.write_variable(g.variables[0], key)
+ var item = v.callsite(g.method_item, [iter]).as(not null)
+ v.write_variable(g.variables[1], item)
+ else
+ abort
+ end
end
v.stmt(self.n_block)
if v.is_escape(self.break_mark) then break
v.is_escape(self.continue_mark) # Clear the break
if v.is_escaping then break
- v.callsite(method_next, [iter])
- end
- var method_finish = self.method_finish
- if method_finish != null then
- v.callsite(method_finish, [iter])
+ for g in n_groups, iter in iters do
+ v.callsite(g.method_next, [iter])
+ end
+ end label
+ for g in n_groups, iter in iters do
+ var method_finish = g.method_finish
+ if method_finish != null then
+ v.callsite(method_finish, [iter])
+ end
end
end
end
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
end