aboutsummaryrefslogtreecommitdiff
path: root/testes/goto.lua
diff options
context:
space:
mode:
Diffstat (limited to 'testes/goto.lua')
-rw-r--r--testes/goto.lua256
1 files changed, 256 insertions, 0 deletions
diff --git a/testes/goto.lua b/testes/goto.lua
new file mode 100644
index 00000000..d22601f9
--- /dev/null
+++ b/testes/goto.lua
@@ -0,0 +1,256 @@
1-- $Id: goto.lua,v 1.15 2017/11/30 13:31:07 roberto Exp $
2-- See Copyright Notice in file all.lua
3
4collectgarbage()
5
6local function errmsg (code, m)
7 local st, msg = load(code)
8 assert(not st and string.find(msg, m))
9end
10
11-- cannot see label inside block
12errmsg([[ goto l1; do ::l1:: end ]], "label 'l1'")
13errmsg([[ do ::l1:: end goto l1; ]], "label 'l1'")
14
15-- repeated label
16errmsg([[ ::l1:: ::l1:: ]], "label 'l1'")
17
18
19-- undefined label
20errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'")
21
22-- jumping over variable definition
23errmsg([[
24do local bb, cc; goto l1; end
25local aa
26::l1:: print(3)
27]], "local 'aa'")
28
29-- jumping into a block
30errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'")
31errmsg([[ goto l1 do ::l1:: end ]], "label 'l1'")
32
33-- cannot continue a repeat-until with variables
34errmsg([[
35 repeat
36 if x then goto cont end
37 local xuxu = 10
38 ::cont::
39 until xuxu < x
40]], "local 'xuxu'")
41
42-- simple gotos
43local x
44do
45 local y = 12
46 goto l1
47 ::l2:: x = x + 1; goto l3
48 ::l1:: x = y; goto l2
49end
50::l3:: ::l3_1:: assert(x == 13)
51
52
53-- long labels
54do
55 local prog = [[
56 do
57 local a = 1
58 goto l%sa; a = a + 1
59 ::l%sa:: a = a + 10
60 goto l%sb; a = a + 2
61 ::l%sb:: a = a + 20
62 return a
63 end
64 ]]
65 local label = string.rep("0123456789", 40)
66 prog = string.format(prog, label, label, label, label)
67 assert(assert(load(prog))() == 31)
68end
69
70-- goto to correct label when nested
71do goto l3; ::l3:: end -- does not loop jumping to previous label 'l3'
72
73-- ok to jump over local dec. to end of block
74do
75 goto l1
76 local a = 23
77 x = a
78 ::l1::;
79end
80
81while true do
82 goto l4
83 goto l1 -- ok to jump over local dec. to end of block
84 goto l1 -- multiple uses of same label
85 local x = 45
86 ::l1:: ;;;
87end
88::l4:: assert(x == 13)
89
90if print then
91 goto l1 -- ok to jump over local dec. to end of block
92 error("should not be here")
93 goto l2 -- ok to jump over local dec. to end of block
94 local x
95 ::l1:: ; ::l2:: ;;
96else end
97
98-- to repeat a label in a different function is OK
99local function foo ()
100 local a = {}
101 goto l3
102 ::l1:: a[#a + 1] = 1; goto l2;
103 ::l2:: a[#a + 1] = 2; goto l5;
104 ::l3::
105 ::l3a:: a[#a + 1] = 3; goto l1;
106 ::l4:: a[#a + 1] = 4; goto l6;
107 ::l5:: a[#a + 1] = 5; goto l4;
108 ::l6:: assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and
109 a[4] == 5 and a[5] == 4)
110 if not a[6] then a[6] = true; goto l3a end -- do it twice
111end
112
113::l6:: foo()
114
115
116do -- bug in 5.2 -> 5.3.2
117 local x
118 ::L1::
119 local y -- cannot join this SETNIL with previous one
120 assert(y == nil)
121 y = true
122 if x == nil then
123 x = 1
124 goto L1
125 else
126 x = x + 1
127 end
128 assert(x == 2 and y == true)
129end
130
131-- bug in 5.3
132do
133 local first = true
134 local a = false
135 if true then
136 goto LBL
137 ::loop::
138 a = true
139 ::LBL::
140 if first then
141 first = false
142 goto loop
143 end
144 end
145 assert(a)
146end
147
148do -- compiling infinite loops
149 goto escape -- do not run the infinite loops
150 ::a:: goto a
151 ::b:: goto c
152 ::c:: goto b
153end
154::escape::
155--------------------------------------------------------------------------------
156-- testing closing of upvalues
157
158local debug = require 'debug'
159
160local function foo ()
161 local t = {}
162 do
163 local i = 1
164 local a, b, c, d
165 t[1] = function () return a, b, c, d end
166 ::l1::
167 local b
168 do
169 local c
170 t[#t + 1] = function () return a, b, c, d end -- t[2], t[4], t[6]
171 if i > 2 then goto l2 end
172 do
173 local d
174 t[#t + 1] = function () return a, b, c, d end -- t[3], t[5]
175 i = i + 1
176 local a
177 goto l1
178 end
179 end
180 end
181 ::l2:: return t
182end
183
184local a = foo()
185assert(#a == 6)
186
187-- all functions share same 'a'
188for i = 2, 6 do
189 assert(debug.upvalueid(a[1], 1) == debug.upvalueid(a[i], 1))
190end
191
192-- 'b' and 'c' are shared among some of them
193for i = 2, 6 do
194 -- only a[1] uses external 'b'/'b'
195 assert(debug.upvalueid(a[1], 2) ~= debug.upvalueid(a[i], 2))
196 assert(debug.upvalueid(a[1], 3) ~= debug.upvalueid(a[i], 3))
197end
198
199for i = 3, 5, 2 do
200 -- inner functions share 'b'/'c' with previous ones
201 assert(debug.upvalueid(a[i], 2) == debug.upvalueid(a[i - 1], 2))
202 assert(debug.upvalueid(a[i], 3) == debug.upvalueid(a[i - 1], 3))
203 -- but not with next ones
204 assert(debug.upvalueid(a[i], 2) ~= debug.upvalueid(a[i + 1], 2))
205 assert(debug.upvalueid(a[i], 3) ~= debug.upvalueid(a[i + 1], 3))
206end
207
208-- only external 'd' is shared
209for i = 2, 6, 2 do
210 assert(debug.upvalueid(a[1], 4) == debug.upvalueid(a[i], 4))
211end
212
213-- internal 'd's are all different
214for i = 3, 5, 2 do
215 for j = 1, 6 do
216 assert((debug.upvalueid(a[i], 4) == debug.upvalueid(a[j], 4))
217 == (i == j))
218 end
219end
220
221--------------------------------------------------------------------------------
222-- testing if x goto optimizations
223
224local function testG (a)
225 if a == 1 then
226 goto l1
227 error("should never be here!")
228 elseif a == 2 then goto l2
229 elseif a == 3 then goto l3
230 elseif a == 4 then
231 goto l1 -- go to inside the block
232 error("should never be here!")
233 ::l1:: a = a + 1 -- must go to 'if' end
234 else
235 goto l4
236 ::l4a:: a = a * 2; goto l4b
237 error("should never be here!")
238 ::l4:: goto l4a
239 error("should never be here!")
240 ::l4b::
241 end
242 do return a end
243 ::l2:: do return "2" end
244 ::l3:: do return "3" end
245 ::l1:: return "1"
246end
247
248assert(testG(1) == "1")
249assert(testG(2) == "2")
250assert(testG(3) == "3")
251assert(testG(4) == 5)
252assert(testG(5) == 10)
253--------------------------------------------------------------------------------
254
255
256print'OK'