Created
August 20, 2014 17:59
-
-
Save Python1320/5c38468949e1f3322216 to your computer and use it in GitHub Desktop.
testing luadata prettier printing, although more expensive :(
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
local luadata = {} | |
local encode_table | |
local typex=type | |
function table.isarray(t) | |
local i = 0 | |
for _ in pairs(t) do | |
i = i + 1 | |
if t[i] == nil then return false end | |
end | |
return true | |
end | |
luadata.Types = | |
{ | |
number = function(var) | |
return ("%s"):format(var) | |
end, | |
string = function(var) | |
return ("%q"):format(var) | |
end, | |
boolean = function(var) | |
return var and "true" or "false" | |
end, | |
Vector = function(var) | |
return ("Vector(%s, %s, %s)"):format(var.x, var.y, var.z) | |
end, | |
Angle = function(var) | |
return ("Angle(%s, %s, %s)"):format(var.p, var.y, var.r) | |
end, | |
table = function(tbl, context) | |
local str | |
context.tab = context.tab + 1 | |
if context.tab == 0 then | |
str = {} | |
else | |
str = {"{\n"} | |
end | |
local maxnum = 0 | |
for i = 1, 99999999 do | |
local v = tbl[i] | |
if v==nil then | |
maxnum = i-1 | |
break | |
end | |
str[#str+1] = ("%s%s,\n"):format(("\t"):rep(context.tab), luadata.ToString(tbl[i], context)) | |
if context.yield then | |
coroutine.yield() | |
end | |
end | |
for key, value in pairs(tbl) do | |
local skip = isnumber(key) and key<=maxnum and key>=1 | |
if not skip then | |
value = luadata.ToString(value, context) | |
if value then | |
local k,quoted = luadata.CanBareKeyName(key) | |
print("q",k,quoted) | |
if k then | |
k = key | |
elseif quoted then | |
k = ("[%s]"):format(quoted) | |
else | |
k = luadata.ToString(key, context) | |
if not k then print("UH",k) end | |
k = k and ("[%s]"):format(k) | |
end | |
if k then | |
str[#str+1] = ("%s%s = %s,\n"):format(("\t"):rep(context.tab), k, value) | |
--else -- error? | |
end | |
end | |
if context.yield then | |
coroutine.yield() | |
end | |
end | |
end | |
if context.tab == 0 then | |
str[#str+1] = "\n" | |
else | |
str[#str+1] = ("%s}"):format(("\t"):rep(context.tab)) | |
end | |
context.tab = context.tab - 1 | |
return table.concat(str, "") | |
end, | |
cdata = function(var) | |
return tostring(var) | |
end, | |
} | |
function luadata.SetModifier(type, callback) | |
luadata.Types[type] = callback | |
end | |
function luadata.Type(var) | |
local t = typex(var) | |
if t == "table" then | |
if var.LuaDataType then | |
t = var.LuaDataType | |
end | |
end | |
return t | |
end | |
local CheckCyclic CheckCyclic = | |
function(tbl,tables) | |
for k,v in next,tbl do | |
if istable(k) then | |
if tables[k] then | |
return true | |
end | |
tables[k] = true | |
if CheckCyclic(tbl,tables) then return true end | |
end | |
if istable(v) then | |
if tables[k] then | |
return true | |
end | |
tables[k] = true | |
if CheckCyclic(tbl,tables) then return true end | |
end | |
end | |
end | |
-- todo test | |
function luadata.CheckCyclic(tbl) | |
return CheckCyclic(tbl,{tbl}) | |
end | |
function luadata.CanBareKeyName(key) | |
if not isstring(key) or key:find("%s") or key=="" then | |
return false | |
end | |
local q = ("%q"):format(key) | |
local result = CompileString(("local %s = true"):format(key),"",false) | |
return isfunction(result),q | |
end | |
print(luadata.CheckCyclic{{},[{}]={}}) | |
function luadata.ToString(var, context) | |
context = context or {} | |
context.tab = context.tab or -1 | |
context.out = context.out or {} | |
local func = luadata.Types[luadata.Type(var)] | |
return func and func(var, context) | |
end | |
function luadata.FromString(str) | |
local func = assert(loadstring("return " .. str)) | |
return func() | |
end | |
function luadata.Encode(tbl, callback, speed) | |
if callback then | |
local co = coroutine.create(function() | |
return luadata.ToString(tbl, {yield = true}) | |
end) | |
event.CreateThinker(function() | |
local ok, data = coroutine.resume(co) | |
if ok then | |
if data then | |
xpcall(callback, system.OnError, data) | |
return true | |
end | |
else | |
xpcall(callback, system.OnError, false, data) | |
return true | |
end | |
end, speed) | |
else | |
return luadata.ToString(tbl) | |
end | |
end | |
function luadata.Decode(str) | |
if not str then return {} end | |
local func, err = loadstring("return {\n" .. str .. "\n}") | |
if not func then | |
logn("luadata syntax error:") | |
logn(err) | |
return {} | |
end | |
local ok, err = xpcall(func, system.OnError) | |
if not ok then | |
logn("luadata runtime error:") | |
logn(err) | |
return {} | |
end | |
return err | |
end | |
--print(luadata.Encode(_G.luadata.Decode(luadata.Encode{{a=Vector(1,2,3)},{[""]="eek",a=Vector(1,2,3)},{"a","b","c"}} ))) | |
_G.lau=luadata | |
function bork(key) | |
local t={[key]=true} | |
local s = luadata.Encode(t) | |
local ret,err = _G.luadata.Decode(s) | |
if not ret then error(tostring(err)) end | |
print(s) | |
end | |
--bork"end" | |
print((luadata.Encode{{1,2,3,4,[3]=nil,q=true,["end"]=false}})) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment