Last active
May 25, 2025 05:39
-
-
Save magicoal-nerb/b6c8421fd812a22cc6a60127c8c81da7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Average stack based JSON parser i guess | |
local LEX_CLASSIFIER = { | |
8, 8, 8, 8, 8, 8, 8, 8, 8, 40, 40, 40, 40, 40, 8, 8, 8, | |
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 160, 16, 16, 16, | |
16, 16, 16, 16, 16, 16, 16, 16, 16, 66, 16, 16, 4, 4, 4, 4, 4, | |
4, 4, 4, 4, 4, 16, 16, 16, 16, 16, 16, 16, 65, 65, 65, 65, 65, | |
65, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
1, 16, 16, 16, 16, 16, 16, 66, 66, 66, 66, 66, 66, 2, 2, 2, 2, | |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, | |
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 16, 16, 16, 16, | |
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, | |
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, | |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, | |
1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | |
2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2 | |
}; | |
return function(content) | |
local root = { id = 0 }; | |
local node = root; | |
local queue = {}; | |
local length = #content; | |
local read = 1; | |
local id = 0; | |
while(read <= length)do | |
local current = string.byte(content, read); | |
local last = queue[#queue]; | |
local classifier = LEX_CLASSIFIER[current + 1]; | |
if(bit.btest(classifier, 0x20))then | |
-- Whitespace | |
elseif(current == 123 or current == 91)then | |
-- Open paranthesees / square bracket | |
if(not last or last.id ~= id)then | |
table.insert(queue, { | |
index = #node+1; | |
id = id; | |
}) | |
end | |
local newStack = {}; | |
id = id + 1; | |
newStack.id = id; | |
newStack.parent = node; | |
node = newStack; | |
elseif(current == 125 or current == 93)then | |
-- Closing paranthesees | |
local parent = node.parent; | |
if(parent.id == 0)then | |
-- End of file | |
break; | |
end | |
-- Should have been from an assignment. | |
assert(last.id == parent.id, "How?"); | |
table.remove(queue); | |
parent[last.index] = node; | |
id = parent.id; | |
-- Set parent | |
node.parent = nil; | |
node.id = nil; | |
node = parent; | |
elseif(current == 58)then | |
table.insert(queue, { | |
index = table.remove(node); | |
id = id; | |
}); | |
elseif(current == 34)then | |
-- String | |
local start = read + 1; | |
read = start; | |
while(string.byte(content, read) ~= 34)do | |
read = read + 1; | |
end | |
local data = string.sub(content, start, read-1); | |
if(last and last.id == id)then | |
-- Check last index | |
table.remove(queue); | |
node[last.index] = data; | |
else | |
-- Probably a literal | |
table.insert(node, data); | |
end | |
elseif(bit.btest(classifier, 0x7))then | |
-- Usually for booleans and stuff. | |
local start = read; | |
read = start + 1; | |
while(bit.btest(LEX_CLASSIFIER[string.byte(content, read) + 1], 0x07))do | |
read = read + 1; | |
end | |
read = read - 1; | |
local substr = string.sub(content, start, read); | |
if(bit.btest(classifier, 0x4))then | |
-- We had a number here! | |
substr = tonumber(substr); | |
end | |
if(last and last.id == id)then | |
-- Check last index | |
table.remove(queue); | |
node[last.index] = substr; | |
else | |
-- Probably a literal | |
table.insert(node, substr); | |
end | |
elseif(current == 44)then | |
-- ¯\_(ツ)_/¯ | |
else | |
error("invalid character: " .. current .. " ascii: " .. string.char(current)); | |
end | |
read = read + 1; | |
end | |
-- Close | |
assert(node.parent.id == 0, "Not enough closing braces :/"); | |
node.parent = nil; | |
node.id = nil; | |
return node; | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment