github.com/xmx/lua@v0.0.0-20230324063450-8a298e091302/_glua-tests/goto.lua (about) 1 local function errmsg (code, m) 2 local st, msg = loadstring(code) 3 assert(not st and string.find(msg, m)) 4 end 5 6 -- cannot see label inside block 7 errmsg([[ goto l1; do ::l1:: end ]], "label 'l1'") 8 errmsg([[ do ::l1:: end goto l1; ]], "label 'l1'") 9 10 -- repeated label 11 errmsg([[ ::l1:: ::l1:: ]], "label 'l1'") 12 13 14 -- undefined label 15 errmsg([[ goto l1; local aa ::l1:: ::l2:: print(3) ]], "local 'aa'") 16 17 -- jumping over variable definition 18 errmsg([[ 19 do local bb, cc; goto l1; end 20 local aa 21 ::l1:: print(3) 22 ]], "local 'aa'") 23 24 -- jumping into a block 25 errmsg([[ do ::l1:: end goto l1 ]], "label 'l1'") 26 errmsg([[ goto l1 do ::l1:: end ]], "label 'l1'") 27 28 -- cannot continue a repeat-until with variables 29 errmsg([[ 30 repeat 31 if x then goto cont end 32 local xuxu = 10 33 ::cont:: 34 until xuxu < x 35 ]], "local 'xuxu'") 36 37 -- simple gotos 38 local x 39 do 40 local y = 12 41 goto l1 42 ::l2:: x = x + 1; goto l3 43 ::l1:: x = y; goto l2 44 end 45 ::l3:: ::l3_1:: assert(x == 13) 46 47 48 -- long labels 49 do 50 local prog = [[ 51 do 52 local a = 1 53 goto l%sa; a = a + 1 54 ::l%sa:: a = a + 10 55 goto l%sb; a = a + 2 56 ::l%sb:: a = a + 20 57 return a 58 end 59 ]] 60 local label = string.rep("0123456789", 40) 61 prog = string.format(prog, label, label, label, label) 62 assert(assert(loadstring(prog))() == 31) 63 end 64 65 -- goto to correct label when nested 66 do goto l3; ::l3:: end -- does not loop jumping to previous label 'l3' 67 68 -- ok to jump over local dec. to end of block 69 do 70 goto l1 71 local a = 23 72 x = a 73 ::l1::; 74 end 75 76 while true do 77 goto l4 78 goto l1 -- ok to jump over local dec. to end of block 79 goto l1 -- multiple uses of same label 80 local x = 45 81 ::l1:: ;;; 82 end 83 ::l4:: assert(x == 13) 84 85 if print then 86 goto l1 -- ok to jump over local dec. to end of block 87 error("should not be here") 88 goto l2 -- ok to jump over local dec. to end of block 89 local x 90 ::l1:: ; ::l2:: ;; 91 else end 92 93 -- to repeat a label in a different function is OK 94 local function foo () 95 local a = {} 96 goto l3 97 ::l1:: a[#a + 1] = 1; goto l2; 98 ::l2:: a[#a + 1] = 2; goto l5; 99 ::l3:: 100 ::l3a:: a[#a + 1] = 3; goto l1; 101 ::l4:: a[#a + 1] = 4; goto l6; 102 ::l5:: a[#a + 1] = 5; goto l4; 103 ::l6:: assert(a[1] == 3 and a[2] == 1 and a[3] == 2 and 104 a[4] == 5 and a[5] == 4) 105 if not a[6] then a[6] = true; goto l3a end -- do it twice 106 end 107 108 ::l6:: foo() 109 110 111 112 -------------------------------------------------------------------------------- 113 -- testing closing of upvalues 114 115 local function foo () 116 local a = {} 117 do 118 local i = 1 119 local k = 0 120 a[0] = function (y) k = y end 121 ::l1:: do 122 local x 123 if i > 2 then goto l2 end 124 a[i] = function (y) if y then x = y else return x + k end end 125 i = i + 1 126 goto l1 127 end 128 end 129 ::l2:: return a 130 end 131 132 local a = foo() 133 a[1](10); a[2](20) 134 assert(a[1]() == 10 and a[2]() == 20 and a[3] == nil) 135 a[0](13) 136 assert(a[1]() == 23 and a[2]() == 33) 137 138 -------------------------------------------------------------------------------- 139 -- testing if x goto optimizations 140 141 local function testG (a) 142 if a == 1 then 143 goto l1 144 error("should never be here!") 145 elseif a == 2 then goto l2 146 elseif a == 3 then goto l3 147 elseif a == 4 then 148 goto l1 -- go to inside the block 149 error("should never be here!") 150 ::l1:: a = a + 1 -- must go to 'if' end 151 else 152 goto l4 153 ::l4a:: a = a * 2; goto l4b 154 error("should never be here!") 155 ::l4:: goto l4a 156 error("should never be here!") 157 ::l4b:: 158 end 159 do return a end 160 ::l2:: do return "2" end 161 ::l3:: do return "3" end 162 ::l1:: return "1" 163 end 164 165 assert(testG(1) == "1") 166 assert(testG(2) == "2") 167 assert(testG(3) == "3") 168 assert(testG(4) == 5) 169 assert(testG(5) == 10) 170 -------------------------------------------------------------------------------- 171 172 173 print'OK'