init
do
- self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
- init_instance_primitive(self.true_instance)
- self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
- init_instance_primitive(self.false_instance)
+ if mainmodule.model.get_mclasses_by_name("Bool") != null then
+ self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
+ init_instance_primitive(self.true_instance)
+ self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
+ init_instance_primitive(self.false_instance)
+ end
self.null_instance = new PrimitiveInstance[nullable Object](mainmodule.model.null_type, null)
end
# If `n` cannot be evaluated, then aborts.
fun stmt(n: nullable AExpr)
do
- if n != null then
- var frame = self.frame
- var old = frame.current_node
- frame.current_node = n
- #n.debug("Execute stmt")
- n.stmt(self)
- frame.current_node = old
+ if n == null then return
+
+ if n.comprehension != null then
+ var comprehension = frame.comprehension.as(not null)
+ var i = expr(n)
+ if i != null then comprehension.add(i)
+ return
end
+
+ var frame = self.frame
+ var old = frame.current_node
+ frame.current_node = n
+ n.stmt(self)
+ frame.current_node = old
end
# Map used to store values of nodes that must be evaluated once in the system (`AOnceExpr`)
fun send_commons(mproperty: MMethod, args: Array[Instance], mtype: MType): nullable Instance
do
if mtype isa MNullType then
- if mproperty.name == "==" then
+ if mproperty.name == "==" or mproperty.name == "is_same_instance" then
return self.bool_instance(args[0] == args[1])
else if mproperty.name == "!=" then
return self.bool_instance(args[0] != args[1])
var arguments: Array[Instance]
# Mapping between a variable and the current value
private var map: Map[Variable, Instance] = new HashMap[Variable, Instance]
+ var comprehension: nullable Array[Instance] = null
end
redef class ANode
return v.int_instance(args[0].to_i.bin_xor(args[1].to_i))
else if pname == "bin_not" then
return v.int_instance(args[0].to_i.bin_not)
+ else if pname == "int_to_s_len" then
+ return v.int_instance(recvval.to_s.length)
else if pname == "native_int_to_s" then
- return v.native_string_instance(recvval.to_s)
+ var s = recvval.to_s
+ var srecv = args[1].val.as(Buffer)
+ srecv.clear
+ srecv.append(s)
+ srecv.add('\0')
+ return null
else if pname == "strerror_ext" then
return v.native_string_instance(recvval.strerror)
end
if fromval < 0 then
debug("Illegal access on {recvval} for element {fromval}/{recvval.length}")
end
- if fromval + lenval >= recvval.length then
+ if fromval + lenval > recvval.length then
debug("Illegal access on {recvval} for element {fromval}+{lenval}/{recvval.length}")
end
if toval < 0 then
debug("Illegal access on {destval} for element {toval}/{destval.length}")
end
- if toval + lenval >= destval.length then
+ if toval + lenval > destval.length then
debug("Illegal access on {destval} for element {toval}+{lenval}/{destval.length}")
end
recvval.as(FlatBuffer).copy(fromval, lenval, destval, toval)
# Return a possible value
# NOTE: Do not call this method directly, but use `v.expr`
# This method is here to be implemented by subclasses.
- private fun expr(v: NaiveInterpreter): nullable Instance
+ protected fun expr(v: NaiveInterpreter): nullable Instance
do
fatal(v, "NOT YET IMPLEMENTED expr {class_name}")
abort
# Evaluate the node as a statement.
# NOTE: Do not call this method directly, but use `v.stmt`
# This method is here to be implemented by subclasses (no need to return something).
- private fun stmt(v: NaiveInterpreter)
+ protected fun stmt(v: NaiveInterpreter)
do
expr(v)
end
redef fun expr(v)
do
var val = new Array[Instance]
- for nexpr in self.n_exprs.n_exprs do
- var i = v.expr(nexpr)
- if i == null then return null
- val.add(i)
+ 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)