Skip to content

Instantly share code, notes, and snippets.

@alanxoc3
Created December 14, 2019 04:15
Show Gist options
  • Save alanxoc3/ad887acf1ecb1a8b89101ca975fab17b to your computer and use it in GitHub Desktop.
Save alanxoc3/ad887acf1ecb1a8b89101ca975fab17b to your computer and use it in GitHub Desktop.
Storing a table inside a string in PICO-8 lua.
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