Advertisement
Guest User

Dex script test

a guest
Jul 15th, 2019
1,153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 151.21 KB | None | 0 0
  1.  
  2. --Converted with ttyyuu12345's model to script plugin v4
  3. function sandbox(var,func)
  4. local env = getfenv(func)
  5. local newenv = setmetatable({},{
  6. __index = function(self,k)
  7. if k=="script" then
  8. return var
  9. else
  10. return env[k]
  11. end
  12. end,
  13. })
  14. setfenv(func,newenv)
  15. return func
  16. end
  17. cors = {}
  18. mas = Instance.new("Model",game:GetService("Lighting"))
  19. local chil = workspace:GetChildren()
  20. for i,v in pairs(chil) do
  21. if not (v==script or v:IsA("Camera") or v:IsA("Terrain") or game:GetService("Players"):GetPlayerFromCharacter(v)~=nil) then
  22. v:Destroy()
  23. end
  24. end
  25. Camera0 = Instance.new("Camera")
  26. Part1 = Instance.new("Part")
  27. Tool2 = Instance.new("Tool")
  28. Script3 = Instance.new("Script")
  29. Model4 = Instance.new("Model")
  30. RemoteEvent5 = Instance.new("RemoteEvent")
  31. RemoteEvent6 = Instance.new("RemoteEvent")
  32. RemoteEvent7 = Instance.new("RemoteEvent")
  33. RemoteEvent8 = Instance.new("RemoteEvent")
  34. Model9 = Instance.new("Model")
  35. Script10 = Instance.new("Script")
  36. Script11 = Instance.new("Script")
  37. Script12 = Instance.new("Script")
  38. Script13 = Instance.new("Script")
  39. Script14 = Instance.new("Script")
  40. ModuleScript15 = Instance.new("ModuleScript")
  41. ModuleScript16 = Instance.new("ModuleScript")
  42. ModuleScript17 = Instance.new("ModuleScript")
  43. ModuleScript18 = Instance.new("ModuleScript")
  44. ModuleScript19 = Instance.new("ModuleScript")
  45. ModuleScript20 = Instance.new("ModuleScript")
  46. ModuleScript21 = Instance.new("ModuleScript")
  47. ModuleScript22 = Instance.new("ModuleScript")
  48. LocalScript23 = Instance.new("LocalScript")
  49. LocalScript24 = Instance.new("LocalScript")
  50. ScreenGui25 = Instance.new("ScreenGui")
  51. Frame26 = Instance.new("Frame")
  52. LocalScript27 = Instance.new("LocalScript")
  53. ModuleScript28 = Instance.new("ModuleScript")
  54. Frame29 = Instance.new("Frame")
  55. TextLabel30 = Instance.new("TextLabel")
  56. TextBox31 = Instance.new("TextBox")
  57. BindableFunction32 = Instance.new("BindableFunction")
  58. BindableFunction33 = Instance.new("BindableFunction")
  59. BindableEvent34 = Instance.new("BindableEvent")
  60. Frame35 = Instance.new("Frame")
  61. BindableEvent36 = Instance.new("BindableEvent")
  62. BindableFunction37 = Instance.new("BindableFunction")
  63. BindableFunction38 = Instance.new("BindableFunction")
  64. BindableFunction39 = Instance.new("BindableFunction")
  65. BindableFunction40 = Instance.new("BindableFunction")
  66. LocalScript41 = Instance.new("LocalScript")
  67. LocalScript42 = Instance.new("LocalScript")
  68. Frame43 = Instance.new("Frame")
  69. TextButton44 = Instance.new("TextButton")
  70. TextLabel45 = Instance.new("TextLabel")
  71. TextLabel46 = Instance.new("TextLabel")
  72. ImageLabel47 = Instance.new("ImageLabel")
  73. Frame48 = Instance.new("Frame")
  74. Frame49 = Instance.new("Frame")
  75. Frame50 = Instance.new("Frame")
  76. TextButton51 = Instance.new("TextButton")
  77. ImageLabel52 = Instance.new("ImageLabel")
  78. TextButton53 = Instance.new("TextButton")
  79. ImageLabel54 = Instance.new("ImageLabel")
  80. TextButton55 = Instance.new("TextButton")
  81. ImageLabel56 = Instance.new("ImageLabel")
  82. TextButton57 = Instance.new("TextButton")
  83. ImageLabel58 = Instance.new("ImageLabel")
  84. TextButton59 = Instance.new("TextButton")
  85. ImageLabel60 = Instance.new("ImageLabel")
  86. TextButton61 = Instance.new("TextButton")
  87. ImageLabel62 = Instance.new("ImageLabel")
  88. TextButton63 = Instance.new("TextButton")
  89. Frame64 = Instance.new("Frame")
  90. Frame65 = Instance.new("Frame")
  91. TextLabel66 = Instance.new("TextLabel")
  92. BindableFunction67 = Instance.new("BindableFunction")
  93. Frame68 = Instance.new("Frame")
  94. TextLabel69 = Instance.new("TextLabel")
  95. TextLabel70 = Instance.new("TextLabel")
  96. TextButton71 = Instance.new("TextButton")
  97. TextLabel72 = Instance.new("TextLabel")
  98. TextLabel73 = Instance.new("TextLabel")
  99. Frame74 = Instance.new("Frame")
  100. Frame75 = Instance.new("Frame")
  101. TextLabel76 = Instance.new("TextLabel")
  102. Frame77 = Instance.new("Frame")
  103. TextButton78 = Instance.new("TextButton")
  104. TextLabel79 = Instance.new("TextLabel")
  105. TextButton80 = Instance.new("TextButton")
  106. TextBox81 = Instance.new("TextBox")
  107. TextButton82 = Instance.new("TextButton")
  108. TextLabel83 = Instance.new("TextLabel")
  109. TextLabel84 = Instance.new("TextLabel")
  110. Frame85 = Instance.new("Frame")
  111. TextLabel86 = Instance.new("TextLabel")
  112. Frame87 = Instance.new("Frame")
  113. TextButton88 = Instance.new("TextButton")
  114. TextLabel89 = Instance.new("TextLabel")
  115. TextButton90 = Instance.new("TextButton")
  116. Frame91 = Instance.new("Frame")
  117. TextLabel92 = Instance.new("TextLabel")
  118. Frame93 = Instance.new("Frame")
  119. TextLabel94 = Instance.new("TextLabel")
  120. TextButton95 = Instance.new("TextButton")
  121. Frame96 = Instance.new("Frame")
  122. TextLabel97 = Instance.new("TextLabel")
  123. Frame98 = Instance.new("Frame")
  124. TextLabel99 = Instance.new("TextLabel")
  125. ScrollingFrame100 = Instance.new("ScrollingFrame")
  126. TextButton101 = Instance.new("TextButton")
  127. TextLabel102 = Instance.new("TextLabel")
  128. TextLabel103 = Instance.new("TextLabel")
  129. TextButton104 = Instance.new("TextButton")
  130. TextButton105 = Instance.new("TextButton")
  131. Frame106 = Instance.new("Frame")
  132. TextButton107 = Instance.new("TextButton")
  133. TextBox108 = Instance.new("TextBox")
  134. TextButton109 = Instance.new("TextButton")
  135. TextButton110 = Instance.new("TextButton")
  136. Frame111 = Instance.new("Frame")
  137. Frame112 = Instance.new("Frame")
  138. TextButton113 = Instance.new("TextButton")
  139. ScrollingFrame114 = Instance.new("ScrollingFrame")
  140. Frame115 = Instance.new("Frame")
  141. TextLabel116 = Instance.new("TextLabel")
  142. TextLabel117 = Instance.new("TextLabel")
  143. TextLabel118 = Instance.new("TextLabel")
  144. Frame119 = Instance.new("Frame")
  145. TextLabel120 = Instance.new("TextLabel")
  146. Frame121 = Instance.new("Frame")
  147. Frame122 = Instance.new("Frame")
  148. Frame123 = Instance.new("Frame")
  149. TextButton124 = Instance.new("TextButton")
  150. LocalScript125 = Instance.new("LocalScript")
  151. TextButton126 = Instance.new("TextButton")
  152. LocalScript127 = Instance.new("LocalScript")
  153. TextButton128 = Instance.new("TextButton")
  154. ImageButton129 = Instance.new("ImageButton")
  155. Frame130 = Instance.new("Frame")
  156. Frame131 = Instance.new("Frame")
  157. Frame132 = Instance.new("Frame")
  158. Frame133 = Instance.new("Frame")
  159. Frame134 = Instance.new("Frame")
  160. ImageButton135 = Instance.new("ImageButton")
  161. Frame136 = Instance.new("Frame")
  162. Frame137 = Instance.new("Frame")
  163. Frame138 = Instance.new("Frame")
  164. Frame139 = Instance.new("Frame")
  165. Frame140 = Instance.new("Frame")
  166. Frame141 = Instance.new("Frame")
  167. Frame142 = Instance.new("Frame")
  168. TextButton143 = Instance.new("TextButton")
  169. TextButton144 = Instance.new("TextButton")
  170. BindableEvent145 = Instance.new("BindableEvent")
  171. LocalScript146 = Instance.new("LocalScript")
  172. TextButton147 = Instance.new("TextButton")
  173. Frame148 = Instance.new("Frame")
  174. ScrollingFrame149 = Instance.new("ScrollingFrame")
  175. TextBox150 = Instance.new("TextBox")
  176. Frame151 = Instance.new("Frame")
  177. Frame152 = Instance.new("Frame")
  178. ImageLabel153 = Instance.new("ImageLabel")
  179. TextLabel154 = Instance.new("TextLabel")
  180. TextLabel155 = Instance.new("TextLabel")
  181. TextLabel156 = Instance.new("TextLabel")
  182. ImageLabel157 = Instance.new("ImageLabel")
  183. TextLabel158 = Instance.new("TextLabel")
  184. ImageLabel159 = Instance.new("ImageLabel")
  185. Frame160 = Instance.new("Frame")
  186. Frame161 = Instance.new("Frame")
  187. TextLabel162 = Instance.new("TextLabel")
  188. Frame163 = Instance.new("Frame")
  189. Frame164 = Instance.new("Frame")
  190. TextLabel165 = Instance.new("TextLabel")
  191. TextLabel166 = Instance.new("TextLabel")
  192. TextButton167 = Instance.new("TextButton")
  193. TextLabel168 = Instance.new("TextLabel")
  194. TextLabel169 = Instance.new("TextLabel")
  195. Frame170 = Instance.new("Frame")
  196. TextLabel171 = Instance.new("TextLabel")
  197. TextLabel172 = Instance.new("TextLabel")
  198. TextButton173 = Instance.new("TextButton")
  199. TextLabel174 = Instance.new("TextLabel")
  200. TextLabel175 = Instance.new("TextLabel")
  201. Frame176 = Instance.new("Frame")
  202. TextLabel177 = Instance.new("TextLabel")
  203. TextLabel178 = Instance.new("TextLabel")
  204. TextButton179 = Instance.new("TextButton")
  205. TextLabel180 = Instance.new("TextLabel")
  206. TextLabel181 = Instance.new("TextLabel")
  207. Frame182 = Instance.new("Frame")
  208. TextLabel183 = Instance.new("TextLabel")
  209. TextLabel184 = Instance.new("TextLabel")
  210. TextButton185 = Instance.new("TextButton")
  211. TextLabel186 = Instance.new("TextLabel")
  212. TextLabel187 = Instance.new("TextLabel")
  213. TextLabel188 = Instance.new("TextLabel")
  214. Frame189 = Instance.new("Frame")
  215. Frame190 = Instance.new("Frame")
  216. TextLabel191 = Instance.new("TextLabel")
  217. TextButton192 = Instance.new("TextButton")
  218. TextBox193 = Instance.new("TextBox")
  219. Frame194 = Instance.new("Frame")
  220. TextButton195 = Instance.new("TextButton")
  221. TextLabel196 = Instance.new("TextLabel")
  222. TextLabel197 = Instance.new("TextLabel")
  223. Frame198 = Instance.new("Frame")
  224. Frame199 = Instance.new("Frame")
  225. TextLabel200 = Instance.new("TextLabel")
  226. BindableFunction201 = Instance.new("BindableFunction")
  227. TextLabel202 = Instance.new("TextLabel")
  228. TextButton203 = Instance.new("TextButton")
  229. RemoteFunction204 = Instance.new("RemoteFunction")
  230. Model205 = Instance.new("Model")
  231. Script206 = Instance.new("Script")
  232. Script207 = Instance.new("Script")
  233. Camera0.Parent = mas
  234. Camera0.CFrame = CFrame.new(1.30181932, 18.7109299, 21.3881245, -0.43208608, -0.624196768, 0.650907159, 1.4901163e-08, 0.72176075, 0.692142725, -0.901832461, 0.299065232, -0.311862707)
  235. Camera0.CoordinateFrame = CFrame.new(1.30181932, 18.7109299, 21.3881245, -0.43208608, -0.624196768, 0.650907159, 1.4901163e-08, 0.72176075, 0.692142725, -0.901832461, 0.299065232, -0.311862707)
  236. Camera0.Focus = CFrame.new(0, 17.3266392, 22.0118523, 1, 0, 0, 0, 1, 0, 0, 0, 1)
  237. Camera0.focus = CFrame.new(0, 17.3266392, 22.0118523, 1, 0, 0, 0, 1, 0, 0, 0, 1)
  238. Part1.Name = "Baseplate"
  239. Part1.Parent = mas
  240. Part1.CFrame = CFrame.new(0, -10, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)
  241. Part1.Position = Vector3.new(0, -10, 0)
  242. Part1.Color = Color3.new(0.388235, 0.372549, 0.384314)
  243. Part1.Size = Vector3.new(512, 20, 512)
  244. Part1.Anchored = true
  245. Part1.BrickColor = BrickColor.new("Dark stone grey")
  246. Part1.Locked = true
  247. Part1.brickColor = BrickColor.new("Dark stone grey")
  248. Part1.FormFactor = Enum.FormFactor.Symmetric
  249. Part1.formFactor = Enum.FormFactor.Symmetric
  250. Tool2.Name = "AstraDex"
  251. Tool2.Parent = mas
  252. Script3.Parent = Tool2
  253. table.insert(cors,sandbox(Script3,function()
  254. wait()
  255.  
  256. for i,v in pairs(script.Parent.ReplicatedStorage:GetChildren()) do
  257. if v:IsA("Instance") then
  258. if game.ReplicatedStorage:FindFirstChild(v.Name) == nil then
  259. v.Parent = game.ReplicatedStorage
  260. end
  261. end
  262. end
  263.  
  264. for i,v in pairs(script.Parent.ServerScriptService:GetChildren()) do
  265. if v:IsA("Script") then
  266. if game.ServerScriptService:FindFirstChild(v.Name) == nil then
  267. v.Parent = game.ServerScriptService
  268. pcall(function()
  269. wait()
  270. v.Disabled = false
  271. end)
  272. end
  273. end
  274. end
  275.  
  276. wait(1)
  277. script.Parent.Giver.Disabled = false
  278. end))
  279. Model4.Name = "ReplicatedStorage"
  280. Model4.Parent = Tool2
  281. RemoteEvent5.Name = "Change"
  282. RemoteEvent5.Parent = Model4
  283. RemoteEvent6.Name = "Function"
  284. RemoteEvent6.Parent = Model4
  285. RemoteEvent7.Name = "Instance"
  286. RemoteEvent7.Parent = Model4
  287. RemoteEvent8.Name = "DexScript"
  288. RemoteEvent8.Parent = Model4
  289. Model9.Name = "ServerScriptService"
  290. Model9.Parent = Tool2
  291. Script10.Name = "ChangeScript"
  292. Script10.Parent = Model9
  293. table.insert(cors,sandbox(Script10,function()
  294. wait()
  295.  
  296. game.ReplicatedStorage.Change.OnServerEvent:connect(function(player, object, property, data)
  297. pcall(function()
  298. object[property] = data
  299. pcall(function()
  300. print("Dex - Changed " .. object.Name .. " property " .. tostring(property) .. " to: " .. tostring(data))
  301. end)
  302. end)
  303. end)
  304. end))
  305. Script10.Disabled = true
  306. Script11.Name = "FunctionScript"
  307. Script11.Parent = Model9
  308. table.insert(cors,sandbox(Script11,function()
  309. wait()
  310.  
  311. local clipboard = {}
  312. local cut = {}
  313.  
  314. game.ReplicatedStorage.Function.OnServerEvent:Connect(function(player, action, args)
  315. --pcall(function()
  316. if action == "Clear" then
  317. clipboard = {}
  318. print("Dex - Cleared Clipboard!")
  319. end
  320. if action == "Delete" then
  321. args.Parent = nil
  322. pcall(function()
  323. print("Dex - Deleted Instance " .. args.Name .. "!")
  324. end)
  325. elseif action == "Copy" then
  326. local clone = args:Clone()
  327. clone.Parent = nil
  328. table.insert(clipboard,clone)
  329. pcall(function()
  330. print("Dex - Copied " .. clone.Name .. " to clipboard")
  331. end)
  332. elseif action == "Paste" then
  333. local parent = args
  334. for i = 1,#clipboard do
  335. clipboard[i]:Clone().Parent = parent
  336. pcall(function()
  337. print("Dex - Pasted " .. clipboard[i].Name .. " to " .. parent.Name)
  338. end)
  339. end
  340. elseif action == "Cut" then
  341. clipboard = {}
  342. local list = args
  343. local cut = {}
  344. for i = 1,#list do
  345. local obj = list[i]:Clone()
  346. if obj then
  347. pcall(function()
  348. print("Dex - Cutted " .. obj.Name .. " to clipboard")
  349. end)
  350. table.insert(clipboard,obj)
  351. table.insert(cut,list[i])
  352. end
  353. end
  354. for i = 1,#cut do
  355. cut[i].Parent = nil
  356. end
  357. elseif action == "Duplicate" then
  358. pcall(function()
  359. print("Dex - Duplicated " .. args[1])
  360. end)
  361. args[1]:Clone().Parent = args[2]
  362. elseif action == "Group" then
  363. pcall(function()
  364. print("Dex - Grouped Objects")
  365. end)
  366. local newModel = Instance.new("Model")
  367. local list = args[1]
  368. newModel.Parent = args[2]
  369. for i = 1,#list do
  370. list[i].Parent = newModel
  371. end
  372. elseif action == "Ungroup" then
  373. local ungrouped = {}
  374. local list = args
  375. for i = 1,#list do
  376. if list[i]:IsA("Model") then
  377. pcall(function()
  378. print("Dex - Ungrouped " .. list[i])
  379. end)
  380. for i2,v2 in pairs(list[i]:GetChildren()) do
  381. v2.Parent = list[i].Parent or workspace
  382. table.insert(ungrouped,v2)
  383. end
  384. list[i].Parent = nil
  385. end
  386. end
  387. end
  388. --end)
  389. end)
  390. end))
  391. Script11.Disabled = true
  392. Script12.Name = "InstanceScript"
  393. Script12.Parent = Model9
  394. table.insert(cors,sandbox(Script12,function()
  395. wait()
  396. local function invoke(player, ty, data)
  397. pcall(function()
  398. local lol = Instance.new(ty)
  399. lol.Parent = data
  400. end)
  401. end
  402.  
  403. game.ReplicatedStorage.Instance.OnServerEvent:connect(invoke)
  404. end))
  405. Script12.Disabled = true
  406. Script13.Name = "Execute"
  407. Script13.Parent = Model9
  408. table.insert(cors,sandbox(Script13,function()
  409. wait()
  410. local deps = script
  411.  
  412. AssignName=function()
  413. local name=math.random(100000,999999)
  414. return name
  415. end
  416.  
  417. game.ReplicatedStorage:WaitForChild("DexScript").OnServerEvent:connect(function(player, type, source)
  418. print("test")
  419. local ScriptType
  420. if type=='Script' then
  421. print("SCRIPT")
  422. ScriptType=deps.ScriptBase
  423. elseif type=='LocalScript' then
  424. ScriptType=deps.LocalScriptBase
  425. end
  426. if ScriptType then
  427. local cl=ScriptType:Clone()
  428. print("EXECUTE")
  429. cl.Name="Dex - "..type.." "..AssignName()
  430. local code=Instance.new('StringValue',cl)
  431. code.Name='Code'
  432. code.Value=source
  433. deps.Loadstring:Clone().Parent=cl
  434. if type=='Script' then
  435. cl.Parent = game.ServerScriptService
  436. cl.Disabled = false
  437. else
  438. cl.Parent = player.PlayerScripts
  439. cl.Disabled = false
  440. end
  441. end
  442. end)
  443. end))
  444. Script13.Disabled = true
  445. Script14.Name = "ScriptBase"
  446. Script14.Parent = Script13
  447. table.insert(cors,sandbox(Script14,function()
  448. wait()
  449. local parser=script:WaitForChild('Loadstring')
  450. local codeValue=script:WaitForChild('Code')
  451. local loadstring=require(parser)
  452. local code=codeValue.Value
  453. parser:Destroy()
  454. codeValue:Destroy()
  455. local func,error=loadstring(code,getfenv())
  456. if func then
  457. func()
  458. else
  459. print((error:match(".+:(.*)") or error))
  460. end
  461. end))
  462. Script14.Disabled = true
  463. ModuleScript15.Name = "Loadstring"
  464. ModuleScript15.Parent = Script13
  465. table.insert(cors,sandbox(ModuleScript15,function()
  466. --[[
  467. Credit to einsteinK.
  468. Credit to Stravant for LBI.
  469.  
  470. Credit to the creators of all the other modules used in this.
  471.  
  472. Sceleratis was here and decided modify some things.
  473. --]]
  474.  
  475. local waitDeps = {
  476. 'LBI';
  477. 'LuaK';
  478. 'LuaP';
  479. 'LuaU';
  480. 'LuaX';
  481. 'LuaY';
  482. 'LuaZ';
  483. }
  484.  
  485. for i,v in pairs(waitDeps) do script:WaitForChild(v) end
  486.  
  487. local luaX = require(script.LuaX)
  488. local luaY = require(script.LuaY)
  489. local luaZ = require(script.LuaZ)
  490. local luaU = require(script.LuaU)
  491. local lbi = require(script.LBI)
  492.  
  493. luaX:init()
  494. local LuaState = {}
  495.  
  496. return function(str,env)
  497. local f,writer,buff
  498. local ran,error=pcall(function()
  499. local zio = luaZ:init(luaZ:make_getS(str), nil)
  500. if not zio then return error() end
  501. local func = luaY:parser(LuaState, zio, nil, "@input")
  502. writer, buff = luaU:make_setS()
  503. luaU:dump(LuaState, func, writer, buff)
  504. f = lbi.load_bytecode(buff.data)
  505. if env then
  506. setfenv(f,env)
  507. else
  508. local env=getfenv()
  509. env.script=nil
  510. setfenv(f,env)
  511. end
  512. end)
  513. if ran then
  514. return f,buff.data
  515. else
  516. return nil,error
  517. end
  518. end
  519. end))
  520. ModuleScript16.Name = "LuaZ"
  521. ModuleScript16.Parent = ModuleScript15
  522. table.insert(cors,sandbox(ModuleScript16,function()
  523. --[[--------------------------------------------------------------------
  524.  
  525. lzio.lua
  526. Lua buffered streams in Lua
  527. This file is part of Yueliang.
  528.  
  529. Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
  530. The COPYRIGHT file describes the conditions
  531. under which this software may be distributed.
  532.  
  533. See the ChangeLog for more information.
  534.  
  535. ----------------------------------------------------------------------]]
  536.  
  537. --[[--------------------------------------------------------------------
  538. -- Notes:
  539. -- * EOZ is implemented as a string, "EOZ"
  540. -- * Format of z structure (ZIO)
  541. -- z.n -- bytes still unread
  542. -- z.p -- last read position position in buffer
  543. -- z.reader -- chunk reader function
  544. -- z.data -- additional data
  545. -- * Current position, p, is now last read index instead of a pointer
  546. --
  547. -- Not implemented:
  548. -- * luaZ_lookahead: used only in lapi.c:lua_load to detect binary chunk
  549. -- * luaZ_read: used only in lundump.c:ezread to read +1 bytes
  550. -- * luaZ_openspace: dropped; let Lua handle buffers as strings (used in
  551. -- lundump.c:LoadString & lvm.c:luaV_concat)
  552. -- * luaZ buffer macros: dropped; buffers are handled as strings
  553. -- * lauxlib.c:getF reader implementation has an extraline flag to
  554. -- skip over a shbang (#!) line, this is not implemented here
  555. --
  556. -- Added:
  557. -- (both of the following are vaguely adapted from lauxlib.c)
  558. -- * luaZ:make_getS: create Reader from a string
  559. -- * luaZ:make_getF: create Reader that reads from a file
  560. --
  561. -- Changed in 5.1.x:
  562. -- * Chunkreader renamed to Reader (ditto with Chunkwriter)
  563. -- * Zio struct: no more name string, added Lua state for reader
  564. -- (however, Yueliang readers do not require a Lua state)
  565. ----------------------------------------------------------------------]]
  566.  
  567. local luaZ = {}
  568.  
  569. ------------------------------------------------------------------------
  570. -- * reader() should return a string, or nil if nothing else to parse.
  571. -- Additional data can be set only during stream initialization
  572. -- * Readers are handled in lauxlib.c, see luaL_load(file|buffer|string)
  573. -- * LUAL_BUFFERSIZE=BUFSIZ=512 in make_getF() (located in luaconf.h)
  574. -- * Original Reader typedef:
  575. -- const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
  576. -- * This Lua chunk reader implementation:
  577. -- returns string or nil, no arguments to function
  578. ------------------------------------------------------------------------
  579.  
  580. ------------------------------------------------------------------------
  581. -- create a chunk reader from a source string
  582. ------------------------------------------------------------------------
  583. function luaZ:make_getS(buff)
  584. local b = buff
  585. return function() -- chunk reader anonymous function here
  586. if not b then return nil end
  587. local data = b
  588. b = nil
  589. return data
  590. end
  591. end
  592.  
  593. ------------------------------------------------------------------------
  594. -- create a chunk reader from a source file
  595. ------------------------------------------------------------------------
  596. --[[
  597. function luaZ:make_getF(filename)
  598. local LUAL_BUFFERSIZE = 512
  599. local h = io.open(filename, "r")
  600. if not h then return nil end
  601. return function() -- chunk reader anonymous function here
  602. if not h or io.type(h) == "closed file" then return nil end
  603. local buff = h:read(LUAL_BUFFERSIZE)
  604. if not buff then h:close(); h = nil end
  605. return buff
  606. end
  607. end
  608. --]]
  609. ------------------------------------------------------------------------
  610. -- creates a zio input stream
  611. -- returns the ZIO structure, z
  612. ------------------------------------------------------------------------
  613. function luaZ:init(reader, data, name)
  614. if not reader then return end
  615. local z = {}
  616. z.reader = reader
  617. z.data = data or ""
  618. z.name = name
  619. -- set up additional data for reading
  620. if not data or data == "" then z.n = 0 else z.n = #data end
  621. z.p = 0
  622. return z
  623. end
  624.  
  625. ------------------------------------------------------------------------
  626. -- fill up input buffer
  627. ------------------------------------------------------------------------
  628. function luaZ:fill(z)
  629. local buff = z.reader()
  630. z.data = buff
  631. if not buff or buff == "" then return "EOZ" end
  632. z.n, z.p = #buff - 1, 1
  633. return string.sub(buff, 1, 1)
  634. end
  635.  
  636. ------------------------------------------------------------------------
  637. -- get next character from the input stream
  638. -- * local n, p are used to optimize code generation
  639. ------------------------------------------------------------------------
  640. function luaZ:zgetc(z)
  641. local n, p = z.n, z.p + 1
  642. if n > 0 then
  643. z.n, z.p = n - 1, p
  644. return string.sub(z.data, p, p)
  645. else
  646. return self:fill(z)
  647. end
  648. end
  649.  
  650. return luaZ
  651. end))
  652. ModuleScript17.Name = "LuaX"
  653. ModuleScript17.Parent = ModuleScript15
  654. table.insert(cors,sandbox(ModuleScript17,function()
  655. --[[--------------------------------------------------------------------
  656.  
  657. llex.lua
  658. Lua lexical analyzer in Lua
  659. This file is part of Yueliang.
  660.  
  661. Copyright (c) 2005-2006 Kein-Hong Man <khman@users.sf.net>
  662. The COPYRIGHT file describes the conditions
  663. under which this software may be distributed.
  664.  
  665. See the ChangeLog for more information.
  666.  
  667. ----------------------------------------------------------------------]]
  668.  
  669. --[[--------------------------------------------------------------------
  670. -- Notes:
  671. -- * intended to 'imitate' llex.c code; performance is not a concern
  672. -- * tokens are strings; code structure largely retained
  673. -- * deleted stuff (compared to llex.c) are noted, comments retained
  674. -- * nextc() returns the currently read character to simplify coding
  675. -- here; next() in llex.c does not return anything
  676. -- * compatibility code is marked with "--#" comments
  677. --
  678. -- Added:
  679. -- * luaX:chunkid (function luaO_chunkid from lobject.c)
  680. -- * luaX:str2d (function luaO_str2d from lobject.c)
  681. -- * luaX.LUA_QS used in luaX:lexerror (from luaconf.h)
  682. -- * luaX.LUA_COMPAT_LSTR in luaX:read_long_string (from luaconf.h)
  683. -- * luaX.MAX_INT used in luaX:inclinenumber (from llimits.h)
  684. --
  685. -- To use the lexer:
  686. -- (1) luaX:init() to initialize the lexer
  687. -- (2) luaX:setinput() to set the input stream to lex
  688. -- (3) call luaX:next() or luaX:luaX:lookahead() to get tokens,
  689. -- until "TK_EOS": luaX:next()
  690. -- * since EOZ is returned as a string, be careful when regexp testing
  691. --
  692. -- Not implemented:
  693. -- * luaX_newstring: not required by this Lua implementation
  694. -- * buffer MAX_SIZET size limit (from llimits.h) test not implemented
  695. -- in the interest of performance
  696. -- * locale-aware number handling is largely redundant as Lua's
  697. -- tonumber() function is already capable of this
  698. --
  699. -- Changed in 5.1.x:
  700. -- * TK_NAME token order moved down
  701. -- * string representation for TK_NAME, TK_NUMBER, TK_STRING changed
  702. -- * token struct renamed to lower case (LS -> ls)
  703. -- * LexState struct: removed nestlevel, added decpoint
  704. -- * error message functions have been greatly simplified
  705. -- * token2string renamed to luaX_tokens, exposed in llex.h
  706. -- * lexer now handles all kinds of newlines, including CRLF
  707. -- * shbang first line handling removed from luaX:setinput;
  708. -- it is now done in lauxlib.c (luaL_loadfile)
  709. -- * next(ls) macro renamed to nextc(ls) due to new luaX_next function
  710. -- * EXTRABUFF and MAXNOCHECK removed due to lexer changes
  711. -- * checkbuffer(ls, len) macro deleted
  712. -- * luaX:read_numeral now has 3 support functions: luaX:trydecpoint,
  713. -- luaX:buffreplace and (luaO_str2d from lobject.c) luaX:str2d
  714. -- * luaX:read_numeral is now more promiscuous in slurping characters;
  715. -- hexadecimal numbers was added, locale-aware decimal points too
  716. -- * luaX:skip_sep is new; used by luaX:read_long_string
  717. -- * luaX:read_long_string handles new-style long blocks, with some
  718. -- optional compatibility code
  719. -- * luaX:llex: parts changed to support new-style long blocks
  720. -- * luaX:llex: readname functionality has been folded in
  721. -- * luaX:llex: removed test for control characters
  722. --
  723. --------------------------------------------------------------------]]
  724.  
  725. local luaZ = require(script.Parent.LuaZ)
  726.  
  727. local luaX = {}
  728.  
  729. -- FIRST_RESERVED is not required as tokens are manipulated as strings
  730. -- TOKEN_LEN deleted; maximum length of a reserved word not needed
  731.  
  732. ------------------------------------------------------------------------
  733. -- "ORDER RESERVED" deleted; enumeration in one place: luaX.RESERVED
  734. ------------------------------------------------------------------------
  735.  
  736. -- terminal symbols denoted by reserved words: TK_AND to TK_WHILE
  737. -- other terminal symbols: TK_NAME to TK_EOS
  738. luaX.RESERVED = [[
  739. TK_AND and
  740. TK_BREAK break
  741. TK_DO do
  742. TK_ELSE else
  743. TK_ELSEIF elseif
  744. TK_END end
  745. TK_FALSE false
  746. TK_FOR for
  747. TK_FUNCTION function
  748. TK_IF if
  749. TK_IN in
  750. TK_LOCAL local
  751. TK_NIL nil
  752. TK_NOT not
  753. TK_OR or
  754. TK_REPEAT repeat
  755. TK_RETURN return
  756. TK_THEN then
  757. TK_TRUE true
  758. TK_UNTIL until
  759. TK_WHILE while
  760. TK_CONCAT ..
  761. TK_DOTS ...
  762. TK_EQ ==
  763. TK_GE >=
  764. TK_LE <=
  765. TK_NE ~=
  766. TK_NAME <name>
  767. TK_NUMBER <number>
  768. TK_STRING <string>
  769. TK_EOS <eof>]]
  770.  
  771. -- NUM_RESERVED is not required; number of reserved words
  772.  
  773. --[[--------------------------------------------------------------------
  774. -- Instead of passing seminfo, the Token struct (e.g. ls.t) is passed
  775. -- so that lexer functions can use its table element, ls.t.seminfo
  776. --
  777. -- SemInfo (struct no longer needed, a mixed-type value is used)
  778. --
  779. -- Token (struct of ls.t and ls.lookahead):
  780. -- token -- token symbol
  781. -- seminfo -- semantics information
  782. --
  783. -- LexState (struct of ls; ls is initialized by luaX:setinput):
  784. -- current -- current character (charint)
  785. -- linenumber -- input line counter
  786. -- lastline -- line of last token 'consumed'
  787. -- t -- current token (table: struct Token)
  788. -- lookahead -- look ahead token (table: struct Token)
  789. -- fs -- 'FuncState' is private to the parser
  790. -- L -- LuaState
  791. -- z -- input stream
  792. -- buff -- buffer for tokens
  793. -- source -- current source name
  794. -- decpoint -- locale decimal point
  795. -- nestlevel -- level of nested non-terminals
  796. ----------------------------------------------------------------------]]
  797.  
  798. -- luaX.tokens (was luaX_tokens) is now a hash; see luaX:init
  799.  
  800. luaX.MAXSRC = 80
  801. luaX.MAX_INT = 2147483645 -- constants from elsewhere (see above)
  802. luaX.LUA_QS = "'%s'"
  803. luaX.LUA_COMPAT_LSTR = 1
  804. --luaX.MAX_SIZET = 4294967293
  805.  
  806. ------------------------------------------------------------------------
  807. -- initialize lexer
  808. -- * original luaX_init has code to create and register token strings
  809. -- * luaX.tokens: TK_* -> token
  810. -- * luaX.enums: token -> TK_* (used in luaX:llex)
  811. ------------------------------------------------------------------------
  812. function luaX:init()
  813. local tokens, enums = {}, {}
  814. for v in string.gmatch(self.RESERVED, "[^\n]+") do
  815. local _, _, tok, str = string.find(v, "(%S+)%s+(%S+)")
  816. tokens[tok] = str
  817. enums[str] = tok
  818. end
  819. self.tokens = tokens
  820. self.enums = enums
  821. end
  822.  
  823. ------------------------------------------------------------------------
  824. -- returns a suitably-formatted chunk name or id
  825. -- * from lobject.c, used in llex.c and ldebug.c
  826. -- * the result, out, is returned (was first argument)
  827. ------------------------------------------------------------------------
  828. function luaX:chunkid(source, bufflen)
  829. local out
  830. local first = string.sub(source, 1, 1)
  831. if first == "=" then
  832. out = string.sub(source, 2, bufflen) -- remove first char
  833. else -- out = "source", or "...source"
  834. if first == "@" then
  835. source = string.sub(source, 2) -- skip the '@'
  836. bufflen = bufflen - #" '...' "
  837. local l = #source
  838. out = ""
  839. if l > bufflen then
  840. source = string.sub(source, 1 + l - bufflen) -- get last part of file name
  841. out = out.."..."
  842. end
  843. out = out..source
  844. else -- out = [string "string"]
  845. local len = string.find(source, "[\n\r]") -- stop at first newline
  846. len = len and (len - 1) or #source
  847. bufflen = bufflen - #(" [string \"...\"] ")
  848. if len > bufflen then len = bufflen end
  849. out = "[string \""
  850. if len < #source then -- must truncate?
  851. out = out..string.sub(source, 1, len).."..."
  852. else
  853. out = out..source
  854. end
  855. out = out.."\"]"
  856. end
  857. end
  858. return out
  859. end
  860.  
  861. --[[--------------------------------------------------------------------
  862. -- Support functions for lexer
  863. -- * all lexer errors eventually reaches lexerror:
  864. syntaxerror -> lexerror
  865. ----------------------------------------------------------------------]]
  866.  
  867. ------------------------------------------------------------------------
  868. -- look up token and return keyword if found (also called by parser)
  869. ------------------------------------------------------------------------
  870. function luaX:token2str(ls, token)
  871. if string.sub(token, 1, 3) ~= "TK_" then
  872. if string.find(token, "%c") then
  873. return string.format("char(%d)", string.byte(token))
  874. end
  875. return token
  876. else
  877. end
  878. return self.tokens[token]
  879. end
  880.  
  881. ------------------------------------------------------------------------
  882. -- throws a lexer error
  883. -- * txtToken has been made local to luaX:lexerror
  884. -- * can't communicate LUA_ERRSYNTAX, so it is unimplemented
  885. ------------------------------------------------------------------------
  886. function luaX:lexerror(ls, msg, token)
  887. local function txtToken(ls, token)
  888. if token == "TK_NAME" or
  889. token == "TK_STRING" or
  890. token == "TK_NUMBER" then
  891. return ls.buff
  892. else
  893. return self:token2str(ls, token)
  894. end
  895. end
  896. local buff = self:chunkid(ls.source, self.MAXSRC)
  897. local msg = string.format("%s:%d: %s", buff, ls.linenumber, msg)
  898. if token then
  899. msg = string.format("%s near "..self.LUA_QS, msg, txtToken(ls, token))
  900. end
  901. -- luaD_throw(ls->L, LUA_ERRSYNTAX)
  902. error(msg)
  903. end
  904.  
  905. ------------------------------------------------------------------------
  906. -- throws a syntax error (mainly called by parser)
  907. -- * ls.t.token has to be set by the function calling luaX:llex
  908. -- (see luaX:next and luaX:lookahead elsewhere in this file)
  909. ------------------------------------------------------------------------
  910. function luaX:syntaxerror(ls, msg)
  911. self:lexerror(ls, msg, ls.t.token)
  912. end
  913.  
  914. ------------------------------------------------------------------------
  915. -- move on to next line
  916. ------------------------------------------------------------------------
  917. function luaX:currIsNewline(ls)
  918. return ls.current == "\n" or ls.current == "\r"
  919. end
  920.  
  921. function luaX:inclinenumber(ls)
  922. local old = ls.current
  923. -- lua_assert(currIsNewline(ls))
  924. self:nextc(ls) -- skip '\n' or '\r'
  925. if self:currIsNewline(ls) and ls.current ~= old then
  926. self:nextc(ls) -- skip '\n\r' or '\r\n'
  927. end
  928. ls.linenumber = ls.linenumber + 1
  929. if ls.linenumber >= self.MAX_INT then
  930. self:syntaxerror(ls, "chunk has too many lines")
  931. end
  932. end
  933.  
  934. ------------------------------------------------------------------------
  935. -- initializes an input stream for lexing
  936. -- * if ls (the lexer state) is passed as a table, then it is filled in,
  937. -- otherwise it has to be retrieved as a return value
  938. -- * LUA_MINBUFFER not used; buffer handling not required any more
  939. ------------------------------------------------------------------------
  940. function luaX:setinput(L, ls, z, source)
  941. if not ls then ls = {} end -- create struct
  942. if not ls.lookahead then ls.lookahead = {} end
  943. if not ls.t then ls.t = {} end
  944. ls.decpoint = "."
  945. ls.L = L
  946. ls.lookahead.token = "TK_EOS" -- no look-ahead token
  947. ls.z = z
  948. ls.fs = nil
  949. ls.linenumber = 1
  950. ls.lastline = 1
  951. ls.source = source
  952. self:nextc(ls) -- read first char
  953. end
  954.  
  955. --[[--------------------------------------------------------------------
  956. -- LEXICAL ANALYZER
  957. ----------------------------------------------------------------------]]
  958.  
  959. ------------------------------------------------------------------------
  960. -- checks if current character read is found in the set 'set'
  961. ------------------------------------------------------------------------
  962. function luaX:check_next(ls, set)
  963. if not string.find(set, ls.current, 1, 1) then
  964. return false
  965. end
  966. self:save_and_next(ls)
  967. return true
  968. end
  969.  
  970. ------------------------------------------------------------------------
  971. -- retrieve next token, checking the lookahead buffer if necessary
  972. -- * note that the macro next(ls) in llex.c is now luaX:nextc
  973. -- * utilized used in lparser.c (various places)
  974. ------------------------------------------------------------------------
  975. function luaX:next(ls)
  976. ls.lastline = ls.linenumber
  977. if ls.lookahead.token ~= "TK_EOS" then -- is there a look-ahead token?
  978. -- this must be copy-by-value
  979. ls.t.seminfo = ls.lookahead.seminfo -- use this one
  980. ls.t.token = ls.lookahead.token
  981. ls.lookahead.token = "TK_EOS" -- and discharge it
  982. else
  983. ls.t.token = self:llex(ls, ls.t) -- read next token
  984. end
  985. end
  986.  
  987. ------------------------------------------------------------------------
  988. -- fill in the lookahead buffer
  989. -- * utilized used in lparser.c:constructor
  990. ------------------------------------------------------------------------
  991. function luaX:lookahead(ls)
  992. -- lua_assert(ls.lookahead.token == "TK_EOS")
  993. ls.lookahead.token = self:llex(ls, ls.lookahead)
  994. end
  995.  
  996. ------------------------------------------------------------------------
  997. -- gets the next character and returns it
  998. -- * this is the next() macro in llex.c; see notes at the beginning
  999. ------------------------------------------------------------------------
  1000. function luaX:nextc(ls)
  1001. local c = luaZ:zgetc(ls.z)
  1002. ls.current = c
  1003. return c
  1004. end
  1005.  
  1006. ------------------------------------------------------------------------
  1007. -- saves the given character into the token buffer
  1008. -- * buffer handling code removed, not used in this implementation
  1009. -- * test for maximum token buffer length not used, makes things faster
  1010. ------------------------------------------------------------------------
  1011.  
  1012. function luaX:save(ls, c)
  1013. local buff = ls.buff
  1014. -- if you want to use this, please uncomment luaX.MAX_SIZET further up
  1015. --if #buff > self.MAX_SIZET then
  1016. -- self:lexerror(ls, "lexical element too long")
  1017. --end
  1018. ls.buff = buff..c
  1019. end
  1020.  
  1021. ------------------------------------------------------------------------
  1022. -- save current character into token buffer, grabs next character
  1023. -- * like luaX:nextc, returns the character read for convenience
  1024. ------------------------------------------------------------------------
  1025. function luaX:save_and_next(ls)
  1026. self:save(ls, ls.current)
  1027. return self:nextc(ls)
  1028. end
  1029.  
  1030. ------------------------------------------------------------------------
  1031. -- LUA_NUMBER
  1032. -- * luaX:read_numeral is the main lexer function to read a number
  1033. -- * luaX:str2d, luaX:buffreplace, luaX:trydecpoint are support functions
  1034. ------------------------------------------------------------------------
  1035.  
  1036. ------------------------------------------------------------------------
  1037. -- string to number converter (was luaO_str2d from lobject.c)
  1038. -- * returns the number, nil if fails (originally returns a boolean)
  1039. -- * conversion function originally lua_str2number(s,p), a macro which
  1040. -- maps to the strtod() function by default (from luaconf.h)
  1041. ------------------------------------------------------------------------
  1042. function luaX:str2d(s)
  1043. local result = tonumber(s)
  1044. if result then return result end
  1045. -- conversion failed
  1046. if string.lower(string.sub(s, 1, 2)) == "0x" then -- maybe an hexadecimal constant?
  1047. result = tonumber(s, 16)
  1048. if result then return result end -- most common case
  1049. -- Was: invalid trailing characters?
  1050. -- In C, this function then skips over trailing spaces.
  1051. -- true is returned if nothing else is found except for spaces.
  1052. -- If there is still something else, then it returns a false.
  1053. -- All this is not necessary using Lua's tonumber.
  1054. end
  1055. return nil
  1056. end
  1057.  
  1058. ------------------------------------------------------------------------
  1059. -- single-character replacement, for locale-aware decimal points
  1060. ------------------------------------------------------------------------
  1061. function luaX:buffreplace(ls, from, to)
  1062. local result, buff = "", ls.buff
  1063. for p = 1, #buff do
  1064. local c = string.sub(buff, p, p)
  1065. if c == from then c = to end
  1066. result = result..c
  1067. end
  1068. ls.buff = result
  1069. end
  1070.  
  1071. ------------------------------------------------------------------------
  1072. -- Attempt to convert a number by translating '.' decimal points to
  1073. -- the decimal point character used by the current locale. This is not
  1074. -- needed in Yueliang as Lua's tonumber() is already locale-aware.
  1075. -- Instead, the code is here in case the user implements localeconv().
  1076. ------------------------------------------------------------------------
  1077. function luaX:trydecpoint(ls, Token)
  1078. -- format error: try to update decimal point separator
  1079. local old = ls.decpoint
  1080. -- translate the following to Lua if you implement localeconv():
  1081. -- struct lconv *cv = localeconv();
  1082. -- ls->decpoint = (cv ? cv->decimal_point[0] : '.');
  1083. self:buffreplace(ls, old, ls.decpoint) -- try updated decimal separator
  1084. local seminfo = self:str2d(ls.buff)
  1085. Token.seminfo = seminfo
  1086. if not seminfo then
  1087. -- format error with correct decimal point: no more options
  1088. self:buffreplace(ls, ls.decpoint, ".") -- undo change (for error message)
  1089. self:lexerror(ls, "malformed number", "TK_NUMBER")
  1090. end
  1091. end
  1092.  
  1093. ------------------------------------------------------------------------
  1094. -- main number conversion function
  1095. -- * "^%w$" needed in the scan in order to detect "EOZ"
  1096. ------------------------------------------------------------------------
  1097. function luaX:read_numeral(ls, Token)
  1098. -- lua_assert(string.find(ls.current, "%d"))
  1099. repeat
  1100. self:save_and_next(ls)
  1101. until string.find(ls.current, "%D") and ls.current ~= "."
  1102. if self:check_next(ls, "Ee") then -- 'E'?
  1103. self:check_next(ls, "+-") -- optional exponent sign
  1104. end
  1105. while string.find(ls.current, "^%w$") or ls.current == "_" do
  1106. self:save_and_next(ls)
  1107. end
  1108. self:buffreplace(ls, ".", ls.decpoint) -- follow locale for decimal point
  1109. local seminfo = self:str2d(ls.buff)
  1110. Token.seminfo = seminfo
  1111. if not seminfo then -- format error?
  1112. self:trydecpoint(ls, Token) -- try to update decimal point separator
  1113. end
  1114. end
  1115.  
  1116. ------------------------------------------------------------------------
  1117. -- count separators ("=") in a long string delimiter
  1118. -- * used by luaX:read_long_string
  1119. ------------------------------------------------------------------------
  1120. function luaX:skip_sep(ls)
  1121. local count = 0
  1122. local s = ls.current
  1123. -- lua_assert(s == "[" or s == "]")
  1124. self:save_and_next(ls)
  1125. while ls.current == "=" do
  1126. self:save_and_next(ls)
  1127. count = count + 1
  1128. end
  1129. return (ls.current == s) and count or (-count) - 1
  1130. end
  1131.  
  1132. ------------------------------------------------------------------------
  1133. -- reads a long string or long comment
  1134. ------------------------------------------------------------------------
  1135. function luaX:read_long_string(ls, Token, sep)
  1136. local cont = 0
  1137. self:save_and_next(ls) -- skip 2nd '['
  1138. if self:currIsNewline(ls) then -- string starts with a newline?
  1139. self:inclinenumber(ls) -- skip it
  1140. end
  1141. while true do
  1142. local c = ls.current
  1143. if c == "EOZ" then
  1144. self:lexerror(ls, Token and "unfinished long string" or
  1145. "unfinished long comment", "TK_EOS")
  1146. elseif c == "[" then
  1147. --# compatibility code start
  1148. if self.LUA_COMPAT_LSTR then
  1149. if self:skip_sep(ls) == sep then
  1150. self:save_and_next(ls) -- skip 2nd '['
  1151. cont = cont + 1
  1152. --# compatibility code start
  1153. if self.LUA_COMPAT_LSTR == 1 then
  1154. if sep == 0 then
  1155. self:lexerror(ls, "nesting of [[...]] is deprecated", "[")
  1156. end
  1157. end
  1158. --# compatibility code end
  1159. end
  1160. end
  1161. --# compatibility code end
  1162. elseif c == "]" then
  1163. if self:skip_sep(ls) == sep then
  1164. self:save_and_next(ls) -- skip 2nd ']'
  1165. --# compatibility code start
  1166. if self.LUA_COMPAT_LSTR and self.LUA_COMPAT_LSTR == 2 then
  1167. cont = cont - 1
  1168. if sep == 0 and cont >= 0 then break end
  1169. end
  1170. --# compatibility code end
  1171. break
  1172. end
  1173. elseif self:currIsNewline(ls) then
  1174. self:save(ls, "\n")
  1175. self:inclinenumber(ls)
  1176. if not Token then ls.buff = "" end -- avoid wasting space
  1177. else -- default
  1178. if Token then
  1179. self:save_and_next(ls)
  1180. else
  1181. self:nextc(ls)
  1182. end
  1183. end--if c
  1184. end--while
  1185. if Token then
  1186. local p = 3 + sep
  1187. Token.seminfo = string.sub(ls.buff, p, -p)
  1188. end
  1189. end
  1190.  
  1191. ------------------------------------------------------------------------
  1192. -- reads a string
  1193. -- * has been restructured significantly compared to the original C code
  1194. ------------------------------------------------------------------------
  1195.  
  1196. function luaX:read_string(ls, del, Token)
  1197. self:save_and_next(ls)
  1198. while ls.current ~= del do
  1199. local c = ls.current
  1200. if c == "EOZ" then
  1201. self:lexerror(ls, "unfinished string", "TK_EOS")
  1202. elseif self:currIsNewline(ls) then
  1203. self:lexerror(ls, "unfinished string", "TK_STRING")
  1204. elseif c == "\\" then
  1205. c = self:nextc(ls) -- do not save the '\'
  1206. if self:currIsNewline(ls) then -- go through
  1207. self:save(ls, "\n")
  1208. self:inclinenumber(ls)
  1209. elseif c ~= "EOZ" then -- will raise an error next loop
  1210. -- escapes handling greatly simplified here:
  1211. local i = string.find("abfnrtv", c, 1, 1)
  1212. if i then
  1213. self:save(ls, string.sub("\a\b\f\n\r\t\v", i, i))
  1214. self:nextc(ls)
  1215. elseif not string.find(c, "%d") then
  1216. self:save_and_next(ls) -- handles \\, \", \', and \?
  1217. else -- \xxx
  1218. c, i = 0, 0
  1219. repeat
  1220. c = 10 * c + ls.current
  1221. self:nextc(ls)
  1222. i = i + 1
  1223. until i >= 3 or not string.find(ls.current, "%d")
  1224. if c > 255 then -- UCHAR_MAX
  1225. self:lexerror(ls, "escape sequence too large", "TK_STRING")
  1226. end
  1227. self:save(ls, string.char(c))
  1228. end
  1229. end
  1230. else
  1231. self:save_and_next(ls)
  1232. end--if c
  1233. end--while
  1234. self:save_and_next(ls) -- skip delimiter
  1235. Token.seminfo = string.sub(ls.buff, 2, -2)
  1236. end
  1237.  
  1238. ------------------------------------------------------------------------
  1239. -- main lexer function
  1240. ------------------------------------------------------------------------
  1241. function luaX:llex(ls, Token)
  1242. ls.buff = ""
  1243. while true do
  1244. local c = ls.current
  1245. ----------------------------------------------------------------
  1246. if self:currIsNewline(ls) then
  1247. self:inclinenumber(ls)
  1248. ----------------------------------------------------------------
  1249. elseif c == "-" then
  1250. c = self:nextc(ls)
  1251. if c ~= "-" then return "-" end
  1252. -- else is a comment
  1253. local sep = -1
  1254. if self:nextc(ls) == '[' then
  1255. sep = self:skip_sep(ls)
  1256. ls.buff = "" -- 'skip_sep' may dirty the buffer
  1257. end
  1258. if sep >= 0 then
  1259. self:read_long_string(ls, nil, sep) -- long comment
  1260. ls.buff = ""
  1261. else -- else short comment
  1262. while not self:currIsNewline(ls) and ls.current ~= "EOZ" do
  1263. self:nextc(ls)
  1264. end
  1265. end
  1266. ----------------------------------------------------------------
  1267. elseif c == "[" then
  1268. local sep = self:skip_sep(ls)
  1269. if sep >= 0 then
  1270. self:read_long_string(ls, Token, sep)
  1271. return "TK_STRING"
  1272. elseif sep == -1 then
  1273. return "["
  1274. else
  1275. self:lexerror(ls, "invalid long string delimiter", "TK_STRING")
  1276. end
  1277. ----------------------------------------------------------------
  1278. elseif c == "=" then
  1279. c = self:nextc(ls)
  1280. if c ~= "=" then return "="
  1281. else self:nextc(ls); return "TK_EQ" end
  1282. ----------------------------------------------------------------
  1283. elseif c == "<" then
  1284. c = self:nextc(ls)
  1285. if c ~= "=" then return "<"
  1286. else self:nextc(ls); return "TK_LE" end
  1287. ----------------------------------------------------------------
  1288. elseif c == ">" then
  1289. c = self:nextc(ls)
  1290. if c ~= "=" then return ">"
  1291. else self:nextc(ls); return "TK_GE" end
  1292. ----------------------------------------------------------------
  1293. elseif c == "~" then
  1294. c = self:nextc(ls)
  1295. if c ~= "=" then return "~"
  1296. else self:nextc(ls); return "TK_NE" end
  1297. ----------------------------------------------------------------
  1298. elseif c == "\"" or c == "'" then
  1299. self:read_string(ls, c, Token)
  1300. return "TK_STRING"
  1301. ----------------------------------------------------------------
  1302. elseif c == "." then
  1303. c = self:save_and_next(ls)
  1304. if self:check_next(ls, ".") then
  1305. if self:check_next(ls, ".") then
  1306. return "TK_DOTS" -- ...
  1307. else return "TK_CONCAT" -- ..
  1308. end
  1309. elseif not string.find(c, "%d") then
  1310. return "."
  1311. else
  1312. self:read_numeral(ls, Token)
  1313. return "TK_NUMBER"
  1314. end
  1315. ----------------------------------------------------------------
  1316. elseif c == "EOZ" then
  1317. return "TK_EOS"
  1318. ----------------------------------------------------------------
  1319. else -- default
  1320. if string.find(c, "%s") then
  1321. -- lua_assert(self:currIsNewline(ls))
  1322. self:nextc(ls)
  1323. elseif string.find(c, "%d") then
  1324. self:read_numeral(ls, Token)
  1325. return "TK_NUMBER"
  1326. elseif string.find(c, "[_%a]") then
  1327. -- identifier or reserved word
  1328. repeat
  1329. c = self:save_and_next(ls)
  1330. until c == "EOZ" or not string.find(c, "[_%w]")
  1331. local ts = ls.buff
  1332. local tok = self.enums[ts]
  1333. if tok then return tok end -- reserved word?
  1334. Token.seminfo = ts
  1335. return "TK_NAME"
  1336. else
  1337. self:nextc(ls)
  1338. return c -- single-char tokens (+ - / ...)
  1339. end
  1340. ----------------------------------------------------------------
  1341. end--if c
  1342. end--while
  1343. end
  1344.  
  1345. return luaX
  1346. end))
  1347. ModuleScript18.Name = "LuaY"
  1348. ModuleScript18.Parent = ModuleScript15
  1349. table.insert(cors,sandbox(ModuleScript18,function()
  1350. --[[--------------------------------------------------------------------
  1351.  
  1352. lparser.lua
  1353. Lua 5 parser in Lua
  1354. This file is part of Yueliang.
  1355.  
  1356. Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
  1357. The COPYRIGHT file describes the conditions
  1358. under which this software may be distributed.
  1359.  
  1360. See the ChangeLog for more information.
  1361.  
  1362. ----------------------------------------------------------------------]]
  1363.  
  1364. --[[--------------------------------------------------------------------
  1365. -- Notes:
  1366. -- * some unused C code that were not converted are kept as comments
  1367. -- * LUA_COMPAT_VARARG option changed into a comment block
  1368. -- * for value/size specific code added, look for 'NOTE: '
  1369. --
  1370. -- Not implemented:
  1371. -- * luaX_newstring not needed by this Lua implementation
  1372. -- * luaG_checkcode() in assert is not currently implemented
  1373. --
  1374. -- Added:
  1375. -- * some constants added from various header files
  1376. -- * luaY.LUA_QS used in error_expected, check_match (from luaconf.h)
  1377. -- * luaY:LUA_QL needed for error messages (from luaconf.h)
  1378. -- * luaY:growvector (from lmem.h) -- skeleton only, limit checking
  1379. -- * luaY.SHRT_MAX (from <limits.h>) for registerlocalvar
  1380. -- * luaY:newproto (from lfunc.c)
  1381. -- * luaY:int2fb (from lobject.c)
  1382. -- * NOTE: HASARG_MASK, for implementing a VARARG_HASARG bit operation
  1383. -- * NOTE: value-specific code for VARARG_NEEDSARG to replace a bitop
  1384. --
  1385. -- Changed in 5.1.x:
  1386. -- * various code changes are not detailed...
  1387. -- * names of constants may have changed, e.g. added a LUAI_ prefix
  1388. -- * struct expkind: added VKNUM, VVARARG; VCALL's info changed?
  1389. -- * struct expdesc: added nval
  1390. -- * struct FuncState: upvalues data type changed to upvaldesc
  1391. -- * macro hasmultret is new
  1392. -- * function checklimit moved to parser from lexer
  1393. -- * functions anchor_token, errorlimit, checknext are new
  1394. -- * checknext is new, equivalent to 5.0.x's check, see check too
  1395. -- * luaY:next and luaY:lookahead moved to lexer
  1396. -- * break keyword no longer skipped in luaY:breakstat
  1397. -- * function new_localvarstr replaced by new_localvarliteral
  1398. -- * registerlocalvar limits local variables to SHRT_MAX
  1399. -- * create_local deleted, new_localvarliteral used instead
  1400. -- * constant LUAI_MAXUPVALUES increased to 60
  1401. -- * constants MAXPARAMS, LUA_MAXPARSERLEVEL, MAXSTACK removed
  1402. -- * function interface changed: singlevaraux, singlevar
  1403. -- * enterlevel and leavelevel uses nCcalls to track call depth
  1404. -- * added a name argument to main entry function, luaY:parser
  1405. -- * function luaY_index changed to yindex
  1406. -- * luaY:int2fb()'s table size encoding format has been changed
  1407. -- * luaY:log2() no longer needed for table constructors
  1408. -- * function code_params deleted, functionality folded in parlist
  1409. -- * vararg flags handling (is_vararg) changes; also see VARARG_*
  1410. -- * LUA_COMPATUPSYNTAX section for old-style upvalues removed
  1411. -- * repeatstat() calls chunk() instead of block()
  1412. -- * function interface changed: cond, test_then_block
  1413. -- * while statement implementation considerably simplified; MAXEXPWHILE
  1414. -- and EXTRAEXP no longer required, no limits to the complexity of a
  1415. -- while condition
  1416. -- * repeat, forbody statement implementation has major changes,
  1417. -- mostly due to new scoping behaviour of local variables
  1418. -- * OPR_MULT renamed to OPR_MUL
  1419. ----------------------------------------------------------------------]]
  1420.  
  1421. --requires luaP, luaX, luaK
  1422. local luaY = {}
  1423. local luaX = require(script.Parent.LuaX)
  1424. local luaK = require(script.Parent.LuaK)(luaY)
  1425. local luaP = require(script.Parent.LuaP)
  1426.  
  1427. --[[--------------------------------------------------------------------
  1428. -- Expression descriptor
  1429. -- * expkind changed to string constants; luaY:assignment was the only
  1430. -- function to use a relational operator with this enumeration
  1431. -- VVOID -- no value
  1432. -- VNIL -- no value
  1433. -- VTRUE -- no value
  1434. -- VFALSE -- no value
  1435. -- VK -- info = index of constant in 'k'
  1436. -- VKNUM -- nval = numerical value
  1437. -- VLOCAL -- info = local register
  1438. -- VUPVAL, -- info = index of upvalue in 'upvalues'
  1439. -- VGLOBAL -- info = index of table; aux = index of global name in 'k'
  1440. -- VINDEXED -- info = table register; aux = index register (or 'k')
  1441. -- VJMP -- info = instruction pc
  1442. -- VRELOCABLE -- info = instruction pc
  1443. -- VNONRELOC -- info = result register
  1444. -- VCALL -- info = instruction pc
  1445. -- VVARARG -- info = instruction pc
  1446. } ----------------------------------------------------------------------]]
  1447.  
  1448. --[[--------------------------------------------------------------------
  1449. -- * expdesc in Lua 5.1.x has a union u and another struct s; this Lua
  1450. -- implementation ignores all instances of u and s usage
  1451. -- struct expdesc:
  1452. -- k -- (enum: expkind)
  1453. -- info, aux -- (int, int)
  1454. -- nval -- (lua_Number)
  1455. -- t -- patch list of 'exit when true'
  1456. -- f -- patch list of 'exit when false'
  1457. ----------------------------------------------------------------------]]
  1458.  
  1459. --[[--------------------------------------------------------------------
  1460. -- struct upvaldesc:
  1461. -- k -- (lu_byte)
  1462. -- info -- (lu_byte)
  1463. ----------------------------------------------------------------------]]
  1464.  
  1465. --[[--------------------------------------------------------------------
  1466. -- state needed to generate code for a given function
  1467. -- struct FuncState:
  1468. -- f -- current function header (table: Proto)
  1469. -- h -- table to find (and reuse) elements in 'k' (table: Table)
  1470. -- prev -- enclosing function (table: FuncState)
  1471. -- ls -- lexical state (table: LexState)
  1472. -- L -- copy of the Lua state (table: lua_State)
  1473. -- bl -- chain of current blocks (table: BlockCnt)
  1474. -- pc -- next position to code (equivalent to 'ncode')
  1475. -- lasttarget -- 'pc' of last 'jump target'
  1476. -- jpc -- list of pending jumps to 'pc'
  1477. -- freereg -- first free register
  1478. -- nk -- number of elements in 'k'
  1479. -- np -- number of elements in 'p'
  1480. -- nlocvars -- number of elements in 'locvars'
  1481. -- nactvar -- number of active local variables
  1482. -- upvalues[LUAI_MAXUPVALUES] -- upvalues (table: upvaldesc)
  1483. -- actvar[LUAI_MAXVARS] -- declared-variable stack
  1484. ----------------------------------------------------------------------]]
  1485.  
  1486. ------------------------------------------------------------------------
  1487. -- constants used by parser
  1488. -- * picks up duplicate values from luaX if required
  1489. ------------------------------------------------------------------------
  1490.  
  1491. luaY.LUA_QS = luaX.LUA_QS or "'%s'" -- (from luaconf.h)
  1492.  
  1493. luaY.SHRT_MAX = 32767 -- (from <limits.h>)
  1494. luaY.LUAI_MAXVARS = 200 -- (luaconf.h)
  1495. luaY.LUAI_MAXUPVALUES = 60 -- (luaconf.h)
  1496. luaY.MAX_INT = luaX.MAX_INT or 2147483645 -- (from llimits.h)
  1497. -- * INT_MAX-2 for 32-bit systems
  1498. luaY.LUAI_MAXCCALLS = 200 -- (from luaconf.h)
  1499.  
  1500. luaY.VARARG_HASARG = 1 -- (from lobject.h)
  1501. -- NOTE: HASARG_MASK is value-specific
  1502. luaY.HASARG_MASK = 2 -- this was added for a bitop in parlist()
  1503. luaY.VARARG_ISVARARG = 2
  1504. -- NOTE: there is some value-specific code that involves VARARG_NEEDSARG
  1505. luaY.VARARG_NEEDSARG = 4
  1506.  
  1507. luaY.LUA_MULTRET = -1 -- (lua.h)
  1508.  
  1509. --[[--------------------------------------------------------------------
  1510. -- other functions
  1511. ----------------------------------------------------------------------]]
  1512.  
  1513. ------------------------------------------------------------------------
  1514. -- LUA_QL describes how error messages quote program elements.
  1515. -- CHANGE it if you want a different appearance. (from luaconf.h)
  1516. ------------------------------------------------------------------------
  1517. function luaY:LUA_QL(x)
  1518. return "'"..x.."'"
  1519. end
  1520.  
  1521. ------------------------------------------------------------------------
  1522. -- this is a stripped-down luaM_growvector (from lmem.h) which is a
  1523. -- macro based on luaM_growaux (in lmem.c); all the following does is
  1524. -- reproduce the size limit checking logic of the original function
  1525. -- so that error behaviour is identical; all arguments preserved for
  1526. -- convenience, even those which are unused
  1527. -- * set the t field to nil, since this originally does a sizeof(t)
  1528. -- * size (originally a pointer) is never updated, their final values
  1529. -- are set by luaY:close_func(), so overall things should still work
  1530. ------------------------------------------------------------------------
  1531. function luaY:growvector(L, v, nelems, size, t, limit, e)
  1532. if nelems >= limit then
  1533. error(e) -- was luaG_runerror
  1534. end
  1535. end
  1536.  
  1537. ------------------------------------------------------------------------
  1538. -- initialize a new function prototype structure (from lfunc.c)
  1539. -- * used only in open_func()
  1540. ------------------------------------------------------------------------
  1541. function luaY:newproto(L)
  1542. local f = {} -- Proto
  1543. -- luaC_link(L, obj2gco(f), LUA_TPROTO); /* GC */
  1544. f.k = {}
  1545. f.sizek = 0
  1546. f.p = {}
  1547. f.sizep = 0
  1548. f.code = {}
  1549. f.sizecode = 0
  1550. f.sizelineinfo = 0
  1551. f.sizeupvalues = 0
  1552. f.nups = 0
  1553. f.upvalues = {}
  1554. f.numparams = 0
  1555. f.is_vararg = 0
  1556. f.maxstacksize = 0
  1557. f.lineinfo = {}
  1558. f.sizelocvars = 0
  1559. f.locvars = {}
  1560. f.lineDefined = 0
  1561. f.lastlinedefined = 0
  1562. f.source = nil
  1563. return f
  1564. end
  1565.  
  1566. ------------------------------------------------------------------------
  1567. -- converts an integer to a "floating point byte", represented as
  1568. -- (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
  1569. -- eeeee != 0 and (xxx) otherwise.
  1570. ------------------------------------------------------------------------
  1571. function luaY:int2fb(x)
  1572. local e = 0 -- exponent
  1573. while x >= 16 do
  1574. x = math.floor((x + 1) / 2)
  1575. e = e + 1
  1576. end
  1577. if x < 8 then
  1578. return x
  1579. else
  1580. return ((e + 1) * 8) + (x - 8)
  1581. end
  1582. end
  1583.  
  1584. --[[--------------------------------------------------------------------
  1585. -- parser functions
  1586. ----------------------------------------------------------------------]]
  1587.  
  1588. ------------------------------------------------------------------------
  1589. -- true of the kind of expression produces multiple return values
  1590. ------------------------------------------------------------------------
  1591. function luaY:hasmultret(k)
  1592. return k == "VCALL" or k == "VVARARG"
  1593. end
  1594.  
  1595. ------------------------------------------------------------------------
  1596. -- convenience function to access active local i, returns entry
  1597. ------------------------------------------------------------------------
  1598. function luaY:getlocvar(fs, i)
  1599. return fs.f.locvars[ fs.actvar[i] ]
  1600. end
  1601.  
  1602. ------------------------------------------------------------------------
  1603. -- check a limit, string m provided as an error message
  1604. ------------------------------------------------------------------------
  1605. function luaY:checklimit(fs, v, l, m)
  1606. if v > l then self:errorlimit(fs, l, m) end
  1607. end
  1608.  
  1609. --[[--------------------------------------------------------------------
  1610. -- nodes for block list (list of active blocks)
  1611. -- struct BlockCnt:
  1612. -- previous -- chain (table: BlockCnt)
  1613. -- breaklist -- list of jumps out of this loop
  1614. -- nactvar -- # active local variables outside the breakable structure
  1615. -- upval -- true if some variable in the block is an upvalue (boolean)
  1616. -- isbreakable -- true if 'block' is a loop (boolean)
  1617. ----------------------------------------------------------------------]]
  1618.  
  1619. ------------------------------------------------------------------------
  1620. -- prototypes for recursive non-terminal functions
  1621. ------------------------------------------------------------------------
  1622. -- prototypes deleted; not required in Lua
  1623.  
  1624. ------------------------------------------------------------------------
  1625. -- reanchor if last token is has a constant string, see close_func()
  1626. -- * used only in close_func()
  1627. ------------------------------------------------------------------------
  1628. function luaY:anchor_token(ls)
  1629. if ls.t.token == "TK_NAME" or ls.t.token == "TK_STRING" then
  1630. -- not relevant to Lua implementation of parser
  1631. -- local ts = ls.t.seminfo
  1632. -- luaX_newstring(ls, getstr(ts), ts->tsv.len); /* C */
  1633. end
  1634. end
  1635.  
  1636. ------------------------------------------------------------------------
  1637. -- throws a syntax error if token expected is not there
  1638. ------------------------------------------------------------------------
  1639. function luaY:error_expected(ls, token)
  1640. luaX:syntaxerror(ls,
  1641. string.format(self.LUA_QS.." expected", luaX:token2str(ls, token)))
  1642. end
  1643.  
  1644. ------------------------------------------------------------------------
  1645. -- prepares error message for display, for limits exceeded
  1646. -- * used only in checklimit()
  1647. ------------------------------------------------------------------------
  1648. function luaY:errorlimit(fs, limit, what)
  1649. local msg = (fs.f.linedefined == 0) and
  1650. string.format("main function has more than %d %s", limit, what) or
  1651. string.format("function at line %d has more than %d %s",
  1652. fs.f.linedefined, limit, what)
  1653. luaX:lexerror(fs.ls, msg, 0)
  1654. end
  1655.  
  1656. ------------------------------------------------------------------------
  1657. -- tests for a token, returns outcome
  1658. -- * return value changed to boolean
  1659. ------------------------------------------------------------------------
  1660. function luaY:testnext(ls, c)
  1661. if ls.t.token == c then
  1662. luaX:next(ls)
  1663. return true
  1664. else
  1665. return false
  1666. end
  1667. end
  1668.  
  1669. ------------------------------------------------------------------------
  1670. -- check for existence of a token, throws error if not found
  1671. ------------------------------------------------------------------------
  1672. function luaY:check(ls, c)
  1673. if ls.t.token ~= c then
  1674. self:error_expected(ls, c)
  1675. end
  1676. end
  1677.  
  1678. ------------------------------------------------------------------------
  1679. -- verify existence of a token, then skip it
  1680. ------------------------------------------------------------------------
  1681. function luaY:checknext(ls, c)
  1682. self:check(ls, c)
  1683. luaX:next(ls)
  1684. end
  1685.  
  1686. ------------------------------------------------------------------------
  1687. -- throws error if condition not matched
  1688. ------------------------------------------------------------------------
  1689. function luaY:check_condition(ls, c, msg)
  1690. if not c then luaX:syntaxerror(ls, msg) end
  1691. end
  1692.  
  1693. ------------------------------------------------------------------------
  1694. -- verifies token conditions are met or else throw error
  1695. ------------------------------------------------------------------------
  1696. function luaY:check_match(ls, what, who, where)
  1697. if not self:testnext(ls, what) then
  1698. if where == ls.linenumber then
  1699. self:error_expected(ls, what)
  1700. else
  1701. luaX:syntaxerror(ls, string.format(
  1702. self.LUA_QS.." expected (to close "..self.LUA_QS.." at line %d)",
  1703. luaX:token2str(ls, what), luaX:token2str(ls, who), where))
  1704. end
  1705. end
  1706. end
  1707.  
  1708. ------------------------------------------------------------------------
  1709. -- expect that token is a name, return the name
  1710. ------------------------------------------------------------------------
  1711. function luaY:str_checkname(ls)
  1712. self:check(ls, "TK_NAME")
  1713. local ts = ls.t.seminfo
  1714. luaX:next(ls)
  1715. return ts
  1716. end
  1717.  
  1718. ------------------------------------------------------------------------
  1719. -- initialize a struct expdesc, expression description data structure
  1720. ------------------------------------------------------------------------
  1721. function luaY:init_exp(e, k, i)
  1722. e.f, e.t = luaK.NO_JUMP, luaK.NO_JUMP
  1723. e.k = k
  1724. e.info = i
  1725. end
  1726.  
  1727. ------------------------------------------------------------------------
  1728. -- adds given string s in string pool, sets e as VK
  1729. ------------------------------------------------------------------------
  1730. function luaY:codestring(ls, e, s)
  1731. self:init_exp(e, "VK", luaK:stringK(ls.fs, s))
  1732. end
  1733.  
  1734. ------------------------------------------------------------------------
  1735. -- consume a name token, adds it to string pool, sets e as VK
  1736. ------------------------------------------------------------------------
  1737. function luaY:checkname(ls, e)
  1738. self:codestring(ls, e, self:str_checkname(ls))
  1739. end
  1740.  
  1741. ------------------------------------------------------------------------
  1742. -- creates struct entry for a local variable
  1743. -- * used only in new_localvar()
  1744. ------------------------------------------------------------------------
  1745. function luaY:registerlocalvar(ls, varname)
  1746. local fs = ls.fs
  1747. local f = fs.f
  1748. self:growvector(ls.L, f.locvars, fs.nlocvars, f.sizelocvars,
  1749. nil, self.SHRT_MAX, "too many local variables")
  1750. -- loop to initialize empty f.locvar positions not required
  1751. f.locvars[fs.nlocvars] = {} -- LocVar
  1752. f.locvars[fs.nlocvars].varname = varname
  1753. -- luaC_objbarrier(ls.L, f, varname) /* GC */
  1754. local nlocvars = fs.nlocvars
  1755. fs.nlocvars = fs.nlocvars + 1
  1756. return nlocvars
  1757. end
  1758.  
  1759. ------------------------------------------------------------------------
  1760. -- creates a new local variable given a name and an offset from nactvar
  1761. -- * used in fornum(), forlist(), parlist(), body()
  1762. ------------------------------------------------------------------------
  1763. function luaY:new_localvarliteral(ls, v, n)
  1764. self:new_localvar(ls, v, n)
  1765. end
  1766.  
  1767. ------------------------------------------------------------------------
  1768. -- register a local variable, set in active variable list
  1769. ------------------------------------------------------------------------
  1770. function luaY:new_localvar(ls, name, n)
  1771. local fs = ls.fs
  1772. self:checklimit(fs, fs.nactvar + n + 1, self.LUAI_MAXVARS, "local variables")
  1773. fs.actvar[fs.nactvar + n] = self:registerlocalvar(ls, name)
  1774. end
  1775.  
  1776. ------------------------------------------------------------------------
  1777. -- adds nvars number of new local variables, set debug information
  1778. ------------------------------------------------------------------------
  1779. function luaY:adjustlocalvars(ls, nvars)
  1780. local fs = ls.fs
  1781. fs.nactvar = fs.nactvar + nvars
  1782. for i = nvars, 1, -1 do
  1783. self:getlocvar(fs, fs.nactvar - i).startpc = fs.pc
  1784. end
  1785. end
  1786.  
  1787. ------------------------------------------------------------------------
  1788. -- removes a number of locals, set debug information
  1789. ------------------------------------------------------------------------
  1790. function luaY:removevars(ls, tolevel)
  1791. local fs = ls.fs
  1792. while fs.nactvar > tolevel do
  1793. fs.nactvar = fs.nactvar - 1
  1794. self:getlocvar(fs, fs.nactvar).endpc = fs.pc
  1795. end
  1796. end
  1797.  
  1798. ------------------------------------------------------------------------
  1799. -- returns an existing upvalue index based on the given name, or
  1800. -- creates a new upvalue struct entry and returns the new index
  1801. -- * used only in singlevaraux()
  1802. ------------------------------------------------------------------------
  1803. function luaY:indexupvalue(fs, name, v)
  1804. local f = fs.f
  1805. for i = 0, f.nups - 1 do
  1806. if fs.upvalues[i].k == v.k and fs.upvalues[i].info == v.info then
  1807. assert(f.upvalues[i] == name)
  1808. return i
  1809. end
  1810. end
  1811. -- new one
  1812. self:checklimit(fs, f.nups + 1, self.LUAI_MAXUPVALUES, "upvalues")
  1813. self:growvector(fs.L, f.upvalues, f.nups, f.sizeupvalues,
  1814. nil, self.MAX_INT, "")
  1815. -- loop to initialize empty f.upvalues positions not required
  1816. f.upvalues[f.nups] = name
  1817. -- luaC_objbarrier(fs->L, f, name); /* GC */
  1818. assert(v.k == "VLOCAL" or v.k == "VUPVAL")
  1819. -- this is a partial copy; only k & info fields used
  1820. fs.upvalues[f.nups] = { k = v.k, info = v.info }
  1821. local nups = f.nups
  1822. f.nups = f.nups + 1
  1823. return nups
  1824. end
  1825.  
  1826. ------------------------------------------------------------------------
  1827. -- search the local variable namespace of the given fs for a match
  1828. -- * used only in singlevaraux()
  1829. ------------------------------------------------------------------------
  1830. function luaY:searchvar(fs, n)
  1831. for i = fs.nactvar - 1, 0, -1 do
  1832. if n == self:getlocvar(fs, i).varname then
  1833. return i
  1834. end
  1835. end
  1836. return -1 -- not found
  1837. end
  1838.  
  1839. ------------------------------------------------------------------------
  1840. -- * mark upvalue flags in function states up to a given level
  1841. -- * used only in singlevaraux()
  1842. ------------------------------------------------------------------------
  1843. function luaY:markupval(fs, level)
  1844. local bl = fs.bl
  1845. while bl and bl.nactvar > level do bl = bl.previous end
  1846. if bl then bl.upval = true end
  1847. end
  1848.  
  1849. ------------------------------------------------------------------------
  1850. -- handle locals, globals and upvalues and related processing
  1851. -- * search mechanism is recursive, calls itself to search parents
  1852. -- * used only in singlevar()
  1853. ------------------------------------------------------------------------
  1854. function luaY:singlevaraux(fs, n, var, base)
  1855. if fs == nil then -- no more levels?
  1856. self:init_exp(var, "VGLOBAL", luaP.NO_REG) -- default is global variable
  1857. return "VGLOBAL"
  1858. else
  1859. local v = self:searchvar(fs, n) -- look up at current level
  1860. if v >= 0 then
  1861. self:init_exp(var, "VLOCAL", v)
  1862. if base == 0 then
  1863. self:markupval(fs, v) -- local will be used as an upval
  1864. end
  1865. return "VLOCAL"
  1866. else -- not found at current level; try upper one
  1867. if self:singlevaraux(fs.prev, n, var, 0) == "VGLOBAL" then
  1868. return "VGLOBAL"
  1869. end
  1870. var.info = self:indexupvalue(fs, n, var) -- else was LOCAL or UPVAL
  1871. var.k = "VUPVAL" -- upvalue in this level
  1872. return "VUPVAL"
  1873. end--if v
  1874. end--if fs
  1875. end
  1876.  
  1877. ------------------------------------------------------------------------
  1878. -- consume a name token, creates a variable (global|local|upvalue)
  1879. -- * used in prefixexp(), funcname()
  1880. ------------------------------------------------------------------------
  1881. function luaY:singlevar(ls, var)
  1882. local varname = self:str_checkname(ls)
  1883. local fs = ls.fs
  1884. if self:singlevaraux(fs, varname, var, 1) == "VGLOBAL" then
  1885. var.info = luaK:stringK(fs, varname) -- info points to global name
  1886. end
  1887. end
  1888.  
  1889. ------------------------------------------------------------------------
  1890. -- adjust RHS to match LHS in an assignment
  1891. -- * used in assignment(), forlist(), localstat()
  1892. ------------------------------------------------------------------------
  1893. function luaY:adjust_assign(ls, nvars, nexps, e)
  1894. local fs = ls.fs
  1895. local extra = nvars - nexps
  1896. if self:hasmultret(e.k) then
  1897. extra = extra + 1 -- includes call itself
  1898. if extra <= 0 then extra = 0 end
  1899. luaK:setreturns(fs, e, extra) -- last exp. provides the difference
  1900. if extra > 1 then luaK:reserveregs(fs, extra - 1) end
  1901. else
  1902. if e.k ~= "VVOID" then luaK:exp2nextreg(fs, e) end -- close last expression
  1903. if extra > 0 then
  1904. local reg = fs.freereg
  1905. luaK:reserveregs(fs, extra)
  1906. luaK:_nil(fs, reg, extra)
  1907. end
  1908. end
  1909. end
  1910.  
  1911. ------------------------------------------------------------------------
  1912. -- tracks and limits parsing depth, assert check at end of parsing
  1913. ------------------------------------------------------------------------
  1914. function luaY:enterlevel(ls)
  1915. ls.L.nCcalls = ls.L.nCcalls + 1
  1916. if ls.L.nCcalls > self.LUAI_MAXCCALLS then
  1917. luaX:lexerror(ls, "chunk has too many syntax levels", 0)
  1918. end
  1919. end
  1920.  
  1921. ------------------------------------------------------------------------
  1922. -- tracks parsing depth, a pair with luaY:enterlevel()
  1923. ------------------------------------------------------------------------
  1924. function luaY:leavelevel(ls)
  1925. ls.L.nCcalls = ls.L.nCcalls - 1
  1926. end
  1927.  
  1928. ------------------------------------------------------------------------
  1929. -- enters a code unit, initializes elements
  1930. ------------------------------------------------------------------------
  1931. function luaY:enterblock(fs, bl, isbreakable)
  1932. bl.breaklist = luaK.NO_JUMP
  1933. bl.isbreakable = isbreakable
  1934. bl.nactvar = fs.nactvar
  1935. bl.upval = false
  1936. bl.previous = fs.bl
  1937. fs.bl = bl
  1938. assert(fs.freereg == fs.nactvar)
  1939. end
  1940.  
  1941. ------------------------------------------------------------------------
  1942. -- leaves a code unit, close any upvalues
  1943. ------------------------------------------------------------------------
  1944. function luaY:leaveblock(fs)
  1945. local bl = fs.bl
  1946. fs.bl = bl.previous
  1947. self:removevars(fs.ls, bl.nactvar)
  1948. if bl.upval then
  1949. luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  1950. end
  1951. -- a block either controls scope or breaks (never both)
  1952. assert(not bl.isbreakable or not bl.upval)
  1953. assert(bl.nactvar == fs.nactvar)
  1954. fs.freereg = fs.nactvar -- free registers
  1955. luaK:patchtohere(fs, bl.breaklist)
  1956. end
  1957.  
  1958. ------------------------------------------------------------------------
  1959. -- implement the instantiation of a function prototype, append list of
  1960. -- upvalues after the instantiation instruction
  1961. -- * used only in body()
  1962. ------------------------------------------------------------------------
  1963. function luaY:pushclosure(ls, func, v)
  1964. local fs = ls.fs
  1965. local f = fs.f
  1966. self:growvector(ls.L, f.p, fs.np, f.sizep, nil,
  1967. luaP.MAXARG_Bx, "constant table overflow")
  1968. -- loop to initialize empty f.p positions not required
  1969. f.p[fs.np] = func.f
  1970. fs.np = fs.np + 1
  1971. -- luaC_objbarrier(ls->L, f, func->f); /* C */
  1972. self:init_exp(v, "VRELOCABLE", luaK:codeABx(fs, "OP_CLOSURE", 0, fs.np - 1))
  1973. for i = 0, func.f.nups - 1 do
  1974. local o = (func.upvalues[i].k == "VLOCAL") and "OP_MOVE" or "OP_GETUPVAL"
  1975. luaK:codeABC(fs, o, 0, func.upvalues[i].info, 0)
  1976. end
  1977. end
  1978.  
  1979. ------------------------------------------------------------------------
  1980. -- opening of a function
  1981. ------------------------------------------------------------------------
  1982. function luaY:open_func(ls, fs)
  1983. local L = ls.L
  1984. local f = self:newproto(ls.L)
  1985. fs.f = f
  1986. fs.prev = ls.fs -- linked list of funcstates
  1987. fs.ls = ls
  1988. fs.L = L
  1989. ls.fs = fs
  1990. fs.pc = 0
  1991. fs.lasttarget = -1
  1992. fs.jpc = luaK.NO_JUMP
  1993. fs.freereg = 0
  1994. fs.nk = 0
  1995. fs.np = 0
  1996. fs.nlocvars = 0
  1997. fs.nactvar = 0
  1998. fs.bl = nil
  1999. f.source = ls.source
  2000. f.maxstacksize = 2 -- registers 0/1 are always valid
  2001. fs.h = {} -- constant table; was luaH_new call
  2002. -- anchor table of constants and prototype (to avoid being collected)
  2003. -- sethvalue2s(L, L->top, fs->h); incr_top(L); /* C */
  2004. -- setptvalue2s(L, L->top, f); incr_top(L);
  2005. end
  2006.  
  2007. ------------------------------------------------------------------------
  2008. -- closing of a function
  2009. ------------------------------------------------------------------------
  2010. function luaY:close_func(ls)
  2011. local L = ls.L
  2012. local fs = ls.fs
  2013. local f = fs.f
  2014. self:removevars(ls, 0)
  2015. luaK:ret(fs, 0, 0) -- final return
  2016. -- luaM_reallocvector deleted for f->code, f->lineinfo, f->k, f->p,
  2017. -- f->locvars, f->upvalues; not required for Lua table arrays
  2018. f.sizecode = fs.pc
  2019. f.sizelineinfo = fs.pc
  2020. f.sizek = fs.nk
  2021. f.sizep = fs.np
  2022. f.sizelocvars = fs.nlocvars
  2023. f.sizeupvalues = f.nups
  2024. --assert(luaG_checkcode(f)) -- currently not implemented
  2025. assert(fs.bl == nil)
  2026. ls.fs = fs.prev
  2027. -- the following is not required for this implementation; kept here
  2028. -- for completeness
  2029. -- L->top -= 2; /* remove table and prototype from the stack */
  2030. -- last token read was anchored in defunct function; must reanchor it
  2031. if fs then self:anchor_token(ls) end
  2032. end
  2033.  
  2034. ------------------------------------------------------------------------
  2035. -- parser initialization function
  2036. -- * note additional sub-tables needed for LexState, FuncState
  2037. ------------------------------------------------------------------------
  2038. function luaY:parser(L, z, buff, name)
  2039. local lexstate = {} -- LexState
  2040. lexstate.t = {}
  2041. lexstate.lookahead = {}
  2042. local funcstate = {} -- FuncState
  2043. funcstate.upvalues = {}
  2044. funcstate.actvar = {}
  2045. -- the following nCcalls initialization added for convenience
  2046. L.nCcalls = 0
  2047. lexstate.buff = buff
  2048. luaX:setinput(L, lexstate, z, name)
  2049. self:open_func(lexstate, funcstate)
  2050. funcstate.f.is_vararg = self.VARARG_ISVARARG -- main func. is always vararg
  2051. luaX:next(lexstate) -- read first token
  2052. self:chunk(lexstate)
  2053. self:check(lexstate, "TK_EOS")
  2054. self:close_func(lexstate)
  2055. assert(funcstate.prev == nil)
  2056. assert(funcstate.f.nups == 0)
  2057. assert(lexstate.fs == nil)
  2058. return funcstate.f
  2059. end
  2060.  
  2061. --[[--------------------------------------------------------------------
  2062. -- GRAMMAR RULES
  2063. ----------------------------------------------------------------------]]
  2064.  
  2065. ------------------------------------------------------------------------
  2066. -- parse a function name suffix, for function call specifications
  2067. -- * used in primaryexp(), funcname()
  2068. ------------------------------------------------------------------------
  2069. function luaY:field(ls, v)
  2070. -- field -> ['.' | ':'] NAME
  2071. local fs = ls.fs
  2072. local key = {} -- expdesc
  2073. luaK:exp2anyreg(fs, v)
  2074. luaX:next(ls) -- skip the dot or colon
  2075. self:checkname(ls, key)
  2076. luaK:indexed(fs, v, key)
  2077. end
  2078.  
  2079. ------------------------------------------------------------------------
  2080. -- parse a table indexing suffix, for constructors, expressions
  2081. -- * used in recfield(), primaryexp()
  2082. ------------------------------------------------------------------------
  2083. function luaY:yindex(ls, v)
  2084. -- index -> '[' expr ']'
  2085. luaX:next(ls) -- skip the '['
  2086. self:expr(ls, v)
  2087. luaK:exp2val(ls.fs, v)
  2088. self:checknext(ls, "]")
  2089. end
  2090.  
  2091. --[[--------------------------------------------------------------------
  2092. -- Rules for Constructors
  2093. ----------------------------------------------------------------------]]
  2094.  
  2095. --[[--------------------------------------------------------------------
  2096. -- struct ConsControl:
  2097. -- v -- last list item read (table: struct expdesc)
  2098. -- t -- table descriptor (table: struct expdesc)
  2099. -- nh -- total number of 'record' elements
  2100. -- na -- total number of array elements
  2101. -- tostore -- number of array elements pending to be stored
  2102. ----------------------------------------------------------------------]]
  2103.  
  2104. ------------------------------------------------------------------------
  2105. -- parse a table record (hash) field
  2106. -- * used in constructor()
  2107. ------------------------------------------------------------------------
  2108. function luaY:recfield(ls, cc)
  2109. -- recfield -> (NAME | '['exp1']') = exp1
  2110. local fs = ls.fs
  2111. local reg = ls.fs.freereg
  2112. local key, val = {}, {} -- expdesc
  2113. if ls.t.token == "TK_NAME" then
  2114. self:checklimit(fs, cc.nh, self.MAX_INT, "items in a constructor")
  2115. self:checkname(ls, key)
  2116. else -- ls->t.token == '['
  2117. self:yindex(ls, key)
  2118. end
  2119. cc.nh = cc.nh + 1
  2120. self:checknext(ls, "=")
  2121. local rkkey = luaK:exp2RK(fs, key)
  2122. self:expr(ls, val)
  2123. luaK:codeABC(fs, "OP_SETTABLE", cc.t.info, rkkey, luaK:exp2RK(fs, val))
  2124. fs.freereg = reg -- free registers
  2125. end
  2126.  
  2127. ------------------------------------------------------------------------
  2128. -- emit a set list instruction if enough elements (LFIELDS_PER_FLUSH)
  2129. -- * used in constructor()
  2130. ------------------------------------------------------------------------
  2131. function luaY:closelistfield(fs, cc)
  2132. if cc.v.k == "VVOID" then return end -- there is no list item
  2133. luaK:exp2nextreg(fs, cc.v)
  2134. cc.v.k = "VVOID"
  2135. if cc.tostore == luaP.LFIELDS_PER_FLUSH then
  2136. luaK:setlist(fs, cc.t.info, cc.na, cc.tostore) -- flush
  2137. cc.tostore = 0 -- no more items pending
  2138. end
  2139. end
  2140.  
  2141. ------------------------------------------------------------------------
  2142. -- emit a set list instruction at the end of parsing list constructor
  2143. -- * used in constructor()
  2144. ------------------------------------------------------------------------
  2145. function luaY:lastlistfield(fs, cc)
  2146. if cc.tostore == 0 then return end
  2147. if self:hasmultret(cc.v.k) then
  2148. luaK:setmultret(fs, cc.v)
  2149. luaK:setlist(fs, cc.t.info, cc.na, self.LUA_MULTRET)
  2150. cc.na = cc.na - 1 -- do not count last expression (unknown number of elements)
  2151. else
  2152. if cc.v.k ~= "VVOID" then
  2153. luaK:exp2nextreg(fs, cc.v)
  2154. end
  2155. luaK:setlist(fs, cc.t.info, cc.na, cc.tostore)
  2156. end
  2157. end
  2158.  
  2159. ------------------------------------------------------------------------
  2160. -- parse a table list (array) field
  2161. -- * used in constructor()
  2162. ------------------------------------------------------------------------
  2163. function luaY:listfield(ls, cc)
  2164. self:expr(ls, cc.v)
  2165. self:checklimit(ls.fs, cc.na, self.MAX_INT, "items in a constructor")
  2166. cc.na = cc.na + 1
  2167. cc.tostore = cc.tostore + 1
  2168. end
  2169.  
  2170. ------------------------------------------------------------------------
  2171. -- parse a table constructor
  2172. -- * used in funcargs(), simpleexp()
  2173. ------------------------------------------------------------------------
  2174. function luaY:constructor(ls, t)
  2175. -- constructor -> '{' [ field { fieldsep field } [ fieldsep ] ] '}'
  2176. -- field -> recfield | listfield
  2177. -- fieldsep -> ',' | ';'
  2178. local fs = ls.fs
  2179. local line = ls.linenumber
  2180. local pc = luaK:codeABC(fs, "OP_NEWTABLE", 0, 0, 0)
  2181. local cc = {} -- ConsControl
  2182. cc.v = {}
  2183. cc.na, cc.nh, cc.tostore = 0, 0, 0
  2184. cc.t = t
  2185. self:init_exp(t, "VRELOCABLE", pc)
  2186. self:init_exp(cc.v, "VVOID", 0) -- no value (yet)
  2187. luaK:exp2nextreg(ls.fs, t) -- fix it at stack top (for gc)
  2188. self:checknext(ls, "{")
  2189. repeat
  2190. assert(cc.v.k == "VVOID" or cc.tostore > 0)
  2191. if ls.t.token == "}" then break end
  2192. self:closelistfield(fs, cc)
  2193. local c = ls.t.token
  2194.  
  2195. if c == "TK_NAME" then -- may be listfields or recfields
  2196. luaX:lookahead(ls)
  2197. if ls.lookahead.token ~= "=" then -- expression?
  2198. self:listfield(ls, cc)
  2199. else
  2200. self:recfield(ls, cc)
  2201. end
  2202. elseif c == "[" then -- constructor_item -> recfield
  2203. self:recfield(ls, cc)
  2204. else -- constructor_part -> listfield
  2205. self:listfield(ls, cc)
  2206. end
  2207. until not self:testnext(ls, ",") and not self:testnext(ls, ";")
  2208. self:check_match(ls, "}", "{", line)
  2209. self:lastlistfield(fs, cc)
  2210. luaP:SETARG_B(fs.f.code[pc], self:int2fb(cc.na)) -- set initial array size
  2211. luaP:SETARG_C(fs.f.code[pc], self:int2fb(cc.nh)) -- set initial table size
  2212. end
  2213.  
  2214. -- }======================================================================
  2215.  
  2216. ------------------------------------------------------------------------
  2217. -- parse the arguments (parameters) of a function declaration
  2218. -- * used in body()
  2219. ------------------------------------------------------------------------
  2220. function luaY:parlist(ls)
  2221. -- parlist -> [ param { ',' param } ]
  2222. local fs = ls.fs
  2223. local f = fs.f
  2224. local nparams = 0
  2225. f.is_vararg = 0
  2226. if ls.t.token ~= ")" then -- is 'parlist' not empty?
  2227. repeat
  2228. local c = ls.t.token
  2229. if c == "TK_NAME" then -- param -> NAME
  2230. self:new_localvar(ls, self:str_checkname(ls), nparams)
  2231. nparams = nparams + 1
  2232. elseif c == "TK_DOTS" then -- param -> `...'
  2233. luaX:next(ls)
  2234. -- [[
  2235. -- #if defined(LUA_COMPAT_VARARG)
  2236. -- use `arg' as default name
  2237. self:new_localvarliteral(ls, "arg", nparams)
  2238. nparams = nparams + 1
  2239. f.is_vararg = self.VARARG_HASARG + self.VARARG_NEEDSARG
  2240. -- #endif
  2241. --]]
  2242. f.is_vararg = f.is_vararg + self.VARARG_ISVARARG
  2243. else
  2244. luaX:syntaxerror(ls, "<name> or "..self:LUA_QL("...").." expected")
  2245. end
  2246. until f.is_vararg ~= 0 or not self:testnext(ls, ",")
  2247. end--if
  2248. self:adjustlocalvars(ls, nparams)
  2249. -- NOTE: the following works only when HASARG_MASK is 2!
  2250. f.numparams = fs.nactvar - (f.is_vararg % self.HASARG_MASK)
  2251. luaK:reserveregs(fs, fs.nactvar) -- reserve register for parameters
  2252. end
  2253.  
  2254. ------------------------------------------------------------------------
  2255. -- parse function declaration body
  2256. -- * used in simpleexp(), localfunc(), funcstat()
  2257. ------------------------------------------------------------------------
  2258. function luaY:body(ls, e, needself, line)
  2259. -- body -> '(' parlist ')' chunk END
  2260. local new_fs = {} -- FuncState
  2261. new_fs.upvalues = {}
  2262. new_fs.actvar = {}
  2263. self:open_func(ls, new_fs)
  2264. new_fs.f.lineDefined = line
  2265. self:checknext(ls, "(")
  2266. if needself then
  2267. self:new_localvarliteral(ls, "self", 0)
  2268. self:adjustlocalvars(ls, 1)
  2269. end
  2270. self:parlist(ls)
  2271. self:checknext(ls, ")")
  2272. self:chunk(ls)
  2273. new_fs.f.lastlinedefined = ls.linenumber
  2274. self:check_match(ls, "TK_END", "TK_FUNCTION", line)
  2275. self:close_func(ls)
  2276. self:pushclosure(ls, new_fs, e)
  2277. end
  2278.  
  2279. ------------------------------------------------------------------------
  2280. -- parse a list of comma-separated expressions
  2281. -- * used is multiple locations
  2282. ------------------------------------------------------------------------
  2283. function luaY:explist1(ls, v)
  2284. -- explist1 -> expr { ',' expr }
  2285. local n = 1 -- at least one expression
  2286. self:expr(ls, v)
  2287. while self:testnext(ls, ",") do
  2288. luaK:exp2nextreg(ls.fs, v)
  2289. self:expr(ls, v)
  2290. n = n + 1
  2291. end
  2292. return n
  2293. end
  2294.  
  2295. ------------------------------------------------------------------------
  2296. -- parse the parameters of a function call
  2297. -- * contrast with parlist(), used in function declarations
  2298. -- * used in primaryexp()
  2299. ------------------------------------------------------------------------
  2300. function luaY:funcargs(ls, f)
  2301. local fs = ls.fs
  2302. local args = {} -- expdesc
  2303. local nparams
  2304. local line = ls.linenumber
  2305. local c = ls.t.token
  2306. if c == "(" then -- funcargs -> '(' [ explist1 ] ')'
  2307. if line ~= ls.lastline then
  2308. luaX:syntaxerror(ls, "ambiguous syntax (function call x new statement)")
  2309. end
  2310. luaX:next(ls)
  2311. if ls.t.token == ")" then -- arg list is empty?
  2312. args.k = "VVOID"
  2313. else
  2314. self:explist1(ls, args)
  2315. luaK:setmultret(fs, args)
  2316. end
  2317. self:check_match(ls, ")", "(", line)
  2318. elseif c == "{" then -- funcargs -> constructor
  2319. self:constructor(ls, args)
  2320. elseif c == "TK_STRING" then -- funcargs -> STRING
  2321. self:codestring(ls, args, ls.t.seminfo)
  2322. luaX:next(ls) -- must use 'seminfo' before 'next'
  2323. else
  2324. luaX:syntaxerror(ls, "function arguments expected")
  2325. return
  2326. end
  2327. assert(f.k == "VNONRELOC")
  2328. local base = f.info -- base register for call
  2329. if self:hasmultret(args.k) then
  2330. nparams = self.LUA_MULTRET -- open call
  2331. else
  2332. if args.k ~= "VVOID" then
  2333. luaK:exp2nextreg(fs, args) -- close last argument
  2334. end
  2335. nparams = fs.freereg - (base + 1)
  2336. end
  2337. self:init_exp(f, "VCALL", luaK:codeABC(fs, "OP_CALL", base, nparams + 1, 2))
  2338. luaK:fixline(fs, line)
  2339. fs.freereg = base + 1 -- call remove function and arguments and leaves
  2340. -- (unless changed) one result
  2341. end
  2342.  
  2343. --[[--------------------------------------------------------------------
  2344. -- Expression parsing
  2345. ----------------------------------------------------------------------]]
  2346.  
  2347. ------------------------------------------------------------------------
  2348. -- parses an expression in parentheses or a single variable
  2349. -- * used in primaryexp()
  2350. ------------------------------------------------------------------------
  2351. function luaY:prefixexp(ls, v)
  2352. -- prefixexp -> NAME | '(' expr ')'
  2353. local c = ls.t.token
  2354. if c == "(" then
  2355. local line = ls.linenumber
  2356. luaX:next(ls)
  2357. self:expr(ls, v)
  2358. self:check_match(ls, ")", "(", line)
  2359. luaK:dischargevars(ls.fs, v)
  2360. elseif c == "TK_NAME" then
  2361. self:singlevar(ls, v)
  2362. else
  2363. luaX:syntaxerror(ls, "unexpected symbol")
  2364. end--if c
  2365. return
  2366. end
  2367.  
  2368. ------------------------------------------------------------------------
  2369. -- parses a prefixexp (an expression in parentheses or a single variable)
  2370. -- or a function call specification
  2371. -- * used in simpleexp(), assignment(), exprstat()
  2372. ------------------------------------------------------------------------
  2373. function luaY:primaryexp(ls, v)
  2374. -- primaryexp ->
  2375. -- prefixexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs }
  2376. local fs = ls.fs
  2377. self:prefixexp(ls, v)
  2378. while true do
  2379. local c = ls.t.token
  2380. if c == "." then -- field
  2381. self:field(ls, v)
  2382. elseif c == "[" then -- '[' exp1 ']'
  2383. local key = {} -- expdesc
  2384. luaK:exp2anyreg(fs, v)
  2385. self:yindex(ls, key)
  2386. luaK:indexed(fs, v, key)
  2387. elseif c == ":" then -- ':' NAME funcargs
  2388. local key = {} -- expdesc
  2389. luaX:next(ls)
  2390. self:checkname(ls, key)
  2391. luaK:_self(fs, v, key)
  2392. self:funcargs(ls, v)
  2393. elseif c == "(" or c == "TK_STRING" or c == "{" then -- funcargs
  2394. luaK:exp2nextreg(fs, v)
  2395. self:funcargs(ls, v)
  2396. else
  2397. return
  2398. end--if c
  2399. end--while
  2400. end
  2401.  
  2402. ------------------------------------------------------------------------
  2403. -- parses general expression types, constants handled here
  2404. -- * used in subexpr()
  2405. ------------------------------------------------------------------------
  2406. function luaY:simpleexp(ls, v)
  2407. -- simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
  2408. -- constructor | FUNCTION body | primaryexp
  2409. local c = ls.t.token
  2410. if c == "TK_NUMBER" then
  2411. self:init_exp(v, "VKNUM", 0)
  2412. v.nval = ls.t.seminfo
  2413. elseif c == "TK_STRING" then
  2414. self:codestring(ls, v, ls.t.seminfo)
  2415. elseif c == "TK_NIL" then
  2416. self:init_exp(v, "VNIL", 0)
  2417. elseif c == "TK_TRUE" then
  2418. self:init_exp(v, "VTRUE", 0)
  2419. elseif c == "TK_FALSE" then
  2420. self:init_exp(v, "VFALSE", 0)
  2421. elseif c == "TK_DOTS" then -- vararg
  2422. local fs = ls.fs
  2423. self:check_condition(ls, fs.f.is_vararg ~= 0,
  2424. "cannot use "..self:LUA_QL("...").." outside a vararg function");
  2425. -- NOTE: the following substitutes for a bitop, but is value-specific
  2426. local is_vararg = fs.f.is_vararg
  2427. if is_vararg >= self.VARARG_NEEDSARG then
  2428. fs.f.is_vararg = is_vararg - self.VARARG_NEEDSARG -- don't need 'arg'
  2429. end
  2430. self:init_exp(v, "VVARARG", luaK:codeABC(fs, "OP_VARARG", 0, 1, 0))
  2431. elseif c == "{" then -- constructor
  2432. self:constructor(ls, v)
  2433. return
  2434. elseif c == "TK_FUNCTION" then
  2435. luaX:next(ls)
  2436. self:body(ls, v, false, ls.linenumber)
  2437. return
  2438. else
  2439. self:primaryexp(ls, v)
  2440. return
  2441. end--if c
  2442. luaX:next(ls)
  2443. end
  2444.  
  2445. ------------------------------------------------------------------------
  2446. -- Translates unary operators tokens if found, otherwise returns
  2447. -- OPR_NOUNOPR. getunopr() and getbinopr() are used in subexpr().
  2448. -- * used in subexpr()
  2449. ------------------------------------------------------------------------
  2450. function luaY:getunopr(op)
  2451. if op == "TK_NOT" then
  2452. return "OPR_NOT"
  2453. elseif op == "-" then
  2454. return "OPR_MINUS"
  2455. elseif op == "#" then
  2456. return "OPR_LEN"
  2457. else
  2458. return "OPR_NOUNOPR"
  2459. end
  2460. end
  2461.  
  2462. ------------------------------------------------------------------------
  2463. -- Translates binary operator tokens if found, otherwise returns
  2464. -- OPR_NOBINOPR. Code generation uses OPR_* style tokens.
  2465. -- * used in subexpr()
  2466. ------------------------------------------------------------------------
  2467. luaY.getbinopr_table = {
  2468. ["+"] = "OPR_ADD",
  2469. ["-"] = "OPR_SUB",
  2470. ["*"] = "OPR_MUL",
  2471. ["/"] = "OPR_DIV",
  2472. ["%"] = "OPR_MOD",
  2473. ["^"] = "OPR_POW",
  2474. ["TK_CONCAT"] = "OPR_CONCAT",
  2475. ["TK_NE"] = "OPR_NE",
  2476. ["TK_EQ"] = "OPR_EQ",
  2477. ["<"] = "OPR_LT",
  2478. ["TK_LE"] = "OPR_LE",
  2479. [">"] = "OPR_GT",
  2480. ["TK_GE"] = "OPR_GE",
  2481. ["TK_AND"] = "OPR_AND",
  2482. ["TK_OR"] = "OPR_OR",
  2483. }
  2484. function luaY:getbinopr(op)
  2485. local opr = self.getbinopr_table[op]
  2486. if opr then return opr else return "OPR_NOBINOPR" end
  2487. end
  2488.  
  2489. ------------------------------------------------------------------------
  2490. -- the following priority table consists of pairs of left/right values
  2491. -- for binary operators (was a static const struct); grep for ORDER OPR
  2492. -- * the following struct is replaced:
  2493. -- static const struct {
  2494. -- lu_byte left; /* left priority for each binary operator */
  2495. -- lu_byte right; /* right priority */
  2496. -- } priority[] = { /* ORDER OPR */
  2497. ------------------------------------------------------------------------
  2498. luaY.priority = {
  2499. {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, -- `+' `-' `/' `%'
  2500. {10, 9}, {5, 4}, -- power and concat (right associative)
  2501. {3, 3}, {3, 3}, -- equality
  2502. {3, 3}, {3, 3}, {3, 3}, {3, 3}, -- order
  2503. {2, 2}, {1, 1} -- logical (and/or)
  2504. }
  2505.  
  2506. luaY.UNARY_PRIORITY = 8 -- priority for unary operators
  2507.  
  2508. ------------------------------------------------------------------------
  2509. -- Parse subexpressions. Includes handling of unary operators and binary
  2510. -- operators. A subexpr is given the rhs priority level of the operator
  2511. -- immediately left of it, if any (limit is -1 if none,) and if a binop
  2512. -- is found, limit is compared with the lhs priority level of the binop
  2513. -- in order to determine which executes first.
  2514. ------------------------------------------------------------------------
  2515.  
  2516. ------------------------------------------------------------------------
  2517. -- subexpr -> (simpleexp | unop subexpr) { binop subexpr }
  2518. -- where 'binop' is any binary operator with a priority higher than 'limit'
  2519. -- * for priority lookups with self.priority[], 1=left and 2=right
  2520. -- * recursively called
  2521. -- * used in expr()
  2522. ------------------------------------------------------------------------
  2523. function luaY:subexpr(ls, v, limit)
  2524. self:enterlevel(ls)
  2525. local uop = self:getunopr(ls.t.token)
  2526. if uop ~= "OPR_NOUNOPR" then
  2527. luaX:next(ls)
  2528. self:subexpr(ls, v, self.UNARY_PRIORITY)
  2529. luaK:prefix(ls.fs, uop, v)
  2530. else
  2531. self:simpleexp(ls, v)
  2532. end
  2533. -- expand while operators have priorities higher than 'limit'
  2534. local op = self:getbinopr(ls.t.token)
  2535. while op ~= "OPR_NOBINOPR" and self.priority[luaK.BinOpr[op] + 1][1] > limit do
  2536. local v2 = {} -- expdesc
  2537. luaX:next(ls)
  2538. luaK:infix(ls.fs, op, v)
  2539. -- read sub-expression with higher priority
  2540. local nextop = self:subexpr(ls, v2, self.priority[luaK.BinOpr[op] + 1][2])
  2541. luaK:posfix(ls.fs, op, v, v2)
  2542. op = nextop
  2543. end
  2544. self:leavelevel(ls)
  2545. return op -- return first untreated operator
  2546. end
  2547.  
  2548. ------------------------------------------------------------------------
  2549. -- Expression parsing starts here. Function subexpr is entered with the
  2550. -- left operator (which is non-existent) priority of -1, which is lower
  2551. -- than all actual operators. Expr information is returned in parm v.
  2552. -- * used in multiple locations
  2553. ------------------------------------------------------------------------
  2554. function luaY:expr(ls, v)
  2555. self:subexpr(ls, v, 0)
  2556. end
  2557.  
  2558. -- }====================================================================
  2559.  
  2560. --[[--------------------------------------------------------------------
  2561. -- Rules for Statements
  2562. ----------------------------------------------------------------------]]
  2563.  
  2564. ------------------------------------------------------------------------
  2565. -- checks next token, used as a look-ahead
  2566. -- * returns boolean instead of 0|1
  2567. -- * used in retstat(), chunk()
  2568. ------------------------------------------------------------------------
  2569. function luaY:block_follow(token)
  2570. if token == "TK_ELSE" or token == "TK_ELSEIF" or token == "TK_END"
  2571. or token == "TK_UNTIL" or token == "TK_EOS" then
  2572. return true
  2573. else
  2574. return false
  2575. end
  2576. end
  2577.  
  2578. ------------------------------------------------------------------------
  2579. -- parse a code block or unit
  2580. -- * used in multiple functions
  2581. ------------------------------------------------------------------------
  2582. function luaY:block(ls)
  2583. -- block -> chunk
  2584. local fs = ls.fs
  2585. local bl = {} -- BlockCnt
  2586. self:enterblock(fs, bl, false)
  2587. self:chunk(ls)
  2588. assert(bl.breaklist == luaK.NO_JUMP)
  2589. self:leaveblock(fs)
  2590. end
  2591.  
  2592. ------------------------------------------------------------------------
  2593. -- structure to chain all variables in the left-hand side of an
  2594. -- assignment
  2595. -- struct LHS_assign:
  2596. -- prev -- (table: struct LHS_assign)
  2597. -- v -- variable (global, local, upvalue, or indexed) (table: expdesc)
  2598. ------------------------------------------------------------------------
  2599.  
  2600. ------------------------------------------------------------------------
  2601. -- check whether, in an assignment to a local variable, the local variable
  2602. -- is needed in a previous assignment (to a table). If so, save original
  2603. -- local value in a safe place and use this safe copy in the previous
  2604. -- assignment.
  2605. -- * used in assignment()
  2606. ------------------------------------------------------------------------
  2607. function luaY:check_conflict(ls, lh, v)
  2608. local fs = ls.fs
  2609. local extra = fs.freereg -- eventual position to save local variable
  2610. local conflict = false
  2611. while lh do
  2612. if lh.v.k == "VINDEXED" then
  2613. if lh.v.info == v.info then -- conflict?
  2614. conflict = true
  2615. lh.v.info = extra -- previous assignment will use safe copy
  2616. end
  2617. if lh.v.aux == v.info then -- conflict?
  2618. conflict = true
  2619. lh.v.aux = extra -- previous assignment will use safe copy
  2620. end
  2621. end
  2622. lh = lh.prev
  2623. end
  2624. if conflict then
  2625. luaK:codeABC(fs, "OP_MOVE", fs.freereg, v.info, 0) -- make copy
  2626. luaK:reserveregs(fs, 1)
  2627. end
  2628. end
  2629.  
  2630. ------------------------------------------------------------------------
  2631. -- parse a variable assignment sequence
  2632. -- * recursively called
  2633. -- * used in exprstat()
  2634. ------------------------------------------------------------------------
  2635. function luaY:assignment(ls, lh, nvars)
  2636. local e = {} -- expdesc
  2637. -- test was: VLOCAL <= lh->v.k && lh->v.k <= VINDEXED
  2638. local c = lh.v.k
  2639. self:check_condition(ls, c == "VLOCAL" or c == "VUPVAL" or c == "VGLOBAL"
  2640. or c == "VINDEXED", "syntax error")
  2641. if self:testnext(ls, ",") then -- assignment -> ',' primaryexp assignment
  2642. local nv = {} -- LHS_assign
  2643. nv.v = {}
  2644. nv.prev = lh
  2645. self:primaryexp(ls, nv.v)
  2646. if nv.v.k == "VLOCAL" then
  2647. self:check_conflict(ls, lh, nv.v)
  2648. end
  2649. self:checklimit(ls.fs, nvars, self.LUAI_MAXCCALLS - ls.L.nCcalls,
  2650. "variables in assignment")
  2651. self:assignment(ls, nv, nvars + 1)
  2652. else -- assignment -> '=' explist1
  2653. self:checknext(ls, "=")
  2654. local nexps = self:explist1(ls, e)
  2655. if nexps ~= nvars then
  2656. self:adjust_assign(ls, nvars, nexps, e)
  2657. if nexps > nvars then
  2658. ls.fs.freereg = ls.fs.freereg - (nexps - nvars) -- remove extra values
  2659. end
  2660. else
  2661. luaK:setoneret(ls.fs, e) -- close last expression
  2662. luaK:storevar(ls.fs, lh.v, e)
  2663. return -- avoid default
  2664. end
  2665. end
  2666. self:init_exp(e, "VNONRELOC", ls.fs.freereg - 1) -- default assignment
  2667. luaK:storevar(ls.fs, lh.v, e)
  2668. end
  2669.  
  2670. ------------------------------------------------------------------------
  2671. -- parse condition in a repeat statement or an if control structure
  2672. -- * used in repeatstat(), test_then_block()
  2673. ------------------------------------------------------------------------
  2674. function luaY:cond(ls)
  2675. -- cond -> exp
  2676. local v = {} -- expdesc
  2677. self:expr(ls, v) -- read condition
  2678. if v.k == "VNIL" then v.k = "VFALSE" end -- 'falses' are all equal here
  2679. luaK:goiftrue(ls.fs, v)
  2680. return v.f
  2681. end
  2682.  
  2683. ------------------------------------------------------------------------
  2684. -- parse a break statement
  2685. -- * used in statements()
  2686. ------------------------------------------------------------------------
  2687. function luaY:breakstat(ls)
  2688. -- stat -> BREAK
  2689. local fs = ls.fs
  2690. local bl = fs.bl
  2691. local upval = false
  2692. while bl and not bl.isbreakable do
  2693. if bl.upval then upval = true end
  2694. bl = bl.previous
  2695. end
  2696. if not bl then
  2697. luaX:syntaxerror(ls, "no loop to break")
  2698. end
  2699. if upval then
  2700. luaK:codeABC(fs, "OP_CLOSE", bl.nactvar, 0, 0)
  2701. end
  2702. bl.breaklist = luaK:concat(fs, bl.breaklist, luaK:jump(fs))
  2703. end
  2704.  
  2705. ------------------------------------------------------------------------
  2706. -- parse a while-do control structure, body processed by block()
  2707. -- * with dynamic array sizes, MAXEXPWHILE + EXTRAEXP limits imposed by
  2708. -- the function's implementation can be removed
  2709. -- * used in statements()
  2710. ------------------------------------------------------------------------
  2711. function luaY:whilestat(ls, line)
  2712. -- whilestat -> WHILE cond DO block END
  2713. local fs = ls.fs
  2714. local bl = {} -- BlockCnt
  2715. luaX:next(ls) -- skip WHILE
  2716. local whileinit = luaK:getlabel(fs)
  2717. local condexit = self:cond(ls)
  2718. self:enterblock(fs, bl, true)
  2719. self:checknext(ls, "TK_DO")
  2720. self:block(ls)
  2721. luaK:patchlist(fs, luaK:jump(fs), whileinit)
  2722. self:check_match(ls, "TK_END", "TK_WHILE", line)
  2723. self:leaveblock(fs)
  2724. luaK:patchtohere(fs, condexit) -- false conditions finish the loop
  2725. end
  2726.  
  2727. ------------------------------------------------------------------------
  2728. -- parse a repeat-until control structure, body parsed by chunk()
  2729. -- * used in statements()
  2730. ------------------------------------------------------------------------
  2731. function luaY:repeatstat(ls, line)
  2732. -- repeatstat -> REPEAT block UNTIL cond
  2733. local fs = ls.fs
  2734. local repeat_init = luaK:getlabel(fs)
  2735. local bl1, bl2 = {}, {} -- BlockCnt
  2736. self:enterblock(fs, bl1, true) -- loop block
  2737. self:enterblock(fs, bl2, false) -- scope block
  2738. luaX:next(ls) -- skip REPEAT
  2739. self:chunk(ls)
  2740. self:check_match(ls, "TK_UNTIL", "TK_REPEAT", line)
  2741. local condexit = self:cond(ls) -- read condition (inside scope block)
  2742. if not bl2.upval then -- no upvalues?
  2743. self:leaveblock(fs) -- finish scope
  2744. luaK:patchlist(ls.fs, condexit, repeat_init) -- close the loop
  2745. else -- complete semantics when there are upvalues
  2746. self:breakstat(ls) -- if condition then break
  2747. luaK:patchtohere(ls.fs, condexit) -- else...
  2748. self:leaveblock(fs) -- finish scope...
  2749. luaK:patchlist(ls.fs, luaK:jump(fs), repeat_init) -- and repeat
  2750. end
  2751. self:leaveblock(fs) -- finish loop
  2752. end
  2753.  
  2754. ------------------------------------------------------------------------
  2755. -- parse the single expressions needed in numerical for loops
  2756. -- * used in fornum()
  2757. ------------------------------------------------------------------------
  2758. function luaY:exp1(ls)
  2759. local e = {} -- expdesc
  2760. self:expr(ls, e)
  2761. local k = e.k
  2762. luaK:exp2nextreg(ls.fs, e)
  2763. return k
  2764. end
  2765.  
  2766. ------------------------------------------------------------------------
  2767. -- parse a for loop body for both versions of the for loop
  2768. -- * used in fornum(), forlist()
  2769. ------------------------------------------------------------------------
  2770. function luaY:forbody(ls, base, line, nvars, isnum)
  2771. -- forbody -> DO block
  2772. local bl = {} -- BlockCnt
  2773. local fs = ls.fs
  2774. self:adjustlocalvars(ls, 3) -- control variables
  2775. self:checknext(ls, "TK_DO")
  2776. local prep = isnum and luaK:codeAsBx(fs, "OP_FORPREP", base, luaK.NO_JUMP)
  2777. or luaK:jump(fs)
  2778. self:enterblock(fs, bl, false) -- scope for declared variables
  2779. self:adjustlocalvars(ls, nvars)
  2780. luaK:reserveregs(fs, nvars)
  2781. self:block(ls)
  2782. self:leaveblock(fs) -- end of scope for declared variables
  2783. luaK:patchtohere(fs, prep)
  2784. local endfor = isnum and luaK:codeAsBx(fs, "OP_FORLOOP", base, luaK.NO_JUMP)
  2785. or luaK:codeABC(fs, "OP_TFORLOOP", base, 0, nvars)
  2786. luaK:fixline(fs, line) -- pretend that `OP_FOR' starts the loop
  2787. luaK:patchlist(fs, isnum and endfor or luaK:jump(fs), prep + 1)
  2788. end
  2789.  
  2790. ------------------------------------------------------------------------
  2791. -- parse a numerical for loop, calls forbody()
  2792. -- * used in forstat()
  2793. ------------------------------------------------------------------------
  2794. function luaY:fornum(ls, varname, line)
  2795. -- fornum -> NAME = exp1,exp1[,exp1] forbody
  2796. local fs = ls.fs
  2797. local base = fs.freereg
  2798. self:new_localvarliteral(ls, "(for index)", 0)
  2799. self:new_localvarliteral(ls, "(for limit)", 1)
  2800. self:new_localvarliteral(ls, "(for step)", 2)
  2801. self:new_localvar(ls, varname, 3)
  2802. self:checknext(ls, '=')
  2803. self:exp1(ls) -- initial value
  2804. self:checknext(ls, ",")
  2805. self:exp1(ls) -- limit
  2806. if self:testnext(ls, ",") then
  2807. self:exp1(ls) -- optional step
  2808. else -- default step = 1
  2809. luaK:codeABx(fs, "OP_LOADK", fs.freereg, luaK:numberK(fs, 1))
  2810. luaK:reserveregs(fs, 1)
  2811. end
  2812. self:forbody(ls, base, line, 1, true)
  2813. end
  2814.  
  2815. ------------------------------------------------------------------------
  2816. -- parse a generic for loop, calls forbody()
  2817. -- * used in forstat()
  2818. ------------------------------------------------------------------------
  2819. function luaY:forlist(ls, indexname)
  2820. -- forlist -> NAME {,NAME} IN explist1 forbody
  2821. local fs = ls.fs
  2822. local e = {} -- expdesc
  2823. local nvars = 0
  2824. local base = fs.freereg
  2825. -- create control variables
  2826. self:new_localvarliteral(ls, "(for generator)", nvars)
  2827. nvars = nvars + 1
  2828. self:new_localvarliteral(ls, "(for state)", nvars)
  2829. nvars = nvars + 1
  2830. self:new_localvarliteral(ls, "(for control)", nvars)
  2831. nvars = nvars + 1
  2832. -- create declared variables
  2833. self:new_localvar(ls, indexname, nvars)
  2834. nvars = nvars + 1
  2835. while self:testnext(ls, ",") do
  2836. self:new_localvar(ls, self:str_checkname(ls), nvars)
  2837. nvars = nvars + 1
  2838. end
  2839. self:checknext(ls, "TK_IN")
  2840. local line = ls.linenumber
  2841. self:adjust_assign(ls, 3, self:explist1(ls, e), e)
  2842. luaK:checkstack(fs, 3) -- extra space to call generator
  2843. self:forbody(ls, base, line, nvars - 3, false)
  2844. end
  2845.  
  2846. ------------------------------------------------------------------------
  2847. -- initial parsing for a for loop, calls fornum() or forlist()
  2848. -- * used in statements()
  2849. ------------------------------------------------------------------------
  2850. function luaY:forstat(ls, line)
  2851. -- forstat -> FOR (fornum | forlist) END
  2852. local fs = ls.fs
  2853. local bl = {} -- BlockCnt
  2854. self:enterblock(fs, bl, true) -- scope for loop and control variables
  2855. luaX:next(ls) -- skip `for'
  2856. local varname = self:str_checkname(ls) -- first variable name
  2857. local c = ls.t.token
  2858. if c == "=" then
  2859. self:fornum(ls, varname, line)
  2860. elseif c == "," or c == "TK_IN" then
  2861. self:forlist(ls, varname)
  2862. else
  2863. luaX:syntaxerror(ls, self:LUA_QL("=").." or "..self:LUA_QL("in").." expected")
  2864. end
  2865. self:check_match(ls, "TK_END", "TK_FOR", line)
  2866. self:leaveblock(fs) -- loop scope (`break' jumps to this point)
  2867. end
  2868.  
  2869. ------------------------------------------------------------------------
  2870. -- parse part of an if control structure, including the condition
  2871. -- * used in ifstat()
  2872. ------------------------------------------------------------------------
  2873. function luaY:test_then_block(ls)
  2874. -- test_then_block -> [IF | ELSEIF] cond THEN block
  2875. luaX:next(ls) -- skip IF or ELSEIF
  2876. local condexit = self:cond(ls)
  2877. self:checknext(ls, "TK_THEN")
  2878. self:block(ls) -- `then' part
  2879. return condexit
  2880. end
  2881.  
  2882. ------------------------------------------------------------------------
  2883. -- parse an if control structure
  2884. -- * used in statements()
  2885. ------------------------------------------------------------------------
  2886. function luaY:ifstat(ls, line)
  2887. -- ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END
  2888. local fs = ls.fs
  2889. local escapelist = luaK.NO_JUMP
  2890. local flist = self:test_then_block(ls) -- IF cond THEN block
  2891. while ls.t.token == "TK_ELSEIF" do
  2892. escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  2893. luaK:patchtohere(fs, flist)
  2894. flist = self:test_then_block(ls) -- ELSEIF cond THEN block
  2895. end
  2896. if ls.t.token == "TK_ELSE" then
  2897. escapelist = luaK:concat(fs, escapelist, luaK:jump(fs))
  2898. luaK:patchtohere(fs, flist)
  2899. luaX:next(ls) -- skip ELSE (after patch, for correct line info)
  2900. self:block(ls) -- 'else' part
  2901. else
  2902. escapelist = luaK:concat(fs, escapelist, flist)
  2903. end
  2904. luaK:patchtohere(fs, escapelist)
  2905. self:check_match(ls, "TK_END", "TK_IF", line)
  2906. end
  2907.  
  2908. ------------------------------------------------------------------------
  2909. -- parse a local function statement
  2910. -- * used in statements()
  2911. ------------------------------------------------------------------------
  2912. function luaY:localfunc(ls)
  2913. local v, b = {}, {} -- expdesc
  2914. local fs = ls.fs
  2915. self:new_localvar(ls, self:str_checkname(ls), 0)
  2916. self:init_exp(v, "VLOCAL", fs.freereg)
  2917. luaK:reserveregs(fs, 1)
  2918. self:adjustlocalvars(ls, 1)
  2919. self:body(ls, b, false, ls.linenumber)
  2920. luaK:storevar(fs, v, b)
  2921. -- debug information will only see the variable after this point!
  2922. self:getlocvar(fs, fs.nactvar - 1).startpc = fs.pc
  2923. end
  2924.  
  2925. ------------------------------------------------------------------------
  2926. -- parse a local variable declaration statement
  2927. -- * used in statements()
  2928. ------------------------------------------------------------------------
  2929. function luaY:localstat(ls)
  2930. -- stat -> LOCAL NAME {',' NAME} ['=' explist1]
  2931. local nvars = 0
  2932. local nexps
  2933. local e = {} -- expdesc
  2934. repeat
  2935. self:new_localvar(ls, self:str_checkname(ls), nvars)
  2936. nvars = nvars + 1
  2937. until not self:testnext(ls, ",")
  2938. if self:testnext(ls, "=") then
  2939. nexps = self:explist1(ls, e)
  2940. else
  2941. e.k = "VVOID"
  2942. nexps = 0
  2943. end
  2944. self:adjust_assign(ls, nvars, nexps, e)
  2945. self:adjustlocalvars(ls, nvars)
  2946. end
  2947.  
  2948. ------------------------------------------------------------------------
  2949. -- parse a function name specification
  2950. -- * used in funcstat()
  2951. ------------------------------------------------------------------------
  2952. function luaY:funcname(ls, v)
  2953. -- funcname -> NAME {field} [':' NAME]
  2954. local needself = false
  2955. self:singlevar(ls, v)
  2956. while ls.t.token == "." do
  2957. self:field(ls, v)
  2958. end
  2959. if ls.t.token == ":" then
  2960. needself = true
  2961. self:field(ls, v)
  2962. end
  2963. return needself
  2964. end
  2965.  
  2966. ------------------------------------------------------------------------
  2967. -- parse a function statement
  2968. -- * used in statements()
  2969. ------------------------------------------------------------------------
  2970. function luaY:funcstat(ls, line)
  2971. -- funcstat -> FUNCTION funcname body
  2972. local v, b = {}, {} -- expdesc
  2973. luaX:next(ls) -- skip FUNCTION
  2974. local needself = self:funcname(ls, v)
  2975. self:body(ls, b, needself, line)
  2976. luaK:storevar(ls.fs, v, b)
  2977. luaK:fixline(ls.fs, line) -- definition 'happens' in the first line
  2978. end
  2979.  
  2980. ------------------------------------------------------------------------
  2981. -- parse a function call with no returns or an assignment statement
  2982. -- * used in statements()
  2983. ------------------------------------------------------------------------
  2984. function luaY:exprstat(ls)
  2985. -- stat -> func | assignment
  2986. local fs = ls.fs
  2987. local v = {} -- LHS_assign
  2988. v.v = {}
  2989. self:primaryexp(ls, v.v)
  2990. if v.v.k == "VCALL" then -- stat -> func
  2991. luaP:SETARG_C(luaK:getcode(fs, v.v), 1) -- call statement uses no results
  2992. else -- stat -> assignment
  2993. v.prev = nil
  2994. self:assignment(ls, v, 1)
  2995. end
  2996. end
  2997.  
  2998. ------------------------------------------------------------------------
  2999. -- parse a return statement
  3000. -- * used in statements()
  3001. ------------------------------------------------------------------------
  3002. function luaY:retstat(ls)
  3003. -- stat -> RETURN explist
  3004. local fs = ls.fs
  3005. local e = {} -- expdesc
  3006. local first, nret -- registers with returned values
  3007. luaX:next(ls) -- skip RETURN
  3008. if self:block_follow(ls.t.token) or ls.t.token == ";" then
  3009. first, nret = 0, 0 -- return no values
  3010. else
  3011. nret = self:explist1(ls, e) -- optional return values
  3012. if self:hasmultret(e.k) then
  3013. luaK:setmultret(fs, e)
  3014. if e.k == "VCALL" and nret == 1 then -- tail call?
  3015. luaP:SET_OPCODE(luaK:getcode(fs, e), "OP_TAILCALL")
  3016. assert(luaP:GETARG_A(luaK:getcode(fs, e)) == fs.nactvar)
  3017. end
  3018. first = fs.nactvar
  3019. nret = self.LUA_MULTRET -- return all values
  3020. else
  3021. if nret == 1 then -- only one single value?
  3022. first = luaK:exp2anyreg(fs, e)
  3023. else
  3024. luaK:exp2nextreg(fs, e) -- values must go to the 'stack'
  3025. first = fs.nactvar -- return all 'active' values
  3026. assert(nret == fs.freereg - first)
  3027. end
  3028. end--if
  3029. end--if
  3030. luaK:ret(fs, first, nret)
  3031. end
  3032.  
  3033. ------------------------------------------------------------------------
  3034. -- initial parsing for statements, calls a lot of functions
  3035. -- * returns boolean instead of 0|1
  3036. -- * used in chunk()
  3037. ------------------------------------------------------------------------
  3038. function luaY:statement(ls)
  3039. local line = ls.linenumber -- may be needed for error messages
  3040. local c = ls.t.token
  3041. if c == "TK_IF" then -- stat -> ifstat
  3042. self:ifstat(ls, line)
  3043. return false
  3044. elseif c == "TK_WHILE" then -- stat -> whilestat
  3045. self:whilestat(ls, line)
  3046. return false
  3047. elseif c == "TK_DO" then -- stat -> DO block END
  3048. luaX:next(ls) -- skip DO
  3049. self:block(ls)
  3050. self:check_match(ls, "TK_END", "TK_DO", line)
  3051. return false
  3052. elseif c == "TK_FOR" then -- stat -> forstat
  3053. self:forstat(ls, line)
  3054. return false
  3055. elseif c == "TK_REPEAT" then -- stat -> repeatstat
  3056. self:repeatstat(ls, line)
  3057. return false
  3058. elseif c == "TK_FUNCTION" then -- stat -> funcstat
  3059. self:funcstat(ls, line)
  3060. return false
  3061. elseif c == "TK_LOCAL" then -- stat -> localstat
  3062. luaX:next(ls) -- skip LOCAL
  3063. if self:testnext(ls, "TK_FUNCTION") then -- local function?
  3064. self:localfunc(ls)
  3065. else
  3066. self:localstat(ls)
  3067. end
  3068. return false
  3069. elseif c == "TK_RETURN" then -- stat -> retstat
  3070. self:retstat(ls)
  3071. return true -- must be last statement
  3072. elseif c == "TK_BREAK" then -- stat -> breakstat
  3073. luaX:next(ls) -- skip BREAK
  3074. self:breakstat(ls)
  3075. return true -- must be last statement
  3076. else
  3077. self:exprstat(ls)
  3078. return false -- to avoid warnings
  3079. end--if c
  3080. end
  3081.  
  3082. ------------------------------------------------------------------------
  3083. -- parse a chunk, which consists of a bunch of statements
  3084. -- * used in parser(), body(), block(), repeatstat()
  3085. ------------------------------------------------------------------------
  3086. function luaY:chunk(ls)
  3087. -- chunk -> { stat [';'] }
  3088. local islast = false
  3089. self:enterlevel(ls)
  3090. while not islast and not self:block_follow(ls.t.token) do
  3091. islast = self:statement(ls)
  3092. self:testnext(ls, ";")
  3093. assert(ls.fs.f.maxstacksize >= ls.fs.freereg and
  3094. ls.fs.freereg >= ls.fs.nactvar)
  3095. ls.fs.freereg = ls.fs.nactvar -- free registers
  3096. end
  3097. self:leavelevel(ls)
  3098. end
  3099.  
  3100. -- }======================================================================
  3101. return luaY
  3102. end))
  3103. ModuleScript19.Name = "LuaK"
  3104. ModuleScript19.Parent = ModuleScript15
  3105. table.insert(cors,sandbox(ModuleScript19,function()
  3106. --[[--------------------------------------------------------------------
  3107.  
  3108. lcode.lua
  3109. Lua 5 code generator in Lua
  3110. This file is part of Yueliang.
  3111.  
  3112. Copyright (c) 2005-2007 Kein-Hong Man <khman@users.sf.net>
  3113. The COPYRIGHT file describes the conditions
  3114. under which this software may be distributed.
  3115.  
  3116. See the ChangeLog for more information.
  3117.  
  3118. ----------------------------------------------------------------------]]
  3119.  
  3120. --[[--------------------------------------------------------------------
  3121. -- Notes:
  3122. -- * one function manipulate a pointer argument with a simple data type
  3123. -- (can't be emulated by a table, ambiguous), now returns that value:
  3124. -- luaK:concat(fs, l1, l2)
  3125. -- * luaM_growvector uses the faux luaY:growvector, for limit checking
  3126. -- * some function parameters changed to boolean, additional code
  3127. -- translates boolean back to 1/0 for instruction fields
  3128. --
  3129. -- Not implemented:
  3130. -- * NOTE there is a failed assert in luaK:addk, a porting problem
  3131. --
  3132. -- Added:
  3133. -- * constant MAXSTACK from llimits.h
  3134. -- * luaK:ttisnumber(o) (from lobject.h)
  3135. -- * luaK:nvalue(o) (from lobject.h)
  3136. -- * luaK:setnilvalue(o) (from lobject.h)
  3137. -- * luaK:setnvalue(o, x) (from lobject.h)
  3138. -- * luaK:setbvalue(o, x) (from lobject.h)
  3139. -- * luaK:sethvalue(o, x) (from lobject.h), parameter L deleted
  3140. -- * luaK:setsvalue(o, x) (from lobject.h), parameter L deleted
  3141. -- * luaK:numadd, luaK:numsub, luaK:nummul, luaK:numdiv, luaK:nummod,
  3142. -- luaK:numpow, luaK:numunm, luaK:numisnan (from luaconf.h)
  3143. -- * copyexp(e1, e2) added in luaK:posfix to copy expdesc struct
  3144. --
  3145. -- Changed in 5.1.x:
  3146. -- * enum BinOpr has a new entry, OPR_MOD
  3147. -- * enum UnOpr has a new entry, OPR_LEN
  3148. -- * binopistest, unused in 5.0.x, has been deleted
  3149. -- * macro setmultret is new
  3150. -- * functions isnumeral, luaK_ret, boolK are new
  3151. -- * funcion nilK was named nil_constant in 5.0.x
  3152. -- * function interface changed: need_value, patchtestreg, concat
  3153. -- * TObject now a TValue
  3154. -- * functions luaK_setreturns, luaK_setoneret are new
  3155. -- * function luaK:setcallreturns deleted, to be replaced by:
  3156. -- luaK:setmultret, luaK:ret, luaK:setreturns, luaK:setoneret
  3157. -- * functions constfolding, codearith, codecomp are new
  3158. -- * luaK:codebinop has been deleted
  3159. -- * function luaK_setlist is new
  3160. -- * OPR_MULT renamed to OPR_MUL
  3161. ----------------------------------------------------------------------]]
  3162.  
  3163. -- requires luaP, luaX, luaY
  3164. local luaK = {}
  3165. local luaP = require(script.Parent.LuaP)
  3166. local luaX = require(script.Parent.LuaX)
  3167.  
  3168. ------------------------------------------------------------------------
  3169. -- constants used by code generator
  3170. ------------------------------------------------------------------------
  3171. -- maximum stack for a Lua function
  3172. luaK.MAXSTACK = 250 -- (from llimits.h)
  3173.  
  3174. --[[--------------------------------------------------------------------
  3175. -- other functions
  3176. ----------------------------------------------------------------------]]
  3177.  
  3178. ------------------------------------------------------------------------
  3179. -- emulation of TValue macros (these are from lobject.h)
  3180. -- * TValue is a table since lcode passes references around
  3181. -- * tt member field removed, using Lua's type() instead
  3182. -- * for setsvalue, sethvalue, parameter L (deleted here) in lobject.h
  3183. -- is used in an assert for testing, see checkliveness(g,obj)
  3184. ------------------------------------------------------------------------
  3185. function luaK:ttisnumber(o)
  3186. if o then return type(o.value) == "number" else return false end
  3187. end
  3188. function luaK:nvalue(o) return o.value end
  3189. function luaK:setnilvalue(o) o.value = nil end
  3190. function luaK:setsvalue(o, x) o.value = x end
  3191. luaK.setnvalue = luaK.setsvalue
  3192. luaK.sethvalue = luaK.setsvalue
  3193. luaK.setbvalue = luaK.setsvalue
  3194.  
  3195. ------------------------------------------------------------------------
  3196. -- The luai_num* macros define the primitive operations over numbers.
  3197. -- * this is not the entire set of primitive operations from luaconf.h
  3198. -- * used in luaK:constfolding()
  3199. ------------------------------------------------------------------------
  3200. function luaK:numadd(a, b) return a + b end
  3201. function luaK:numsub(a, b) return a - b end
  3202. function luaK:nummul(a, b) return a * b end
  3203. function luaK:numdiv(a, b) return a / b end
  3204. function luaK:nummod(a, b) return a % b end
  3205. -- ((a) - floor((a)/(b))*(b)) /* actual, for reference */
  3206. function luaK:numpow(a, b) return a ^ b end
  3207. function luaK:numunm(a) return -a end
  3208. function luaK:numisnan(a) return not a == a end
  3209. -- a NaN cannot equal another NaN
  3210.  
  3211. --[[--------------------------------------------------------------------
  3212. -- code generator functions
  3213. ----------------------------------------------------------------------]]
  3214.  
  3215. ------------------------------------------------------------------------
  3216. -- Marks the end of a patch list. It is an invalid value both as an absolute
  3217. -- address, and as a list link (would link an element to itself).
  3218. ------------------------------------------------------------------------
  3219. luaK.NO_JUMP = -1
  3220.  
  3221. ------------------------------------------------------------------------
  3222. -- grep "ORDER OPR" if you change these enums
  3223. ------------------------------------------------------------------------
  3224. luaK.BinOpr = {
  3225. OPR_ADD = 0, OPR_SUB = 1, OPR_MUL = 2, OPR_DIV = 3, OPR_MOD = 4, OPR_POW = 5,
  3226. OPR_CONCAT = 6,
  3227. OPR_NE = 7, OPR_EQ = 8,
  3228. OPR_LT = 9, OPR_LE = 10, OPR_GT = 11, OPR_GE = 12,
  3229. OPR_AND = 13, OPR_OR = 14,
  3230. OPR_NOBINOPR = 15,
  3231. }
  3232.  
  3233. -- * UnOpr is used by luaK:prefix's op argument, but not directly used
  3234. -- because the function receives the symbols as strings, e.g. "OPR_NOT"
  3235. luaK.UnOpr = {
  3236. OPR_MINUS = 0, OPR_NOT = 1, OPR_LEN = 2, OPR_NOUNOPR = 3
  3237. }
  3238.  
  3239. ------------------------------------------------------------------------
  3240. -- returns the instruction object for given e (expdesc), was a macro
  3241. ------------------------------------------------------------------------
  3242. function luaK:getcode(fs, e)
  3243. return fs.f.code[e.info]
  3244. end
  3245.  
  3246. ------------------------------------------------------------------------
  3247. -- codes an instruction with a signed Bx (sBx) field, was a macro
  3248. -- * used in luaK:jump(), (lparser) luaY:forbody()
  3249. ------------------------------------------------------------------------
  3250. function luaK:codeAsBx(fs, o, A, sBx)
  3251. return self:codeABx(fs, o, A, sBx + luaP.MAXARG_sBx)
  3252. end
  3253.  
  3254. ------------------------------------------------------------------------
  3255. -- set the expdesc e instruction for multiple returns, was a macro
  3256. ------------------------------------------------------------------------
  3257. function luaK:setmultret(fs, e)
  3258. self:setreturns(fs, e, luaY.LUA_MULTRET)
  3259. end
  3260.  
  3261. ------------------------------------------------------------------------
  3262. -- there is a jump if patch lists are not identical, was a macro
  3263. -- * used in luaK:exp2reg(), luaK:exp2anyreg(), luaK:exp2val()
  3264. ------------------------------------------------------------------------
  3265. function luaK:hasjumps(e)
  3266. return e.t ~= e.f
  3267. end
  3268.  
  3269. ------------------------------------------------------------------------
  3270. -- true if the expression is a constant number (for constant folding)
  3271. -- * used in constfolding(), infix()
  3272. ------------------------------------------------------------------------
  3273. function luaK:isnumeral(e)
  3274. return e.k == "VKNUM" and e.t == self.NO_JUMP and e.f == self.NO_JUMP
  3275. end
  3276.  
  3277. ------------------------------------------------------------------------
  3278. -- codes loading of nil, optimization done if consecutive locations
  3279. -- * used in luaK:discharge2reg(), (lparser) luaY:adjust_assign()
  3280. ------------------------------------------------------------------------
  3281. function luaK:_nil(fs, from, n)
  3282. if fs.pc > fs.lasttarget then -- no jumps to current position?
  3283. if fs.pc == 0 then -- function start?
  3284. if from >= fs.nactvar then
  3285. return -- positions are already clean
  3286. end
  3287. else
  3288. local previous = fs.f.code[fs.pc - 1]
  3289. if luaP:GET_OPCODE(previous) == "OP_LOADNIL" then
  3290. local pfrom = luaP:GETARG_A(previous)
  3291. local pto = luaP:GETARG_B(previous)
  3292. if pfrom <= from and from <= pto + 1 then -- can connect both?
  3293. if from + n - 1 > pto then
  3294. luaP:SETARG_B(previous, from + n - 1)
  3295. end
  3296. return
  3297. end
  3298. end
  3299. end
  3300. end
  3301. self:codeABC(fs, "OP_LOADNIL", from, from + n - 1, 0) -- else no optimization
  3302. end
  3303.  
  3304. ------------------------------------------------------------------------
  3305. --
  3306. -- * used in multiple locations
  3307. ------------------------------------------------------------------------
  3308. function luaK:jump(fs)
  3309. local jpc = fs.jpc -- save list of jumps to here
  3310. fs.jpc = self.NO_JUMP
  3311. local j = self:codeAsBx(fs, "OP_JMP", 0, self.NO_JUMP)
  3312. j = self:concat(fs, j, jpc) -- keep them on hold
  3313. return j
  3314. end
  3315.  
  3316. ------------------------------------------------------------------------
  3317. -- codes a RETURN instruction
  3318. -- * used in luaY:close_func(), luaY:retstat()
  3319. ------------------------------------------------------------------------
  3320. function luaK:ret(fs, first, nret)
  3321. self:codeABC(fs, "OP_RETURN", first, nret + 1, 0)
  3322. end
  3323.  
  3324. ------------------------------------------------------------------------
  3325. --
  3326. -- * used in luaK:jumponcond(), luaK:codecomp()
  3327. ------------------------------------------------------------------------
  3328. function luaK:condjump(fs, op, A, B, C)
  3329. self:codeABC(fs, op, A, B, C)
  3330. return self:jump(fs)
  3331. end
  3332.  
  3333. ------------------------------------------------------------------------
  3334. --
  3335. -- * used in luaK:patchlistaux(), luaK:concat()
  3336. ------------------------------------------------------------------------
  3337. function luaK:fixjump(fs, pc, dest)
  3338. local jmp = fs.f.code[pc]
  3339. local offset = dest - (pc + 1)
  3340. assert(dest ~= self.NO_JUMP)
  3341. if math.abs(offset) > luaP.MAXARG_sBx then
  3342. luaX:syntaxerror(fs.ls, "control structure too long")
  3343. end
  3344. luaP:SETARG_sBx(jmp, offset)
  3345. end
  3346.  
  3347. ------------------------------------------------------------------------
  3348. -- returns current 'pc' and marks it as a jump target (to avoid wrong
  3349. -- optimizations with consecutive instructions not in the same basic block).
  3350. -- * used in multiple locations
  3351. -- * fs.lasttarget tested only by luaK:_nil() when optimizing OP_LOADNIL
  3352. ------------------------------------------------------------------------
  3353. function luaK:getlabel(fs)
  3354. fs.lasttarget = fs.pc
  3355. return fs.pc
  3356. end
  3357.  
  3358. ------------------------------------------------------------------------
  3359. --
  3360. -- * used in luaK:need_value(), luaK:removevalues(), luaK:patchlistaux(),
  3361. -- luaK:concat()
  3362. ------------------------------------------------------------------------
  3363. function luaK:getjump(fs, pc)
  3364. local offset = luaP:GETARG_sBx(fs.f.code[pc])
  3365. if offset == self.NO_JUMP then -- point to itself represents end of list
  3366. return self.NO_JUMP -- end of list
  3367. else
  3368. return (pc + 1) + offset -- turn offset into absolute position
  3369. end
  3370. end
  3371.  
  3372. ------------------------------------------------------------------------
  3373. --
  3374. -- * used in luaK:need_value(), luaK:patchtestreg(), luaK:invertjump()
  3375. ------------------------------------------------------------------------
  3376. function luaK:getjumpcontrol(fs, pc)
  3377. local pi = fs.f.code[pc]
  3378. local ppi = fs.f.code[pc - 1]
  3379. if pc >= 1 and luaP:testTMode(luaP:GET_OPCODE(ppi)) ~= 0 then
  3380. return ppi
  3381. else
  3382. return pi
  3383. end
  3384. end
  3385.  
  3386. ------------------------------------------------------------------------
  3387. -- check whether list has any jump that do not produce a value
  3388. -- (or produce an inverted value)
  3389. -- * return value changed to boolean
  3390. -- * used only in luaK:exp2reg()
  3391. ------------------------------------------------------------------------
  3392. function luaK:need_value(fs, list)
  3393. while list ~= self.NO_JUMP do
  3394. local i = self:getjumpcontrol(fs, list)
  3395. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then return true end
  3396. list = self:getjump(fs, list)
  3397. end
  3398. return false -- not found
  3399. end
  3400.  
  3401. ------------------------------------------------------------------------
  3402. --
  3403. -- * used in luaK:removevalues(), luaK:patchlistaux()
  3404. ------------------------------------------------------------------------
  3405. function luaK:patchtestreg(fs, node, reg)
  3406. local i = self:getjumpcontrol(fs, node)
  3407. if luaP:GET_OPCODE(i) ~= "OP_TESTSET" then
  3408. return false -- cannot patch other instructions
  3409. end
  3410. if reg ~= luaP.NO_REG and reg ~= luaP:GETARG_B(i) then
  3411. luaP:SETARG_A(i, reg)
  3412. else -- no register to put value or register already has the value
  3413. -- due to use of a table as i, i cannot be replaced by another table
  3414. -- so the following is required; there is no change to ARG_C
  3415. luaP:SET_OPCODE(i, "OP_TEST")
  3416. local b = luaP:GETARG_B(i)
  3417. luaP:SETARG_A(i, b)
  3418. luaP:SETARG_B(i, 0)
  3419. -- *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); /* C */
  3420. end
  3421. return true
  3422. end
  3423.  
  3424. ------------------------------------------------------------------------
  3425. --
  3426. -- * used only in luaK:codenot()
  3427. ------------------------------------------------------------------------
  3428. function luaK:removevalues(fs, list)
  3429. while list ~= self.NO_JUMP do
  3430. self:patchtestreg(fs, list, luaP.NO_REG)
  3431. list = self:getjump(fs, list)
  3432. end
  3433. end
  3434.  
  3435. ------------------------------------------------------------------------
  3436. --
  3437. -- * used in luaK:dischargejpc(), luaK:patchlist(), luaK:exp2reg()
  3438. ------------------------------------------------------------------------
  3439. function luaK:patchlistaux(fs, list, vtarget, reg, dtarget)
  3440. while list ~= self.NO_JUMP do
  3441. local _next = self:getjump(fs, list)
  3442. if self:patchtestreg(fs, list, reg) then
  3443. self:fixjump(fs, list, vtarget)
  3444. else
  3445. self:fixjump(fs, list, dtarget) -- jump to default target
  3446. end
  3447. list = _next
  3448. end
  3449. end
  3450.  
  3451. ------------------------------------------------------------------------
  3452. --
  3453. -- * used only in luaK:code()
  3454. ------------------------------------------------------------------------
  3455. function luaK:dischargejpc(fs)
  3456. self:patchlistaux(fs, fs.jpc, fs.pc, luaP.NO_REG, fs.pc)
  3457. fs.jpc = self.NO_JUMP
  3458. end
  3459.  
  3460. ------------------------------------------------------------------------
  3461. --
  3462. -- * used in (lparser) luaY:whilestat(), luaY:repeatstat(), luaY:forbody()
  3463. ------------------------------------------------------------------------
  3464. function luaK:patchlist(fs, list, target)
  3465. if target == fs.pc then
  3466. self:patchtohere(fs, list)
  3467. else
  3468. assert(target < fs.pc)
  3469. self:patchlistaux(fs, list, target, luaP.NO_REG, target)
  3470. end
  3471. end
  3472.  
  3473. ------------------------------------------------------------------------
  3474. --
  3475. -- * used in multiple locations
  3476. ------------------------------------------------------------------------
  3477. function luaK:patchtohere(fs, list)
  3478. self:getlabel(fs)
  3479. fs.jpc = self:concat(fs, fs.jpc, list)
  3480. end
  3481.  
  3482. ------------------------------------------------------------------------
  3483. -- * l1 was a pointer, now l1 is returned and callee assigns the value
  3484. -- * used in multiple locations
  3485. ------------------------------------------------------------------------
  3486. function luaK:concat(fs, l1, l2)
  3487. if l2 == self.NO_JUMP then return l1
  3488. elseif l1 == self.NO_JUMP then
  3489. return l2
  3490. else
  3491. local list = l1
  3492. local _next = self:getjump(fs, list)
  3493. while _next ~= self.NO_JUMP do -- find last element
  3494. list = _next
  3495. _next = self:getjump(fs, list)
  3496. end
  3497. self:fixjump(fs, list, l2)
  3498. end
  3499. return l1
  3500. end
  3501.  
  3502. ------------------------------------------------------------------------
  3503. --
  3504. -- * used in luaK:reserveregs(), (lparser) luaY:forlist()
  3505. ------------------------------------------------------------------------
  3506. function luaK:checkstack(fs, n)
  3507. local newstack = fs.freereg + n
  3508. if newstack > fs.f.maxstacksize then
  3509. if newstack >= self.MAXSTACK then
  3510. luaX:syntaxerror(fs.ls, "function or expression too complex")
  3511. end
  3512. fs.f.maxstacksize = newstack
  3513. end
  3514. end
  3515.  
  3516. ------------------------------------------------------------------------
  3517. --
  3518. -- * used in multiple locations
  3519. ------------------------------------------------------------------------
  3520. function luaK:reserveregs(fs, n)
  3521. self:checkstack(fs, n)
  3522. fs.freereg = fs.freereg + n
  3523. end
  3524.  
  3525. ------------------------------------------------------------------------
  3526. --
  3527. -- * used in luaK:freeexp(), luaK:dischargevars()
  3528. ------------------------------------------------------------------------
  3529. function luaK:freereg(fs, reg)
  3530. if not luaP:ISK(reg) and reg >= fs.nactvar then
  3531. fs.freereg = fs.freereg - 1
  3532. assert(reg == fs.freereg)
  3533. end
  3534. end
  3535.  
  3536. ------------------------------------------------------------------------
  3537. --
  3538. -- * used in multiple locations
  3539. ------------------------------------------------------------------------
  3540. function luaK:freeexp(fs, e)
  3541. if e.k == "VNONRELOC" then
  3542. self:freereg(fs, e.info)
  3543. end
  3544. end
  3545.  
  3546. ------------------------------------------------------------------------
  3547. -- * TODO NOTE implementation is not 100% correct, since the assert fails
  3548. -- * luaH_set, setobj deleted; direct table access used instead
  3549. -- * used in luaK:stringK(), luaK:numberK(), luaK:boolK(), luaK:nilK()
  3550. ------------------------------------------------------------------------
  3551. function luaK:addk(fs, k, v)
  3552. local L = fs.L
  3553. local idx = fs.h[k.value]
  3554. --TValue *idx = luaH_set(L, fs->h, k); /* C */
  3555. local f = fs.f
  3556. if self:ttisnumber(idx) then
  3557. --TODO this assert currently FAILS (last tested for 5.0.2)
  3558. --assert(fs.f.k[self:nvalue(idx)] == v)
  3559. --assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v)); /* C */
  3560. return self:nvalue(idx)
  3561. else -- constant not found; create a new entry
  3562. idx = {}
  3563. self:setnvalue(idx, fs.nk)
  3564. fs.h[k.value] = idx
  3565. -- setnvalue(idx, cast_num(fs->nk)); /* C */
  3566. luaY:growvector(L, f.k, fs.nk, f.sizek, nil,
  3567. luaP.MAXARG_Bx, "constant table overflow")
  3568. -- loop to initialize empty f.k positions not required
  3569. f.k[fs.nk] = v
  3570. -- setobj(L, &f->k[fs->nk], v); /* C */
  3571. -- luaC_barrier(L, f, v); /* GC */
  3572. local nk = fs.nk
  3573. fs.nk = fs.nk + 1
  3574. return nk
  3575. end
  3576.  
  3577. end
  3578.  
  3579. ------------------------------------------------------------------------
  3580. -- creates and sets a string object
  3581. -- * used in (lparser) luaY:codestring(), luaY:singlevar()
  3582. ------------------------------------------------------------------------
  3583. function luaK:stringK(fs, s)
  3584. local o = {} -- TValue
  3585. self:setsvalue(o, s)
  3586. return self:addk(fs, o, o)
  3587. end
  3588.  
  3589. ------------------------------------------------------------------------
  3590. -- creates and sets a number object
  3591. -- * used in luaK:prefix() for negative (or negation of) numbers
  3592. -- * used in (lparser) luaY:simpleexp(), luaY:fornum()
  3593. ------------------------------------------------------------------------
  3594. function luaK:numberK(fs, r)
  3595. local o = {} -- TValue
  3596. self:setnvalue(o, r)
  3597. return self:addk(fs, o, o)
  3598. end
  3599.  
  3600. ------------------------------------------------------------------------
  3601. -- creates and sets a boolean object
  3602. -- * used only in luaK:exp2RK()
  3603. ------------------------------------------------------------------------
  3604. function luaK:boolK(fs, b)
  3605. local o = {} -- TValue
  3606. self:setbvalue(o, b)
  3607. return self:addk(fs, o, o)
  3608. end
  3609.  
  3610. ------------------------------------------------------------------------
  3611. -- creates and sets a nil object
  3612. -- * used only in luaK:exp2RK()
  3613. ------------------------------------------------------------------------
  3614. function luaK:nilK(fs)
  3615. local k, v = {}, {} -- TValue
  3616. self:setnilvalue(v)
  3617. -- cannot use nil as key; instead use table itself to represent nil
  3618. self:sethvalue(k, fs.h)
  3619. return self:addk(fs, k, v)
  3620. end
  3621.  
  3622. ------------------------------------------------------------------------
  3623. --
  3624. -- * used in luaK:setmultret(), (lparser) luaY:adjust_assign()
  3625. ------------------------------------------------------------------------
  3626. function luaK:setreturns(fs, e, nresults)
  3627. if e.k == "VCALL" then -- expression is an open function call?
  3628. luaP:SETARG_C(self:getcode(fs, e), nresults + 1)
  3629. elseif e.k == "VVARARG" then
  3630. luaP:SETARG_B(self:getcode(fs, e), nresults + 1);
  3631. luaP:SETARG_A(self:getcode(fs, e), fs.freereg);
  3632. luaK:reserveregs(fs, 1)
  3633. end
  3634. end
  3635.  
  3636. ------------------------------------------------------------------------
  3637. --
  3638. -- * used in luaK:dischargevars(), (lparser) luaY:assignment()
  3639. ------------------------------------------------------------------------
  3640. function luaK:setoneret(fs, e)
  3641. if e.k == "VCALL" then -- expression is an open function call?
  3642. e.k = "VNONRELOC"
  3643. e.info = luaP:GETARG_A(self:getcode(fs, e))
  3644. elseif e.k == "VVARARG" then
  3645. luaP:SETARG_B(self:getcode(fs, e), 2)
  3646. e.k = "VRELOCABLE" -- can relocate its simple result
  3647. end
  3648. end
  3649.  
  3650. ------------------------------------------------------------------------
  3651. --
  3652. -- * used in multiple locations
  3653. ------------------------------------------------------------------------
  3654. function luaK:dischargevars(fs, e)
  3655. local k = e.k
  3656. if k == "VLOCAL" then
  3657. e.k = "VNONRELOC"
  3658. elseif k == "VUPVAL" then
  3659. e.info = self:codeABC(fs, "OP_GETUPVAL", 0, e.info, 0)
  3660. e.k = "VRELOCABLE"
  3661. elseif k == "VGLOBAL" then
  3662. e.info = self:codeABx(fs, "OP_GETGLOBAL", 0, e.info)
  3663. e.k = "VRELOCABLE"
  3664. elseif k == "VINDEXED" then
  3665. self:freereg(fs, e.aux)
  3666. self:freereg(fs, e.info)
  3667. e.info = self:codeABC(fs, "OP_GETTABLE", 0, e.info, e.aux)
  3668. e.k = "VRELOCABLE"
  3669. elseif k == "VVARARG" or k == "VCALL" then
  3670. self:setoneret(fs, e)
  3671. else
  3672. -- there is one value available (somewhere)
  3673. end
  3674. end
  3675.  
  3676. ------------------------------------------------------------------------
  3677. --
  3678. -- * used only in luaK:exp2reg()
  3679. ------------------------------------------------------------------------
  3680. function luaK:code_label(fs, A, b, jump)
  3681. self:getlabel(fs) -- those instructions may be jump targets
  3682. return self:codeABC(fs, "OP_LOADBOOL", A, b, jump)
  3683. end
  3684.  
  3685. ------------------------------------------------------------------------
  3686. --
  3687. -- * used in luaK:discharge2anyreg(), luaK:exp2reg()
  3688. ------------------------------------------------------------------------
  3689. function luaK:discharge2reg(fs, e, reg)
  3690. self:dischargevars(fs, e)
  3691. local k = e.k
  3692. if k == "VNIL" then
  3693. self:_nil(fs, reg, 1)
  3694. elseif k == "VFALSE" or k == "VTRUE" then
  3695. self:codeABC(fs, "OP_LOADBOOL", reg, (e.k == "VTRUE") and 1 or 0, 0)
  3696. elseif k == "VK" then
  3697. self:codeABx(fs, "OP_LOADK", reg, e.info)
  3698. elseif k == "VKNUM" then
  3699. self:codeABx(fs, "OP_LOADK", reg, self:numberK(fs, e.nval))
  3700. elseif k == "VRELOCABLE" then
  3701. local pc = self:getcode(fs, e)
  3702. luaP:SETARG_A(pc, reg)
  3703. elseif k == "VNONRELOC" then
  3704. if reg ~= e.info then
  3705. self:codeABC(fs, "OP_MOVE", reg, e.info, 0)
  3706. end
  3707. else
  3708. assert(e.k == "VVOID" or e.k == "VJMP")
  3709. return -- nothing to do...
  3710. end
  3711. e.info = reg
  3712. e.k = "VNONRELOC"
  3713. end
  3714.  
  3715. ------------------------------------------------------------------------
  3716. --
  3717. -- * used in luaK:jumponcond(), luaK:codenot()
  3718. ------------------------------------------------------------------------
  3719. function luaK:discharge2anyreg(fs, e)
  3720. if e.k ~= "VNONRELOC" then
  3721. self:reserveregs(fs, 1)
  3722. self:discharge2reg(fs, e, fs.freereg - 1)
  3723. end
  3724. end
  3725.  
  3726. ------------------------------------------------------------------------
  3727. --
  3728. -- * used in luaK:exp2nextreg(), luaK:exp2anyreg(), luaK:storevar()
  3729. ------------------------------------------------------------------------
  3730. function luaK:exp2reg(fs, e, reg)
  3731. self:discharge2reg(fs, e, reg)
  3732. if e.k == "VJMP" then
  3733. e.t = self:concat(fs, e.t, e.info) -- put this jump in 't' list
  3734. end
  3735. if self:hasjumps(e) then
  3736. local final -- position after whole expression
  3737. local p_f = self.NO_JUMP -- position of an eventual LOAD false
  3738. local p_t = self.NO_JUMP -- position of an eventual LOAD true
  3739. if self:need_value(fs, e.t) or self:need_value(fs, e.f) then
  3740. local fj = (e.k == "VJMP") and self.NO_JUMP or self:jump(fs)
  3741. p_f = self:code_label(fs, reg, 0, 1)
  3742. p_t = self:code_label(fs, reg, 1, 0)
  3743. self:patchtohere(fs, fj)
  3744. end
  3745. final = self:getlabel(fs)
  3746. self:patchlistaux(fs, e.f, final, reg, p_f)
  3747. self:patchlistaux(fs, e.t, final, reg, p_t)
  3748. end
  3749. e.f, e.t = self.NO_JUMP, self.NO_JUMP
  3750. e.info = reg
  3751. e.k = "VNONRELOC"
  3752. end
  3753.  
  3754. ------------------------------------------------------------------------
  3755. --
  3756. -- * used in multiple locations
  3757. ------------------------------------------------------------------------
  3758. function luaK:exp2nextreg(fs, e)
  3759. self:dischargevars(fs, e)
  3760. self:freeexp(fs, e)
  3761. self:reserveregs(fs, 1)
  3762. self:exp2reg(fs, e, fs.freereg - 1)
  3763. end
  3764.  
  3765. ------------------------------------------------------------------------
  3766. --
  3767. -- * used in multiple locations
  3768. ------------------------------------------------------------------------
  3769. function luaK:exp2anyreg(fs, e)
  3770. self:dischargevars(fs, e)
  3771. if e.k == "VNONRELOC" then
  3772. if not self:hasjumps(e) then -- exp is already in a register
  3773. return e.info
  3774. end
  3775. if e.info >= fs.nactvar then -- reg. is not a local?
  3776. self:exp2reg(fs, e, e.info) -- put value on it
  3777. return e.info
  3778. end
  3779. end
  3780. self:exp2nextreg(fs, e) -- default
  3781. return e.info
  3782. end
  3783.  
  3784. ------------------------------------------------------------------------
  3785. --
  3786. -- * used in luaK:exp2RK(), luaK:prefix(), luaK:posfix()
  3787. -- * used in (lparser) luaY:yindex()
  3788. ------------------------------------------------------------------------
  3789. function luaK:exp2val(fs, e)
  3790. if self:hasjumps(e) then
  3791. self:exp2anyreg(fs, e)
  3792. else
  3793. self:dischargevars(fs, e)
  3794. end
  3795. end
  3796.  
  3797. ------------------------------------------------------------------------
  3798. --
  3799. -- * used in multiple locations
  3800. ------------------------------------------------------------------------
  3801. function luaK:exp2RK(fs, e)
  3802. self:exp2val(fs, e)
  3803. local k = e.k
  3804. if k == "VKNUM" or k == "VTRUE" or k == "VFALSE" or k == "VNIL" then
  3805. if fs.nk <= luaP.MAXINDEXRK then -- constant fit in RK operand?
  3806. -- converted from a 2-deep ternary operator expression
  3807. if e.k == "VNIL" then
  3808. e.info = self:nilK(fs)
  3809. else
  3810. e.info = (e.k == "VKNUM") and self:numberK(fs, e.nval)
  3811. or self:boolK(fs, e.k == "VTRUE")
  3812. end
  3813. e.k = "VK"
  3814. return luaP:RKASK(e.info)
  3815. end
  3816. elseif k == "VK" then
  3817. if e.info <= luaP.MAXINDEXRK then -- constant fit in argC?
  3818. return luaP:RKASK(e.info)
  3819. end
  3820. else
  3821. -- default
  3822. end
  3823. -- not a constant in the right range: put it in a register
  3824. return self:exp2anyreg(fs, e)
  3825. end
  3826.  
  3827. ------------------------------------------------------------------------
  3828. --
  3829. -- * used in (lparser) luaY:assignment(), luaY:localfunc(), luaY:funcstat()
  3830. ------------------------------------------------------------------------
  3831. function luaK:storevar(fs, var, ex)
  3832. local k = var.k
  3833. if k == "VLOCAL" then
  3834. self:freeexp(fs, ex)
  3835. self:exp2reg(fs, ex, var.info)
  3836. return
  3837. elseif k == "VUPVAL" then
  3838. local e = self:exp2anyreg(fs, ex)
  3839. self:codeABC(fs, "OP_SETUPVAL", e, var.info, 0)
  3840. elseif k == "VGLOBAL" then
  3841. local e = self:exp2anyreg(fs, ex)
  3842. self:codeABx(fs, "OP_SETGLOBAL", e, var.info)
  3843. elseif k == "VINDEXED" then
  3844. local e = self:exp2RK(fs, ex)
  3845. self:codeABC(fs, "OP_SETTABLE", var.info, var.aux, e)
  3846. else
  3847. assert(0) -- invalid var kind to store
  3848. end
  3849. self:freeexp(fs, ex)
  3850. end
  3851.  
  3852. ------------------------------------------------------------------------
  3853. --
  3854. -- * used only in (lparser) luaY:primaryexp()
  3855. ------------------------------------------------------------------------
  3856. function luaK:_self(fs, e, key)
  3857. self:exp2anyreg(fs, e)
  3858. self:freeexp(fs, e)
  3859. local func = fs.freereg
  3860. self:reserveregs(fs, 2)
  3861. self:codeABC(fs, "OP_SELF", func, e.info, self:exp2RK(fs, key))
  3862. self:freeexp(fs, key)
  3863. e.info = func
  3864. e.k = "VNONRELOC"
  3865. end
  3866.  
  3867. ------------------------------------------------------------------------
  3868. --
  3869. -- * used in luaK:goiftrue(), luaK:codenot()
  3870. ------------------------------------------------------------------------
  3871. function luaK:invertjump(fs, e)
  3872. local pc = self:getjumpcontrol(fs, e.info)
  3873. assert(luaP:testTMode(luaP:GET_OPCODE(pc)) ~= 0 and
  3874. luaP:GET_OPCODE(pc) ~= "OP_TESTSET" and
  3875. luaP:GET_OPCODE(pc) ~= "OP_TEST")
  3876. luaP:SETARG_A(pc, (luaP:GETARG_A(pc) == 0) and 1 or 0)
  3877. end
  3878.  
  3879. ------------------------------------------------------------------------
  3880. --
  3881. -- * used in luaK:goiftrue(), luaK:goiffalse()
  3882. ------------------------------------------------------------------------
  3883. function luaK:jumponcond(fs, e, cond)
  3884. if e.k == "VRELOCABLE" then
  3885. local ie = self:getcode(fs, e)
  3886. if luaP:GET_OPCODE(ie) == "OP_NOT" then
  3887. fs.pc = fs.pc - 1 -- remove previous OP_NOT
  3888. return self:condjump(fs, "OP_TEST", luaP:GETARG_B(ie), 0, cond and 0 or 1)
  3889. end
  3890. -- else go through
  3891. end
  3892. self:discharge2anyreg(fs, e)
  3893. self:freeexp(fs, e)
  3894. return self:condjump(fs, "OP_TESTSET", luaP.NO_REG, e.info, cond and 1 or 0)
  3895. end
  3896.  
  3897. ------------------------------------------------------------------------
  3898. --
  3899. -- * used in luaK:infix(), (lparser) luaY:cond()
  3900. ------------------------------------------------------------------------
  3901. function luaK:goiftrue(fs, e)
  3902. local pc -- pc of last jump
  3903. self:dischargevars(fs, e)
  3904. local k = e.k
  3905. if k == "VK" or k == "VKNUM" or k == "VTRUE" then
  3906. pc = self.NO_JUMP -- always true; do nothing
  3907. elseif k == "VFALSE" then
  3908. pc = self:jump(fs) -- always jump
  3909. elseif k == "VJMP" then
  3910. self:invertjump(fs, e)
  3911. pc = e.info
  3912. else
  3913. pc = self:jumponcond(fs, e, false)
  3914. end
  3915. e.f = self:concat(fs, e.f, pc) -- insert last jump in `f' list
  3916. self:patchtohere(fs, e.t)
  3917. e.t = self.NO_JUMP
  3918. end
  3919.  
  3920. ------------------------------------------------------------------------
  3921. --
  3922. -- * used in luaK:infix()
  3923. ------------------------------------------------------------------------
  3924. function luaK:goiffalse(fs, e)
  3925. local pc -- pc of last jump
  3926. self:dischargevars(fs, e)
  3927. local k = e.k
  3928. if k == "VNIL" or k == "VFALSE"then
  3929. pc = self.NO_JUMP -- always false; do nothing
  3930. elseif k == "VTRUE" then
  3931. pc = self:jump(fs) -- always jump
  3932. elseif k == "VJMP" then
  3933. pc = e.info
  3934. else
  3935. pc = self:jumponcond(fs, e, true)
  3936. end
  3937. e.t = self:concat(fs, e.t, pc) -- insert last jump in `t' list
  3938. self:patchtohere(fs, e.f)
  3939. e.f = self.NO_JUMP
  3940. end
  3941.  
  3942. ------------------------------------------------------------------------
  3943. --
  3944. -- * used only in luaK:prefix()
  3945. ------------------------------------------------------------------------
  3946. function luaK:codenot(fs, e)
  3947. self:dischargevars(fs, e)
  3948. local k = e.k
  3949. if k == "VNIL" or k == "VFALSE" then
  3950. e.k = "VTRUE"
  3951. elseif k == "VK" or k == "VKNUM" or k == "VTRUE" then
  3952. e.k = "VFALSE"
  3953. elseif k == "VJMP" then
  3954. self:invertjump(fs, e)
  3955. elseif k == "VRELOCABLE" or k == "VNONRELOC" then
  3956. self:discharge2anyreg(fs, e)
  3957. self:freeexp(fs, e)
  3958. e.info = self:codeABC(fs, "OP_NOT", 0, e.info, 0)
  3959. e.k = "VRELOCABLE"
  3960. else
  3961. assert(0) -- cannot happen
  3962. end
  3963. -- interchange true and false lists
  3964. e.f, e.t = e.t, e.f
  3965. self:removevalues(fs, e.f)
  3966. self:removevalues(fs, e.t)
  3967. end
  3968.  
  3969. ------------------------------------------------------------------------
  3970. --
  3971. -- * used in (lparser) luaY:field(), luaY:primaryexp()
  3972. ------------------------------------------------------------------------
  3973. function luaK:indexed(fs, t, k)
  3974. t.aux = self:exp2RK(fs, k)
  3975. t.k = "VINDEXED"
  3976. end
  3977.  
  3978. ------------------------------------------------------------------------
  3979. --
  3980. -- * used only in luaK:codearith()
  3981. ------------------------------------------------------------------------
  3982. function luaK:constfolding(op, e1, e2)
  3983. local r
  3984. if not self:isnumeral(e1) or not self:isnumeral(e2) then return false end
  3985. local v1 = e1.nval
  3986. local v2 = e2.nval
  3987. if op == "OP_ADD" then
  3988. r = self:numadd(v1, v2)
  3989. elseif op == "OP_SUB" then
  3990. r = self:numsub(v1, v2)
  3991. elseif op == "OP_MUL" then
  3992. r = self:nummul(v1, v2)
  3993. elseif op == "OP_DIV" then
  3994. if v2 == 0 then return false end -- do not attempt to divide by 0
  3995. r = self:numdiv(v1, v2)
  3996. elseif op == "OP_MOD" then
  3997. if v2 == 0 then return false end -- do not attempt to divide by 0
  3998. r = self:nummod(v1, v2)
  3999. elseif op == "OP_POW" then
  4000. r = self:numpow(v1, v2)
  4001. elseif op == "OP_UNM" then
  4002. r = self:numunm(v1)
  4003. elseif op == "OP_LEN" then
  4004. return false -- no constant folding for 'len'
  4005. else
  4006. assert(0)
  4007. r = 0
  4008. end
  4009. if self:numisnan(r) then return false end -- do not attempt to produce NaN
  4010. e1.nval = r
  4011. return true
  4012. end
  4013.  
  4014. ------------------------------------------------------------------------
  4015. --
  4016. -- * used in luaK:prefix(), luaK:posfix()
  4017. ------------------------------------------------------------------------
  4018. function luaK:codearith(fs, op, e1, e2)
  4019. if self:constfolding(op, e1, e2) then
  4020. return
  4021. else
  4022. local o2 = (op ~= "OP_UNM" and op ~= "OP_LEN") and self:exp2RK(fs, e2) or 0
  4023. local o1 = self:exp2RK(fs, e1)
  4024. if o1 > o2 then
  4025. self:freeexp(fs, e1)
  4026. self:freeexp(fs, e2)
  4027. else
  4028. self:freeexp(fs, e2)
  4029. self:freeexp(fs, e1)
  4030. end
  4031. e1.info = self:codeABC(fs, op, 0, o1, o2)
  4032. e1.k = "VRELOCABLE"
  4033. end
  4034. end
  4035.  
  4036. ------------------------------------------------------------------------
  4037. --
  4038. -- * used only in luaK:posfix()
  4039. ------------------------------------------------------------------------
  4040. function luaK:codecomp(fs, op, cond, e1, e2)
  4041. local o1 = self:exp2RK(fs, e1)
  4042. local o2 = self:exp2RK(fs, e2)
  4043. self:freeexp(fs, e2)
  4044. self:freeexp(fs, e1)
  4045. if cond == 0 and op ~= "OP_EQ" then
  4046. -- exchange args to replace by `<' or `<='
  4047. o1, o2 = o2, o1 -- o1 <==> o2
  4048. cond = 1
  4049. end
  4050. e1.info = self:condjump(fs, op, cond, o1, o2)
  4051. e1.k = "VJMP"
  4052. end
  4053.  
  4054. ------------------------------------------------------------------------
  4055. --
  4056. -- * used only in (lparser) luaY:subexpr()
  4057. ------------------------------------------------------------------------
  4058. function luaK:prefix(fs, op, e)
  4059. local e2 = {} -- expdesc
  4060. e2.t, e2.f = self.NO_JUMP, self.NO_JUMP
  4061. e2.k = "VKNUM"
  4062. e2.nval = 0
  4063. if op == "OPR_MINUS" then
  4064. if not self:isnumeral(e) then
  4065. self:exp2anyreg(fs, e) -- cannot operate on non-numeric constants
  4066. end
  4067. self:codearith(fs, "OP_UNM", e, e2)
  4068. elseif op == "OPR_NOT" then
  4069. self:codenot(fs, e)
  4070. elseif op == "OPR_LEN" then
  4071. self:exp2anyreg(fs, e) -- cannot operate on constants
  4072. self:codearith(fs, "OP_LEN", e, e2)
  4073. else
  4074. assert(0)
  4075. end
  4076. end
  4077.  
  4078. ------------------------------------------------------------------------
  4079. --
  4080. -- * used only in (lparser) luaY:subexpr()
  4081. ------------------------------------------------------------------------
  4082. function luaK:infix(fs, op, v)
  4083. if op == "OPR_AND" then
  4084. self:goiftrue(fs, v)
  4085. elseif op == "OPR_OR" then
  4086. self:goiffalse(fs, v)
  4087. elseif op == "OPR_CONCAT" then
  4088. self:exp2nextreg(fs, v) -- operand must be on the 'stack'
  4089. elseif op == "OPR_ADD" or op == "OPR_SUB" or
  4090. op == "OPR_MUL" or op == "OPR_DIV" or
  4091. op == "OPR_MOD" or op == "OPR_POW" then
  4092. if not self:isnumeral(v) then self:exp2RK(fs, v) end
  4093. else
  4094. self:exp2RK(fs, v)
  4095. end
  4096. end
  4097.  
  4098. ------------------------------------------------------------------------
  4099. --
  4100. -- * used only in (lparser) luaY:subexpr()
  4101. ------------------------------------------------------------------------
  4102. -- table lookups to simplify testing
  4103. luaK.arith_op = {
  4104. OPR_ADD = "OP_ADD", OPR_SUB = "OP_SUB", OPR_MUL = "OP_MUL",
  4105. OPR_DIV = "OP_DIV", OPR_MOD = "OP_MOD", OPR_POW = "OP_POW",
  4106. }
  4107. luaK.comp_op = {
  4108. OPR_EQ = "OP_EQ", OPR_NE = "OP_EQ", OPR_LT = "OP_LT",
  4109. OPR_LE = "OP_LE", OPR_GT = "OP_LT", OPR_GE = "OP_LE",
  4110. }
  4111. luaK.comp_cond = {
  4112. OPR_EQ = 1, OPR_NE = 0, OPR_LT = 1,
  4113. OPR_LE = 1, OPR_GT = 0, OPR_GE = 0,
  4114. }
  4115. function luaK:posfix(fs, op, e1, e2)
  4116. -- needed because e1 = e2 doesn't copy values...
  4117. -- * in 5.0.x, only k/info/aux/t/f copied, t for AND, f for OR
  4118. -- but here, all elements are copied for completeness' sake
  4119. local function copyexp(e1, e2)
  4120. e1.k = e2.k
  4121. e1.info = e2.info; e1.aux = e2.aux
  4122. e1.nval = e2.nval
  4123. e1.t = e2.t; e1.f = e2.f
  4124. end
  4125. if op == "OPR_AND" then
  4126. assert(e1.t == self.NO_JUMP) -- list must be closed
  4127. self:dischargevars(fs, e2)
  4128. e2.f = self:concat(fs, e2.f, e1.f)
  4129. copyexp(e1, e2)
  4130. elseif op == "OPR_OR" then
  4131. assert(e1.f == self.NO_JUMP) -- list must be closed
  4132. self:dischargevars(fs, e2)
  4133. e2.t = self:concat(fs, e2.t, e1.t)
  4134. copyexp(e1, e2)
  4135. elseif op == "OPR_CONCAT" then
  4136. self:exp2val(fs, e2)
  4137. if e2.k == "VRELOCABLE" and luaP:GET_OPCODE(self:getcode(fs, e2)) == "OP_CONCAT" then
  4138. assert(e1.info == luaP:GETARG_B(self:getcode(fs, e2)) - 1)
  4139. self:freeexp(fs, e1)
  4140. luaP:SETARG_B(self:getcode(fs, e2), e1.info)
  4141. e1.k = "VRELOCABLE"
  4142. e1.info = e2.info
  4143. else
  4144. self:exp2nextreg(fs, e2) -- operand must be on the 'stack'
  4145. self:codearith(fs, "OP_CONCAT", e1, e2)
  4146. end
  4147. else
  4148. -- the following uses a table lookup in place of conditionals
  4149. local arith = self.arith_op[op]
  4150. if arith then
  4151. self:codearith(fs, arith, e1, e2)
  4152. else
  4153. local comp = self.comp_op[op]
  4154. if comp then
  4155. self:codecomp(fs, comp, self.comp_cond[op], e1, e2)
  4156. else
  4157. assert(0)
  4158. end
  4159. end--if arith
  4160. end--if op
  4161. end
  4162.  
  4163. ------------------------------------------------------------------------
  4164. -- adjusts debug information for last instruction written, in order to
  4165. -- change the line where item comes into existence
  4166. -- * used in (lparser) luaY:funcargs(), luaY:forbody(), luaY:funcstat()
  4167. ------------------------------------------------------------------------
  4168. function luaK:fixline(fs, line)
  4169. fs.f.lineinfo[fs.pc - 1] = line
  4170. end
  4171.  
  4172. ------------------------------------------------------------------------
  4173. -- general function to write an instruction into the instruction buffer,
  4174. -- sets debug information too
  4175. -- * used in luaK:codeABC(), luaK:codeABx()
  4176. -- * called directly by (lparser) luaY:whilestat()
  4177. ------------------------------------------------------------------------
  4178. function luaK:code(fs, i, line)
  4179. local f = fs.f
  4180. self:dischargejpc(fs) -- 'pc' will change
  4181. -- put new instruction in code array
  4182. luaY:growvector(fs.L, f.code, fs.pc, f.sizecode, nil,
  4183. luaY.MAX_INT, "code size overflow")
  4184. f.code[fs.pc] = i
  4185. -- save corresponding line information
  4186. luaY:growvector(fs.L, f.lineinfo, fs.pc, f.sizelineinfo, nil,
  4187. luaY.MAX_INT, "code size overflow")
  4188. f.lineinfo[fs.pc] = line
  4189. local pc = fs.pc
  4190. fs.pc = fs.pc + 1
  4191. return pc
  4192. end
  4193.  
  4194. ------------------------------------------------------------------------
  4195. -- writes an instruction of type ABC
  4196. -- * calls luaK:code()
  4197. ------------------------------------------------------------------------
  4198. function luaK:codeABC(fs, o, a, b, c)
  4199. assert(luaP:getOpMode(o) == luaP.OpMode.iABC)
  4200. assert(luaP:getBMode(o) ~= luaP.OpArgMask.OpArgN or b == 0)
  4201. assert(luaP:getCMode(o) ~= luaP.OpArgMask.OpArgN or c == 0)
  4202. return self:code(fs, luaP:CREATE_ABC(o, a, b, c), fs.ls.lastline)
  4203. end
  4204.  
  4205. ------------------------------------------------------------------------
  4206. -- writes an instruction of type ABx
  4207. -- * calls luaK:code(), called by luaK:codeAsBx()
  4208. ------------------------------------------------------------------------
  4209. function luaK:codeABx(fs, o, a, bc)
  4210. assert(luaP:getOpMode(o) == luaP.OpMode.iABx or
  4211. luaP:getOpMode(o) == luaP.OpMode.iAsBx)
  4212. assert(luaP:getCMode(o) == luaP.OpArgMask.OpArgN)
  4213. return self:code(fs, luaP:CREATE_ABx(o, a, bc), fs.ls.lastline)
  4214. end
  4215.  
  4216. ------------------------------------------------------------------------
  4217. --
  4218. -- * used in (lparser) luaY:closelistfield(), luaY:lastlistfield()
  4219. ------------------------------------------------------------------------
  4220. function luaK:setlist(fs, base, nelems, tostore)
  4221. local c = math.floor((nelems - 1)/luaP.LFIELDS_PER_FLUSH) + 1
  4222. local b = (tostore == luaY.LUA_MULTRET) and 0 or tostore
  4223. assert(tostore ~= 0)
  4224. if c <= luaP.MAXARG_C then
  4225. self:codeABC(fs, "OP_SETLIST", base, b, c)
  4226. else
  4227. self:codeABC(fs, "OP_SETLIST", base, b, 0)
  4228. self:code(fs, luaP:CREATE_Inst(c), fs.ls.lastline)
  4229. end
  4230. fs.freereg = base + 1 -- free registers with list values
  4231. end
  4232.  
  4233. return function(a) luaY = a return luaK end
  4234. end))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement