syntax: fix 'break' with value in default closures
authorJean Privat <jean@pryen.org>
Mon, 24 Aug 2009 03:00:32 +0000 (23:00 -0400)
committerJean Privat <jean@pryen.org>
Mon, 24 Aug 2009 03:00:32 +0000 (23:00 -0400)
Break return type and return value is associated with the method return
type and return value.

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

19 files changed:
src/syntax/icode_generation.nit
src/syntax/typing.nit
tests/base_closure_default1.nit
tests/base_closure_default2.nit
tests/base_closure_default3.nit
tests/base_closure_default4.nit
tests/sav/base_closure_default1_alt3.sav
tests/sav/base_closure_default1_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_default1_alt7.sav [new file with mode: 0644]
tests/sav/base_closure_default2_alt3.sav
tests/sav/base_closure_default2_alt6.sav
tests/sav/base_closure_default2_alt7.sav [new file with mode: 0644]
tests/sav/base_closure_default2_alt8.sav [new file with mode: 0644]
tests/sav/base_closure_default3_alt3.sav
tests/sav/base_closure_default3_alt5.sav
tests/sav/base_closure_default3_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_default4_alt3.sav
tests/sav/base_closure_default4_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_default4_alt7.sav [new file with mode: 0644]

index fb4a801..08466d9 100644 (file)
@@ -347,6 +347,8 @@ redef class AClosureDecl
                v.seq = iclos.body
                escapable.continue_seq = iclos.body
                escapable.continue_value = iclos.result
+               escapable.break_seq = v.return_seq
+               escapable.break_value = v.return_value
                n_signature.fill_iroutine_parameters(v, variable.closure.signature, iclos.params, null)
 
                if n_expr != null then
index c3a5ffc..8bbcda8 100644 (file)
@@ -274,7 +274,10 @@ redef class AClosureDecl
                v.base_variable_ctx = v.variable_ctx
                v.variable_ctx = v.variable_ctx.sub(self)
 
-               var escapable = new EscapableClosure(self, variable.closure, null)
+               var blist: nullable Array[AExpr] = null
+               var t = v.local_property.signature.return_type
+               if t != null then blist = new Array[AExpr]
+               var escapable = new EscapableClosure(self, variable.closure, blist)
                _escapable = escapable
                v.escapable_ctx.push(escapable, null)
 
@@ -289,6 +292,9 @@ redef class AClosureDecl
                                end
                        end
                end
+               if blist != null then for x in blist do
+                       v.check_conform_expr(x, t)
+               end
 
                old_var_ctx.merge(v.variable_ctx)
                v.variable_ctx = old_var_ctx
index dc5bbbb..560e2cd 100644 (file)
@@ -24,6 +24,8 @@ class A
                        #alt3# abort
                        #alt4# continue
                        #alt5# continue 20
+                       #alt6# break
+                       #alt7# break 1
                        20.output
                end
        do
index ce6f476..a8d7251 100644 (file)
@@ -24,6 +24,8 @@ class A
                        #alt3# abort
                        #alt4# continue
                        #alt5# continue 20
+                       #alt7# break
+                       #alt8# break 1
                        (i * 10).output
                end
        do
index 9b413bc..44764de 100644 (file)
@@ -23,6 +23,8 @@ class A
                        #alt2# return 1
                        #alt3# abort
                        #alt4# continue
+                       #alt5# break
+                       #alt6# break 1
                        continue 20 #!alt5#
                end
        do
index 0cb3d77..1209c18 100644 (file)
@@ -23,6 +23,8 @@ class A
                        #alt2# return -1
                        #alt3# abort
                        #alt4# continue
+                       #alt6# break
+                       #alt7# break 1
                        continue (i * 10) #!alt5#
                end
        do
index 924c5c9..7db5fc4 100644 (file)
@@ -7,5 +7,5 @@
 Aborted (alt/base_closure_default1_alt3.nit:24)
 ,---- Stack trace -- - -  -
 | base_closure_default1_alt3::A::foo (alt/base_closure_default1_alt3.nit:20)
-| base_closure_default1_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default1_alt3.nit:36)
+| base_closure_default1_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default1_alt3.nit:38)
 `------------------- - -  -
diff --git a/tests/sav/base_closure_default1_alt6.sav b/tests/sav/base_closure_default1_alt6.sav
new file mode 100644 (file)
index 0000000..e8350ed
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+3
+0
+1
+0
diff --git a/tests/sav/base_closure_default1_alt7.sav b/tests/sav/base_closure_default1_alt7.sav
new file mode 100644 (file)
index 0000000..b12ac5d
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_default1_alt7.nit:28,5--11: Error: break without value required in this block.
index 9dc27f1..75d7d31 100644 (file)
@@ -7,5 +7,5 @@
 Aborted (alt/base_closure_default2_alt3.nit:24)
 ,---- Stack trace -- - -  -
 | base_closure_default2_alt3::A::foo (alt/base_closure_default2_alt3.nit:20)
-| base_closure_default2_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default2_alt3.nit:37)
+| base_closure_default2_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default2_alt3.nit:39)
 `------------------- - -  -
index c1ca6e5..2ba416d 100644 (file)
@@ -1 +1 @@
-alt/base_closure_default2_alt6.nit:32,3: Error: Method or variable 'i' unknown in A.
+alt/base_closure_default2_alt6.nit:34,3: Error: Method or variable 'i' unknown in A.
diff --git a/tests/sav/base_closure_default2_alt7.sav b/tests/sav/base_closure_default2_alt7.sav
new file mode 100644 (file)
index 0000000..e8350ed
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+3
+0
+1
+0
diff --git a/tests/sav/base_closure_default2_alt8.sav b/tests/sav/base_closure_default2_alt8.sav
new file mode 100644 (file)
index 0000000..30febd3
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_default2_alt8.nit:28,5--11: Error: break without value required in this block.
index 24832da..9218fde 100644 (file)
@@ -7,5 +7,5 @@
 Aborted (alt/base_closure_default3_alt3.nit:24)
 ,---- Stack trace -- - -  -
 | base_closure_default3_alt3::A::foo (alt/base_closure_default3_alt3.nit:20)
-| base_closure_default3_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default3_alt3.nit:35)
+| base_closure_default3_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default3_alt3.nit:37)
 `------------------- - -  -
index 293e7a5..e8350ed 100644 (file)
@@ -1 +1,7 @@
-alt/base_closure_default3_alt5.nit:21,3--11: Control error: Reached end of block (a 'continue' with a value was expected).
+0
+1
+2
+3
+0
+1
+0
diff --git a/tests/sav/base_closure_default3_alt6.sav b/tests/sav/base_closure_default3_alt6.sav
new file mode 100644 (file)
index 0000000..0203763
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_default3_alt6.nit:27,5--11: Error: break without value required in this block.
index 0812bec..5ded1f8 100644 (file)
@@ -7,5 +7,5 @@
 Aborted (alt/base_closure_default4_alt3.nit:24)
 ,---- Stack trace -- - -  -
 | base_closure_default4_alt3::A::foo (alt/base_closure_default4_alt3.nit:20)
-| base_closure_default4_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default4_alt3.nit:35)
+| base_closure_default4_alt3::Sys::(kernel::Sys::main) (alt/base_closure_default4_alt3.nit:37)
 `------------------- - -  -
diff --git a/tests/sav/base_closure_default4_alt6.sav b/tests/sav/base_closure_default4_alt6.sav
new file mode 100644 (file)
index 0000000..e8350ed
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+3
+0
+1
+0
diff --git a/tests/sav/base_closure_default4_alt7.sav b/tests/sav/base_closure_default4_alt7.sav
new file mode 100644 (file)
index 0000000..05e9908
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_default4_alt7.nit:27,5--11: Error: break without value required in this block.