Skip to content

Commit 3104086

Browse files
committed
use getVariable
1 parent a50369c commit 3104086

File tree

1 file changed

+74
-58
lines changed

1 file changed

+74
-58
lines changed

script/parser/compile.lua

Lines changed: 74 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,20 @@ local function getVariable(name, pos)
21852185
end
21862186
end
21872187

2188+
-- If not found, look for global *
2189+
for i = #Chunk, 1, -1 do
2190+
local chunk = Chunk[i]
2191+
local globals = chunk.globals
2192+
if globals then
2193+
for n = #globals, 1, -1 do
2194+
local glob = globals[n]
2195+
if glob[1] == '*' then
2196+
return glob
2197+
end
2198+
end
2199+
end
2200+
end
2201+
21882202
return nil
21892203
end
21902204

@@ -2206,13 +2220,58 @@ local function resolveName(node)
22062220
else
22072221
node.type = 'getglobal'
22082222
node.var = var
2209-
local env = getLocal(State.ENVMode, node.start)
2210-
if env then
2211-
node.node = env
2212-
if not env.ref then
2213-
env.ref = {}
2223+
2224+
-- Lua 5.5: Check VARIABLE_NOT_DECLARED
2225+
if State.version == 'Lua 5.5' and not var then
2226+
-- Check if there's any global declaration in scope
2227+
local hasAnyGlobal = false
2228+
for i = #Chunk, 1, -1 do
2229+
local chunk = Chunk[i]
2230+
if chunk.globals and #chunk.globals > 0 then
2231+
hasAnyGlobal = true
2232+
break
2233+
end
2234+
end
2235+
2236+
if hasAnyGlobal then
2237+
pushError {
2238+
type = 'VARIABLE_NOT_DECLARED',
2239+
start = node.start,
2240+
finish = node.finish,
2241+
}
2242+
end
2243+
end
2244+
2245+
-- Lua 5.5: Use getVariable to find _ENV, check if it's global
2246+
local env
2247+
if State.version == 'Lua 5.5' then
2248+
env = getVariable(State.ENVMode, node.start)
2249+
if env and env.type == 'global' then
2250+
pushError {
2251+
type = 'RUNTIME_ERROR',
2252+
start = node.start,
2253+
finish = node.finish,
2254+
info = {
2255+
message = '_ENV is global when accessing variable'
2256+
}
2257+
}
2258+
end
2259+
if env and env.type == 'local' then
2260+
node.node = env
2261+
if not env.ref then
2262+
env.ref = {}
2263+
end
2264+
env.ref[#env.ref+1] = node
2265+
end
2266+
else
2267+
env = getLocal(State.ENVMode, node.start)
2268+
if env then
2269+
node.node = env
2270+
if not env.ref then
2271+
env.ref = {}
2272+
end
2273+
env.ref[#env.ref+1] = node
22142274
end
2215-
env.ref[#env.ref+1] = node
22162275
end
22172276
end
22182277
local name = node[1]
@@ -2992,52 +3051,19 @@ local function bindValue(n, v, index, lastValue, isLocal, isSet)
29923051
end
29933052
end
29943053
if n.type == 'setglobal' then
2995-
local nameKey = n[1]
2996-
-- check if in strict global scope (any chunk has globals declared)
2997-
local hasGlobalDecl = false
2998-
local hasGlobalAll = false
2999-
local globalAllConst = false
3000-
local declaredGlobal = nil
3001-
3002-
for i = #Chunk, 1, -1 do
3003-
local chunk = Chunk[i]
3004-
if chunk.globals then
3005-
hasGlobalDecl = true
3006-
for j = 1, #chunk.globals do
3007-
if chunk.globals[j][1] == nameKey then
3008-
declaredGlobal = chunk.globals[j]
3009-
break
3010-
end
3011-
end
3012-
end
3013-
if chunk.hasGlobalAll then
3014-
hasGlobalAll = true
3015-
if chunk.globalAllConst then
3016-
globalAllConst = true
3017-
end
3018-
end
3019-
if declaredGlobal or hasGlobalAll then
3020-
break
3021-
end
3022-
end
3023-
3024-
-- assignment in strict global scope
3025-
if hasGlobalDecl or hasGlobalAll then
3026-
if not hasGlobalAll and not declaredGlobal then
3027-
pushError {
3028-
type = 'UNDEFINED_IN_GLOBAL_SCOPE',
3029-
start = n.start,
3030-
finish = n.finish,
3031-
}
3032-
end
3033-
local isConst = (declaredGlobal and declaredGlobal.attrs and hasAttr(declaredGlobal.attrs, 'const')) or globalAllConst
3034-
if isConst then
3054+
-- n.var is set by resolveName, contains the found global declaration or global *
3055+
if n.var then
3056+
-- Check if it's const
3057+
if n.var.attrs and hasAttr(n.var.attrs, 'const') then
30353058
pushError {
30363059
type = 'ASSIGN_CONST_GLOBAL',
30373060
start = n.start,
30383061
finish = n.finish,
30393062
}
30403063
end
3064+
else
3065+
-- No var means no global declaration found at all (not even global *)
3066+
-- This means we're not in strict global scope, allow free assignment
30413067
end
30423068
end
30433069
end
@@ -3337,19 +3363,8 @@ local function parseGlobal()
33373363
start = globalPos,
33383364
finish = getPosition(Tokens[Index], 'right'),
33393365
attrs = attrs,
3366+
[1] = '*',
33403367
}
3341-
local chunk = Chunk[#Chunk]
3342-
if chunk then
3343-
chunk.hasGlobalAll = true
3344-
if attrs then
3345-
for i = 1, #attrs do
3346-
if attrs[i][1] == 'const' then
3347-
chunk.globalAllConst = true
3348-
break
3349-
end
3350-
end
3351-
end
3352-
end
33533368
if attrs then
33543369
attrs.parent = action
33553370
for i = 1, #attrs do
@@ -3363,6 +3378,7 @@ local function parseGlobal()
33633378
end
33643379
end
33653380
end
3381+
createGlobal(action, attrs)
33663382
Index = Index + 2
33673383
pushActionIntoCurrentChunk(action)
33683384
return action

0 commit comments

Comments
 (0)