summaryrefslogtreecommitdiff
path: root/testes/goto.lua
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-17 14:46:37 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-17 14:46:37 -0200
commit063d4e4543088e7a21965bda8ee5a0f952a9029e (patch)
tree6c3f2f8e98c26f071a94a32f9f2754396a66a9de /testes/goto.lua
parente354c6355e7f48e087678ec49e340ca0696725b1 (diff)
downloadlua-5.3.5.tar.gz
lua-5.3.5.tar.bz2
lua-5.3.5.zip
Lua 5.3.5 ported to gitv5.3.5
This is the first commit for the branch Lua 5.3. All source files were copied from the official distribution of 5.3.5 in the Lua site. The test files are the same of 5.3.4. The manual came from the previous RCS repository, revision 1.167.1.2.
Diffstat (limited to 'testes/goto.lua')
-rw-r--r--testes/goto.lua232
1 files changed, 232 insertions, 0 deletions
diff --git a/testes/goto.lua b/testes/goto.lua
new file mode 100644
index 00000000..0372aa9d
--- /dev/null
+++ b/testes/goto.lua
@@ -0,0 +1,232 @@
1-- $Id: goto.lua,v 1.13 2016/11/07 13:11:28 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--------------------------------------------------------------------------------
132-- testing closing of upvalues
133
134local debug = require 'debug'
135
136local function foo ()
137 local t = {}
138 do
139 local i = 1
140 local a, b, c, d
141 t[1] = function () return a, b, c, d end
142 ::l1::
143 local b
144 do
145 local c
146 t[#t + 1] = function () return a, b, c, d end -- t[2], t[4], t[6]
147 if i > 2 then goto l2 end
148 do
149 local d
150 t[#t + 1] = function () return a, b, c, d end -- t[3], t[5]
151 i = i + 1
152 local a
153 goto l1
154 end
155 end
156 end
157 ::l2:: return t
158end
159
160local a = foo()
161assert(#a == 6)
162
163-- all functions share same 'a'
164for i = 2, 6 do
165 assert(debug.upvalueid(a[1], 1) == debug.upvalueid(a[i], 1))
166end
167
168-- 'b' and 'c' are shared among some of them
169for i = 2, 6 do
170 -- only a[1] uses external 'b'/'b'
171 assert(debug.upvalueid(a[1], 2) ~= debug.upvalueid(a[i], 2))
172 assert(debug.upvalueid(a[1], 3) ~= debug.upvalueid(a[i], 3))
173end
174
175for i = 3, 5, 2 do
176 -- inner functions share 'b'/'c' with previous ones
177 assert(debug.upvalueid(a[i], 2) == debug.upvalueid(a[i - 1], 2))
178 assert(debug.upvalueid(a[i], 3) == debug.upvalueid(a[i - 1], 3))
179 -- but not with next ones
180 assert(debug.upvalueid(a[i], 2) ~= debug.upvalueid(a[i + 1], 2))
181 assert(debug.upvalueid(a[i], 3) ~= debug.upvalueid(a[i + 1], 3))
182end
183
184-- only external 'd' is shared
185for i = 2, 6, 2 do
186 assert(debug.upvalueid(a[1], 4) == debug.upvalueid(a[i], 4))
187end
188
189-- internal 'd's are all different
190for i = 3, 5, 2 do
191 for j = 1, 6 do
192 assert((debug.upvalueid(a[i], 4) == debug.upvalueid(a[j], 4))
193 == (i == j))
194 end
195end
196
197--------------------------------------------------------------------------------
198-- testing if x goto optimizations
199
200local function testG (a)
201 if a == 1 then
202 goto l1
203 error("should never be here!")
204 elseif a == 2 then goto l2
205 elseif a == 3 then goto l3
206 elseif a == 4 then
207 goto l1 -- go to inside the block
208 error("should never be here!")
209 ::l1:: a = a + 1 -- must go to 'if' end
210 else
211 goto l4
212 ::l4a:: a = a * 2; goto l4b
213 error("should never be here!")
214 ::l4:: goto l4a
215 error("should never be here!")
216 ::l4b::
217 end
218 do return a end
219 ::l2:: do return "2" end
220 ::l3:: do return "3" end
221 ::l1:: return "1"
222end
223
224assert(testG(1) == "1")
225assert(testG(2) == "2")
226assert(testG(3) == "3")
227assert(testG(4) == 5)
228assert(testG(5) == 10)
229--------------------------------------------------------------------------------
230
231
232print'OK'