niti: expressions are escapable
authorJean Privat <jean@pryen.org>
Tue, 3 Jul 2012 17:24:43 +0000 (13:24 -0400)
committerJean Privat <jean@pryen.org>
Tue, 3 Jul 2012 17:24:43 +0000 (13:24 -0400)
Evaluating an expression return null if there is an escape.
Each caller should then accept or propagate the escaping.

Signed-off-by: Jean Privat <jean@pryen.org>

src/naive_interpreter.nit

index 27dfd13..2a80e3d 100644 (file)
@@ -135,12 +135,15 @@ private class NaiveInterpreter
        # Evaluate `n' as an expression in the current context.
        # Return the value of the expression.
        # If `n' cannot be evaluated, then aborts.
-       fun expr(n: AExpr): Instance
+       fun expr(n: AExpr): nullable Instance
        do
                var old = self.frame.current_node
                self.frame.current_node = n
                #n.debug("IN Execute expr")
-               var i = n.expr(self).as(not null)
+               var i = n.expr(self)
+               if i == null and not self.is_escaping then
+                       n.debug("inconsitance: no value and not escaping.")
+               end
                #n.debug("OUT Execute expr: value is {i}")
                #if not is_subtype(i.mtype, n.mtype.as(not null)) then n.debug("Expected {n.mtype.as(not null)} got {i}")
                self.frame.current_node = old
@@ -802,6 +805,7 @@ redef class AAttrPropdef
                        var f = new Frame(self, self.mpropdef.as(not null), [recv])
                        v.frames.unshift(f)
                        var val = v.expr(nexpr)
+                       assert val != null
                        v.frames.shift
                        assert not v.is_escaping
                        recv.attributes[self.mpropdef.mproperty] = val
@@ -878,6 +882,7 @@ redef class AVardeclExpr
                var ne = self.n_expr
                if ne != null then
                        var i = v.expr(ne)
+                       if i == null then return
                        v.frame.map[self.variable.as(not null)] = i
                end
        end
@@ -894,6 +899,7 @@ redef class AVarAssignExpr
        redef fun stmt(v)
        do
                var i = v.expr(self.n_value)
+               if i == null then return
                v.frame.map[self.variable.as(not null)] = i
        end
 end
@@ -903,6 +909,7 @@ redef class AVarReassignExpr
        do
                var vari = v.frame.map[self.variable.as(not null)]
                var value = v.expr(self.n_value)
+               if value == null then return
                var res = v.send(reassign_property.mproperty, [vari, value])
                assert res != null
                v.frame.map[self.variable.as(not null)] = res
@@ -919,6 +926,12 @@ 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
@@ -926,6 +939,12 @@ end
 redef class ABreakExpr
        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.breakmark = self.escapemark
        end
 end
@@ -936,6 +955,7 @@ redef class AReturnExpr
                var ne = self.n_expr
                if ne != null then
                        var i = v.expr(ne)
+                       if i == null then return
                        v.escapevalue = i
                end
                v.returnmark = v.frame
@@ -954,6 +974,7 @@ redef class AIfExpr
        redef fun stmt(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return
                if cond.is_true then
                        v.stmt(self.n_then)
                else
@@ -966,6 +987,7 @@ redef class AIfexprExpr
        redef fun expr(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return null
                if cond.is_true then
                        return v.expr(self.n_then)
                else
@@ -987,6 +1009,7 @@ redef class AWhileExpr
        do
                loop
                        var cond = v.expr(self.n_expr)
+                       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
@@ -1012,6 +1035,7 @@ redef class AForExpr
        redef fun stmt(v)
        do
                var col = v.expr(self.n_expr)
+               if col == null then return
                #self.debug("col {col}")
                var iter = v.send(v.mainmodule.force_get_primitive_method("iterator", col.mtype), [col]).as(not null)
                #self.debug("iter {iter}")
@@ -1043,6 +1067,7 @@ redef class AAssertExpr
        redef fun stmt(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return
                if not cond.is_true then
                        v.stmt(self.n_else)
                        if v.is_escaping then return
@@ -1061,6 +1086,7 @@ redef class AOrExpr
        redef fun expr(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return null
                if cond.is_true then return cond
                return v.expr(self.n_expr2)
        end
@@ -1070,6 +1096,7 @@ redef class AAndExpr
        redef fun expr(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return null
                if not cond.is_true then return cond
                return v.expr(self.n_expr2)
        end
@@ -1079,6 +1106,7 @@ redef class ANotExpr
        redef fun expr(v)
        do
                var cond = v.expr(self.n_expr)
+               if cond == null then return null
                return v.bool_instance(not cond.is_true)
        end
 end
@@ -1087,6 +1115,7 @@ redef class AOrElseExpr
        redef fun expr(v)
        do
                var i = v.expr(self.n_expr)
+               if i == null then return null
                if i != v.null_instance then return i
                return v.expr(self.n_expr2)
        end
@@ -1096,7 +1125,9 @@ redef class AEeExpr
        redef fun expr(v)
        do
                var i = v.expr(self.n_expr)
+               if i == null then return null
                var i2 = v.expr(self.n_expr2)
+               if i2 == null then return null
                return v.bool_instance(i.eq_is(i2))
        end
 end
@@ -1127,7 +1158,9 @@ redef class AArrayExpr
        do
                var val = new Array[Instance]
                for nexpr in self.n_exprs.n_exprs do
-                       val.add(v.expr(nexpr))
+                       var i = v.expr(nexpr)
+                       if i == null then return null
+                       val.add(i)
                end
                var mtype = v.unanchor_type(self.mtype.as(not null)).as(MGenericType)
                var elttype = mtype.arguments.first
@@ -1153,7 +1186,9 @@ redef class ASuperstringExpr
        do
                var array = new Array[Instance]
                for nexpr in n_exprs do
-                       array.add(v.expr(nexpr))
+                       var i = v.expr(nexpr)
+                       if i == null then return null
+                       array.add(i)
                end
                var i = v.array_instance(array, v.mainmodule.get_primitive_class("Object").mclass_type)
                var res = v.send(v.mainmodule.force_get_primitive_method("to_s", i.mtype), [i])
@@ -1166,7 +1201,9 @@ redef class ACrangeExpr
        redef fun expr(v)
        do
                var e1 = v.expr(self.n_expr)
+               if e1 == null then return null
                var e2 = v.expr(self.n_expr2)
+               if e2 == null then return null
                var mtype = v.unanchor_type(self.mtype.as(not null))
                var res = new Instance(mtype)
                v.init_instance(res)
@@ -1180,7 +1217,9 @@ redef class AOrangeExpr
        redef fun expr(v)
        do
                var e1 = v.expr(self.n_expr)
+               if e1 == null then return null
                var e2 = v.expr(self.n_expr2)
+               if e2 == null then return null
                var mtype = v.unanchor_type(self.mtype.as(not null))
                var res = new Instance(mtype)
                v.init_instance(res)
@@ -1215,6 +1254,7 @@ redef class AIsaExpr
        redef fun expr(v)
        do
                var i = v.expr(self.n_expr)
+               if i == null then return null
                var mtype = v.unanchor_type(self.cast_type.as(not null))
                return v.bool_instance(v.is_subtype(i.mtype, mtype))
        end
@@ -1224,6 +1264,7 @@ redef class AAsCastExpr
        redef fun expr(v)
        do
                var i = v.expr(self.n_expr)
+               if i == null then return null
                var mtype = v.unanchor_type(self.mtype.as(not null))
                if not v.is_subtype(i.mtype, mtype) then
                        #fatal(v, "Cast failed expected {mtype}, got {i}")
@@ -1237,6 +1278,7 @@ redef class AAsNotnullExpr
        redef fun expr(v)
        do
                var i = v.expr(self.n_expr)
+               if i == null then return null
                var mtype = v.unanchor_type(self.mtype.as(not null))
                if i.mtype isa MNullType then
                        fatal(v, "Cast failed")
@@ -1259,6 +1301,7 @@ redef class AOnceExpr
                        return v.onces[self]
                else
                        var res = v.expr(self.n_expr)
+                       if res == null then return null
                        v.onces[self] = res
                        return res
                end
@@ -1269,9 +1312,12 @@ redef class ASendExpr
        redef fun expr(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return null
                var args = [recv]
                for a in compute_raw_arguments do
-                       args.add(v.expr(a))
+                       var i = v.expr(a)
+                       if i == null then return null
+                       args.add(i)
                end
                var mproperty = self.mproperty.as(not null)
                return v.send(mproperty, args)
@@ -1282,11 +1328,15 @@ redef class ASendReassignFormExpr
        redef fun stmt(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return
                var args = [recv]
                for a in compute_raw_arguments do
-                       args.add(v.expr(a))
+                       var i = v.expr(a)
+                       if i == null then return
+                       args.add(i)
                end
                var value = v.expr(self.n_value)
+               if value == null then return
 
                var mproperty = self.mproperty.as(not null)
                var read = v.send(mproperty, args)
@@ -1307,7 +1357,9 @@ redef class ASuperExpr
                var recv = v.frame.arguments.first
                var args = [recv]
                for a in self.n_args.n_exprs do
-                       args.add(v.expr(a))
+                       var i = v.expr(a)
+                       if i == null then return null
+                       args.add(i)
                end
                if args.length == 1 then
                        args = v.frame.arguments
@@ -1345,7 +1397,9 @@ redef class ANewExpr
                v.init_instance(recv)
                var args = [recv]
                for a in self.n_args.n_exprs do
-                       args.add(v.expr(a))
+                       var i = v.expr(a)
+                       if i == null then return null
+                       args.add(i)
                end
                var mproperty = self.mproperty.as(not null)
                var res2 = v.send(mproperty, args)
@@ -1362,6 +1416,7 @@ redef class AAttrExpr
        redef fun expr(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return null
                var mproperty = self.mproperty.as(not null)
                return v.read_attribute(mproperty, recv)
        end
@@ -1371,7 +1426,9 @@ redef class AAttrAssignExpr
        redef fun stmt(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return
                var i = v.expr(self.n_value)
+               if i == null then return
                var mproperty = self.mproperty.as(not null)
                recv.attributes[mproperty] = i
        end
@@ -1381,7 +1438,9 @@ redef class AAttrReassignExpr
        redef fun stmt(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return
                var value = v.expr(self.n_value)
+               if value == null then return
                var mproperty = self.mproperty.as(not null)
                var attr = v.read_attribute(mproperty, recv)
                var res = v.send(reassign_property.mproperty, [attr, value])
@@ -1394,6 +1453,7 @@ redef class AIssetAttrExpr
        redef fun expr(v)
        do
                var recv = v.expr(self.n_expr)
+               if recv == null then return null
                var mproperty = self.mproperty.as(not null)
                return v.bool_instance(recv.attributes.has_key(mproperty))
        end