tools: accept statement block in attributes
[nit.git] / src / interpreter / naive_interpreter.nit
index 7ee3ff7..e358b12 100644 (file)
@@ -114,43 +114,26 @@ class NaiveInterpreter
        # 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
@@ -398,7 +381,7 @@ class NaiveInterpreter
                        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)
@@ -908,7 +891,7 @@ redef class AMethPropdef
                                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)
@@ -969,7 +952,7 @@ redef class AMethPropdef
                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
@@ -1093,8 +1076,7 @@ redef class AAttrPropdef
        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
@@ -1108,12 +1090,26 @@ redef class AAttrPropdef
        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)
@@ -1230,20 +1226,7 @@ redef class ASelfExpr
        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
@@ -1252,7 +1235,7 @@ redef class ABreakExpr
                        if i == null then return
                        v.escapevalue = i
                end
-               v.breakmark = self.escapemark
+               v.escapemark = self.escapemark
        end
 end
 
@@ -1318,7 +1301,7 @@ redef class ADoExpr
        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
 
@@ -1330,8 +1313,8 @@ redef class AWhileExpr
                        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
@@ -1342,8 +1325,8 @@ redef class ALoopExpr
        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
@@ -1375,8 +1358,8 @@ redef class AForExpr
                                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
@@ -1696,7 +1679,7 @@ 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)