# Set this mark to skip the evaluation until the end of the specified method frame
var returnmark: nullable Frame = null
- # Is a break executed?
- # Set this mark to skip the evaluation until a labeled statement catch it with `is_break`
- var breakmark: nullable EscapeMark = null
-
- # Is a continue executed?
- # Set this mark to skip the evaluation until a labeled statement catch it with `is_continue`
- var continuemark: nullable EscapeMark = null
+ # Is a break or a continue executed?
+ # Set this mark to skip the evaluation until a labeled statement catch it with `is_escape`
+ var escapemark: nullable EscapeMark = null
# Is a return or a break or a continue executed?
# Use this function to know if you must skip the evaluation of statements
- fun is_escaping: Bool do return returnmark != null or breakmark != null or continuemark != null
+ fun is_escaping: Bool do return returnmark != null or escapemark != null
# The value associated with the current return/break/continue, if any.
# Set the value when you set a escapemark.
# Read the value when you catch a mark or reach the end of a method
var escapevalue: nullable Instance = null
- # If there is a break and is associated with `escapemark`, then return true an clear the mark.
- # If there is no break or if `escapemark` is null then return false.
- # Use this function to catch a potential break.
- fun is_break(escapemark: nullable EscapeMark): Bool
+ # If there is a break/continue and is associated with `escapemark`, then return true and clear the mark.
+ # If there is no break/continue or if `escapemark` is null then return false.
+ # Use this function to catch a potential break/continue.
+ fun is_escape(escapemark: nullable EscapeMark): Bool
do
- if escapemark != null and self.breakmark == escapemark then
- self.breakmark = null
- return true
- else
- return false
- end
- end
-
- # If there is a continue and is associated with `escapemark`, then return true an clear the mark.
- # If there is no continue or if `escapemark` is null then return false.
- # Use this function to catch a potential continue.
- fun is_continue(escapemark: nullable EscapeMark): Bool
- do
- if escapemark != null and self.continuemark == escapemark then
- self.continuemark = null
+ if escapemark != null and self.escapemark == escapemark then
+ self.escapemark = null
return true
else
return false
var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef]
self.parameter_check(npropdef, mpropdef, args)
return npropdef.call(self, mpropdef, args)
- else if mproperty.name == "init" then
+ else if mproperty.is_root_init then
var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef]
self.parameter_check(nclassdef, mpropdef, args)
return nclassdef.call(self, mpropdef, args)
return v.bool_instance(args[0].to_f.is_inf != 0)
end
else if cname == "NativeString" then
- if pname == "init" then
+ if pname == "new" then
return v.native_string_instance("!" * args[1].to_i)
end
var recvval = args.first.val.as(Buffer)
else if pname == "calloc_string" then
return v.native_string_instance("!" * args[1].to_i)
else if cname == "NativeArray" then
- if pname == "init" then
+ if pname == "new" then
var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
return new PrimitiveInstance[Array[Instance]](args[0].mtype, val)
end
private fun init_expr(v: NaiveInterpreter, recv: Instance)
do
if is_lazy then return
- var nexpr = self.n_expr
- if nexpr != null then
+ if has_value then
evaluate_expr(v, recv)
return
end
private fun evaluate_expr(v: NaiveInterpreter, recv: Instance): Instance
do
assert recv isa MutableInstance
- var nexpr = self.n_expr
- assert nexpr != null
var f = new Frame(self, self.mpropdef.as(not null), [recv])
v.frames.unshift(f)
- var val = v.expr(nexpr)
+
+ var val
+
+ var nexpr = self.n_expr
+ var nblock = self.n_block
+ if nexpr != null then
+ val = v.expr(nexpr)
+ else if nblock != null then
+ v.stmt(nblock)
+ assert v.returnmark == f
+ val = v.escapevalue
+ v.returnmark = null
+ v.escapevalue = null
+ else
+ abort
+ end
assert val != null
+
v.frames.shift
assert not v.is_escaping
v.write_attribute(self.mpropdef.mproperty, recv, val)
end
end
-redef class AContinueExpr
- redef fun stmt(v)
- do
- var ne = self.n_expr
- if ne != null then
- var i = v.expr(ne)
- if i == null then return
- v.escapevalue = i
- end
- v.continuemark = self.escapemark
- end
-end
-
-redef class ABreakExpr
+redef class AEscapeExpr
redef fun stmt(v)
do
var ne = self.n_expr
if i == null then return
v.escapevalue = i
end
- v.breakmark = self.escapemark
+ v.escapemark = self.escapemark
end
end
redef fun stmt(v)
do
v.stmt(self.n_block)
- v.is_break(self.escapemark) # Clear the break (if any)
+ v.is_escape(self.break_mark) # Clear the break (if any)
end
end
if cond == null then return
if not cond.is_true then return
v.stmt(self.n_block)
- if v.is_break(self.escapemark) then return
- v.is_continue(self.escapemark) # Clear the break
+ if v.is_escape(self.break_mark) then return
+ v.is_escape(self.continue_mark) # Clear the break
if v.is_escaping then return
end
end
do
loop
v.stmt(self.n_block)
- if v.is_break(self.escapemark) then return
- v.is_continue(self.escapemark) # Clear the break
+ if v.is_escape(self.break_mark) then return
+ v.is_escape(self.continue_mark) # Clear the break
if v.is_escaping then return
end
end
abort
end
v.stmt(self.n_block)
- if v.is_break(self.escapemark) then break
- v.is_continue(self.escapemark) # Clear the break
+ 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
redef class ANewExpr
redef fun expr(v)
do
- var mtype = v.unanchor_type(self.mtype.as(not null))
+ 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)