Type and check 'continue' return value.
authorJean Privat <jean@pryen.org>
Tue, 20 Jan 2009 23:30:27 +0000 (18:30 -0500)
committerJean Privat <jean@pryen.org>
Tue, 20 Jan 2009 23:30:27 +0000 (18:30 -0500)
Also detects closure with a missing continue.

src/syntax/control_flow.nit
src/syntax/typing.nit

index f044cd1..e477fca 100644 (file)
@@ -265,9 +265,14 @@ special PExpr
 
                super
 
+               # Check control flow if any
+               check_control_flow(v)
+
                # Restore control flow value since all controlable blocks are optionnal
                v.control_flow_ctx = old_control_flow_ctx
        end
+
+       private meth check_control_flow(v: ControlFlowVisitor) do end
 end
 
 redef class AWhileExpr
@@ -303,6 +308,21 @@ redef class AVarReassignExpr
        end
 end
 
+redef class AClosureDef
+special AControlableBlock
+       redef meth accept_control_flow(v)
+       do
+               for va in variables do v.mark_is_set(va)
+               super
+       end
+
+       redef meth check_control_flow(v)
+       do
+               if v.control_flow_ctx.unreash == false and signature.return_type != null then
+                       v.error(self, "Control error: Reached end of bloc (a 'continue' with a value was expected).")
+               end
+       end
+end
 
 redef class AOnceExpr
        redef meth accept_control_flow(v)
index 423d970..4fb05fb 100644 (file)
@@ -50,6 +50,9 @@ special AbsSyntaxVisitor
        # Block of the current method
        readable writable attr _top_block: PExpr
 
+       # Current closure 'return' static type (if any)
+       readable writable attr _closure_stype: MMType
+
        # List of explicit invocation of constructors of super-classes
        readable writable attr _explicit_super_init_calls: Array[MMMethod]
 
@@ -364,6 +367,20 @@ redef class AReturnExpr
        end
 end
 
+redef class AContinueExpr
+       redef meth after_typing(v)
+       do
+               var t = v.closure_stype
+               if n_expr == null and t != null then
+                       v.error(self, "Error: continue with a value required in this bloc.")
+               else if n_expr != null and t == null then
+                       v.error(self, "Error: continue without value required in this bloc.")
+               else if n_expr != null and t != null then
+                       v.check_conform_expr(n_expr, t)
+               end
+       end
+end
+
 redef class AIfExpr
        redef meth accept_typing(v)
        do
@@ -1232,6 +1249,9 @@ redef class AClosureDef
 
                signature = sig
 
+               var old_stype = v.closure_stype
+               v.closure_stype = sig.return_type
+
                v.variable_ctx = v.variable_ctx.sub
                variables = new Array[AutoVariable]
                for i in [0..n_id.length[ do
@@ -1243,6 +1263,8 @@ redef class AClosureDef
 
                _accept_typing2 = true
                accept_typing(v)
+
+               v.closure_stype = old_stype
        end
 end