syntax: break closures are implicitly ended with 'break'
authorJean Privat <jean@pryen.org>
Mon, 24 Aug 2009 03:08:45 +0000 (23:08 -0400)
committerJean Privat <jean@pryen.org>
Mon, 24 Aug 2009 03:08:45 +0000 (23:08 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

39 files changed:
src/syntax/icode_generation.nit
src/syntax/typing.nit
tests/base_closure_break2.nit [new file with mode: 0644]
tests/base_closure_break_default.nit [new file with mode: 0644]
tests/base_closure_break_default2.nit [new file with mode: 0644]
tests/base_closure_forms.nit
tests/sav/base_closure_break2.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt1.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt10.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt11.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt12.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt13.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt2.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt3.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt4.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt5.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt7.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt8.sav [new file with mode: 0644]
tests/sav/base_closure_break2_alt9.sav [new file with mode: 0644]
tests/sav/base_closure_break_alt13.sav
tests/sav/base_closure_break_default.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt1.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt2.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt3.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt4.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt5.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt7.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt8.sav [new file with mode: 0644]
tests/sav/base_closure_break_default2_alt9.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt1.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt2.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt3.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt4.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt5.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt6.sav [new file with mode: 0644]
tests/sav/base_closure_break_default_alt7.sav [new file with mode: 0644]

index 08466d9..31546ac 100644 (file)
@@ -354,6 +354,11 @@ redef class AClosureDecl
                if n_expr != null then
                        v.generate_stmt(n_expr)
                        v.iroutine.closure_decls[position].default = iclos
+
+                       # Add a final break in case of break block witout value
+                       if variable.closure.is_break and v.return_value == null then
+                               v.stmt(new IEscape(v.return_seq.as(not null)))
+                       end
                end
                v.seq = old_seq
        end
@@ -1400,6 +1405,11 @@ redef class AClosureDef
 
                v.generate_stmt(n_expr)
 
+               # Add a final break in case of break block witout value
+               if closure.is_break and escapable.break_value == null then
+                       v.stmt(new IEscape(escapable.break_seq.as(not null)))
+               end
+
                v.seq = seq_old
                _iclosure_def = iclos
                return iclos
index 8bbcda8..70e7d5d 100644 (file)
@@ -287,8 +287,8 @@ redef class AClosureDecl
                        if v.variable_ctx.unreash == false then
                                if variable.closure.signature.return_type != null then
                                        v.error(self, "Control error: Reached end of block (a 'continue' with a value was expected).")
-                               else if variable.closure.is_break then
-                                       v.error(self, "Control error: Reached end of break block (an 'abort' was expected).")
+                               else if variable.closure.is_break and escapable.break_list != null then
+                                       v.error(self, "Control error: Reached end of break block (a 'break' with a value was expected).")
                                end
                        end
                end
@@ -1683,8 +1683,8 @@ redef class AClosureDef
                if v.variable_ctx.unreash == false then
                        if closure.signature.return_type != null then
                                v.error(self, "Control error: Reached end of block (a 'continue' with a value was expected).")
-                       else if closure.is_break then
-                               v.error(self, "Control error: Reached end of break block (a 'break' was expected).")
+                       else if closure.is_break and esc.break_list != null then
+                               v.error(self, "Control error: Reached end of break block (a 'break' with a value was expected).")
                        end
                end
                v.variable_ctx = old_var_ctx
diff --git a/tests/base_closure_break2.nit b/tests/base_closure_break2.nit
new file mode 100644 (file)
index 0000000..f11670e
--- /dev/null
@@ -0,0 +1,55 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class A
+       fun foo: Int
+               break !bar #!alt12#
+               #alt12#break !bar: Int
+       do
+               1.output
+               bar #!alt1#
+               #alt2#bar(2)
+               #alt3#var x = bar
+               return 4
+       end
+end
+
+fun work
+do
+       var a = new A
+       var r = a.foo !bar do #!alt11#
+               #alt11#var r = a.foo !bar x do
+               2.output
+               #alt4#break 4
+               #alt5#break 'x'
+               #alt6#continue
+               #alt7#continue 'x'
+               #alt8#return
+               #alt9#return 'x'
+               3.output
+               break 4 #!alt13#
+       end
+       r.output
+       #alt10# a.foo
+       5.output
+end
+
+0.output
+work
+6.output
+
diff --git a/tests/base_closure_break_default.nit b/tests/base_closure_break_default.nit
new file mode 100644 (file)
index 0000000..774227a
--- /dev/null
@@ -0,0 +1,43 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class A
+       fun foo
+               break !bar do
+                       #alt1# return
+                       #alt2# return 1
+                       #alt3# abort
+                       #alt4# continue
+                       #alt5# continue 20
+                       #alt6# break
+                       #alt7# break 1
+                       20.output
+               end
+       do
+               1.output
+               bar
+               3.output
+       end
+end
+
+var a = new A
+0.output
+a.foo !bar do 2.output
+0.output
+a.foo
+0.output
diff --git a/tests/base_closure_break_default2.nit b/tests/base_closure_break_default2.nit
new file mode 100644 (file)
index 0000000..174cc23
--- /dev/null
@@ -0,0 +1,46 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean Privat <jean@pryen.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import kernel
+
+class A
+       fun foo: Int
+               break !bar do
+                       #alt1# return
+                       #alt2# return 1
+                       #alt3# abort
+                       #alt4# continue
+                       #alt5# continue 20
+                       #alt6# break
+                       #alt7# break 1
+                       #alt8# break 'x'
+                       break 20#!alt9#
+               end
+       do
+               1.output
+               bar
+               3.output
+       end
+end
+
+var a = new A
+0.output
+var x = a.foo !bar do break 2
+x.output
+0.output
+x = a.foo
+x.output
+0.output
index d5457a7..262d433 100644 (file)
@@ -215,7 +215,6 @@ do
        !error(e) do
                'E'.output
                e.output
-               break
        end
        if f_escape != null then
                'O'.output
diff --git a/tests/sav/base_closure_break2.sav b/tests/sav/base_closure_break2.sav
new file mode 100644 (file)
index 0000000..09c277a
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+3
+4
+5
+6
diff --git a/tests/sav/base_closure_break2_alt1.sav b/tests/sav/base_closure_break2_alt1.sav
new file mode 100644 (file)
index 0000000..5ac6b87
--- /dev/null
@@ -0,0 +1,5 @@
+0
+1
+4
+5
+6
diff --git a/tests/sav/base_closure_break2_alt10.sav b/tests/sav/base_closure_break2_alt10.sav
new file mode 100644 (file)
index 0000000..3f36375
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt10.nit:48,3--7: Error: foo requires 1 blocks.
diff --git a/tests/sav/base_closure_break2_alt11.sav b/tests/sav/base_closure_break2_alt11.sav
new file mode 100644 (file)
index 0000000..082f9c3
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt11.nit:35,17--44,9: Error: 0 automatic variable names expected, 1 found.
diff --git a/tests/sav/base_closure_break2_alt12.sav b/tests/sav/base_closure_break2_alt12.sav
new file mode 100644 (file)
index 0000000..512619b
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt12.nit:21,3--17: Syntax Error: A break block cannot have a return value.
diff --git a/tests/sav/base_closure_break2_alt13.sav b/tests/sav/base_closure_break2_alt13.sav
new file mode 100644 (file)
index 0000000..885f0f7
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt13.nit:35,16--44,10: Control error: Reached end of break block (a 'break' with a value was expected).
diff --git a/tests/sav/base_closure_break2_alt2.sav b/tests/sav/base_closure_break2_alt2.sav
new file mode 100644 (file)
index 0000000..23d8025
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt2.nit:26,3--7: Error: arity missmatch; prototype is 'bar'.
diff --git a/tests/sav/base_closure_break2_alt3.sav b/tests/sav/base_closure_break2_alt3.sav
new file mode 100644 (file)
index 0000000..5e5bf2c
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt3.nit:27,11--13: Type error: expected expression.
diff --git a/tests/sav/base_closure_break2_alt4.sav b/tests/sav/base_closure_break2_alt4.sav
new file mode 100644 (file)
index 0000000..8f824a6
--- /dev/null
@@ -0,0 +1,6 @@
+0
+1
+2
+4
+5
+6
diff --git a/tests/sav/base_closure_break2_alt5.sav b/tests/sav/base_closure_break2_alt5.sav
new file mode 100644 (file)
index 0000000..46671c7
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt5.nit:39,9--11: Type error: no most general type. Got Char and Int at 45,9.
diff --git a/tests/sav/base_closure_break2_alt6.sav b/tests/sav/base_closure_break2_alt6.sav
new file mode 100644 (file)
index 0000000..8f4ce59
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt6.nit:40,3--10: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break2_alt7.sav b/tests/sav/base_closure_break2_alt7.sav
new file mode 100644 (file)
index 0000000..2326d14
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt7.nit:41,3--14: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break2_alt8.sav b/tests/sav/base_closure_break2_alt8.sav
new file mode 100644 (file)
index 0000000..f9c3b7b
--- /dev/null
@@ -0,0 +1,4 @@
+0
+1
+2
+6
diff --git a/tests/sav/base_closure_break2_alt9.sav b/tests/sav/base_closure_break2_alt9.sav
new file mode 100644 (file)
index 0000000..cd9487c
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break2_alt9.nit:43,3--12: Error: Return with value in a procedure.
index eec06e9..6196664 100644 (file)
@@ -1 +1,6 @@
-alt/base_closure_break_alt13.nit:35,8--44,10: Control error: Reached end of break block (a 'break' was expected).
+0
+1
+2
+3
+5
+6
diff --git a/tests/sav/base_closure_break_default.sav b/tests/sav/base_closure_break_default.sav
new file mode 100644 (file)
index 0000000..21a2d26
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+0
+1
+20
+0
diff --git a/tests/sav/base_closure_break_default2.sav b/tests/sav/base_closure_break_default2.sav
new file mode 100644 (file)
index 0000000..21a2d26
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+0
+1
+20
+0
diff --git a/tests/sav/base_closure_break_default2_alt1.sav b/tests/sav/base_closure_break_default2_alt1.sav
new file mode 100644 (file)
index 0000000..1baa661
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt1.nit:22,5--10: Error: Return without value in a function.
diff --git a/tests/sav/base_closure_break_default2_alt2.sav b/tests/sav/base_closure_break_default2_alt2.sav
new file mode 100644 (file)
index 0000000..9542707
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+0
+1
+1
+0
diff --git a/tests/sav/base_closure_break_default2_alt3.sav b/tests/sav/base_closure_break_default2_alt3.sav
new file mode 100644 (file)
index 0000000..c9217ae
--- /dev/null
@@ -0,0 +1,10 @@
+0
+1
+2
+0
+1
+Aborted (alt/base_closure_break_default2_alt3.nit:24)
+,---- Stack trace -- - -  -
+| base_closure_break_default2_alt3::A::foo (alt/base_closure_break_default2_alt3.nit:20)
+| base_closure_break_default2_alt3::Sys::(kernel::Sys::main) (alt/base_closure_break_default2_alt3.nit:39)
+`------------------- - -  -
diff --git a/tests/sav/base_closure_break_default2_alt4.sav b/tests/sav/base_closure_break_default2_alt4.sav
new file mode 100644 (file)
index 0000000..02f50c6
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt4.nit:25,5--12: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break_default2_alt5.sav b/tests/sav/base_closure_break_default2_alt5.sav
new file mode 100644 (file)
index 0000000..96d0659
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt5.nit:26,5--15: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break_default2_alt6.sav b/tests/sav/base_closure_break_default2_alt6.sav
new file mode 100644 (file)
index 0000000..6343951
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt6.nit:27,5--9: Error: break with a value required in this block.
diff --git a/tests/sav/base_closure_break_default2_alt7.sav b/tests/sav/base_closure_break_default2_alt7.sav
new file mode 100644 (file)
index 0000000..9542707
--- /dev/null
@@ -0,0 +1,7 @@
+0
+1
+2
+0
+1
+1
+0
diff --git a/tests/sav/base_closure_break_default2_alt8.sav b/tests/sav/base_closure_break_default2_alt8.sav
new file mode 100644 (file)
index 0000000..1b5b879
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt8.nit:29,11--13: Type error: expected Int, got Char
diff --git a/tests/sav/base_closure_break_default2_alt9.sav b/tests/sav/base_closure_break_default2_alt9.sav
new file mode 100644 (file)
index 0000000..b9f6464
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default2_alt9.nit:21,3--12: Control error: Reached end of break block (a 'break' with a value was expected).
diff --git a/tests/sav/base_closure_break_default_alt1.sav b/tests/sav/base_closure_break_default_alt1.sav
new file mode 100644 (file)
index 0000000..4657fc0
--- /dev/null
@@ -0,0 +1,6 @@
+0
+1
+2
+0
+1
+0
diff --git a/tests/sav/base_closure_break_default_alt2.sav b/tests/sav/base_closure_break_default_alt2.sav
new file mode 100644 (file)
index 0000000..23e01ac
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default_alt2.nit:23,5--12: Error: Return with value in a procedure.
diff --git a/tests/sav/base_closure_break_default_alt3.sav b/tests/sav/base_closure_break_default_alt3.sav
new file mode 100644 (file)
index 0000000..c400701
--- /dev/null
@@ -0,0 +1,10 @@
+0
+1
+2
+0
+1
+Aborted (alt/base_closure_break_default_alt3.nit:24)
+,---- Stack trace -- - -  -
+| base_closure_break_default_alt3::A::foo (alt/base_closure_break_default_alt3.nit:20)
+| base_closure_break_default_alt3::Sys::(kernel::Sys::main) (alt/base_closure_break_default_alt3.nit:38)
+`------------------- - -  -
diff --git a/tests/sav/base_closure_break_default_alt4.sav b/tests/sav/base_closure_break_default_alt4.sav
new file mode 100644 (file)
index 0000000..a28c02a
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default_alt4.nit:25,5--12: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break_default_alt5.sav b/tests/sav/base_closure_break_default_alt5.sav
new file mode 100644 (file)
index 0000000..93faf17
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default_alt5.nit:26,5--15: Error: cannot 'continue', only 'break'.
diff --git a/tests/sav/base_closure_break_default_alt6.sav b/tests/sav/base_closure_break_default_alt6.sav
new file mode 100644 (file)
index 0000000..4657fc0
--- /dev/null
@@ -0,0 +1,6 @@
+0
+1
+2
+0
+1
+0
diff --git a/tests/sav/base_closure_break_default_alt7.sav b/tests/sav/base_closure_break_default_alt7.sav
new file mode 100644 (file)
index 0000000..b04c112
--- /dev/null
@@ -0,0 +1 @@
+alt/base_closure_break_default_alt7.nit:28,5--11: Error: break without value required in this block.