Created
December 14, 2019 04:15
-
-
Save alanxoc3/ad887acf1ecb1a8b89101ca975fab17b to your computer and use it in GitHub Desktop.
Storing a table inside a string in PICO-8 lua.
This file contains 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
function nf() end | |
-- Recursively copies table attributes. | |
function tabcpy(src, dest) | |
dest = dest or {} | |
for k,v in pairs(src or {}) do | |
if type(v) == 'table' and not v.is_tabcpy_disabled then | |
dest[k] = tabcpy(v) | |
else | |
dest[k] = v | |
end | |
end | |
return dest | |
end | |
-- Returns the parsed table, the current position, and the parameter locations | |
function gun_vals_helper(val_str,i,new_params) | |
local val_list, val, val_ind, isnum, val_key, str_mode = {}, '', 1, true | |
while i <= #val_str do | |
local x = sub(val_str, i, i) | |
if x == '\"' then str_mode, isnum = not str_mode | |
elseif str_mode then val=val..x | |
elseif x == '}' or x == ',' then | |
if type(val) == 'table' or not isnum then | |
elseif sub(val,1,1) == '@' then | |
local sec = tonum(sub(val,2,#val)) | |
assert(sec != nil) | |
if not new_params[sec] then new_params[sec] = {} end | |
add(new_params[sec], {val_list, val_key or val_ind}) | |
elseif val == 'nf' then val = nf | |
elseif val == 'true' or val == 'false' then val=val=='true' | |
elseif val == 'nil' or val == '' then val=nil | |
elseif isnum then val=tonum(val) | |
end | |
val_list[val_key or val_ind], isnum, val, val_ind, val_key = val, true, '', val_key and val_ind or val_ind+1 | |
if x == '}' then | |
return val_list, i | |
end | |
elseif x == '{' then val, i, isnum = gun_vals_helper(val_str,i+1,new_params) | |
elseif x == '=' then isnum, val_key, val = true, val, '' | |
elseif x != " " and x != '\n' then val=val..x end | |
i += 1 | |
end | |
return val_list, i, new_params | |
end | |
-- Cached for speedy delivery :). | |
g_param_cache = {} | |
function gun_vals(val_str, ...) | |
-- there is global state logic in here. you have been warned. | |
if not g_param_cache[val_str] then | |
g_param_cache[val_str] = { gun_vals_helper(val_str..',',1,{}) } | |
end | |
local params, lookup = {...}, g_param_cache[val_str] | |
for k,v in pairs(lookup[3]) do | |
foreach(lookup[3][k], function(x) | |
x[1][x[2]] = params[k] | |
if type(params[k]) == 'table' then | |
params[k].is_tabcpy_disabled = true | |
end | |
end) | |
end | |
return tabcpy(lookup[1]) | |
end | |
-- DEMO: | |
local complete_table = gun_vals([[func=nf,x="nothing",{"help",0,1,3333,0xffff},{true, false},@1]], {"parameter"}) | |
assert(complete_table[1][1] == "help") | |
assert(complete_table[1][2] == 0) | |
assert(complete_table[1][3] == 1) | |
assert(complete_table[1][4] == 3333) | |
assert(complete_table[1][5] == -1) | |
assert(complete_table[2][1] == true) | |
assert(complete_table[2][2] == false) | |
assert(complete_table[3][1] == "parameter") | |
assert(complete_table.x == "nothing") | |
assert(complete_table.func() == nil) | |
-- Some gotchas: | |
-- nf is an empty function (nothing function). | |
-- Parameters are specified with the @ sign: @1, @2, ..., @15, ... | |
-- Every string passed is cached, so that parsing is only CPU intensive the first time. | |
-- An is_tabcpy_disabled is attached to all table parameters, to prevent recursively copying them. | |
-- Only double quotes are supported for strings inside table. Single quotes are not supported. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment