-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathserde.t
128 lines (119 loc) · 3.35 KB
/
serde.t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
-- SPDX-FileCopyrightText: 2024 René Hiemstra <[email protected]>
-- SPDX-FileCopyrightText: 2024 Torsten Keßler <[email protected]>
--
-- SPDX-License-Identifier: MIT
local tuple = require("tuple")
local function get_local_vars()
--[=[
Return a key-value list of all lua variables available in the current scope.
--]=]
local upvalues = {}
local thread = 0 -- Index of scope
local failure = 0 -- It might fail on the inner scope, so break if this larger than 1.
while true do
thread = thread + 1
local index = 0 -- Index of local variables in scope
while true do
index = index + 1
-- The number of scopes is not known before, so we have to iterate
-- until debug.getlocal throws an error
local ok, name, value = pcall(debug.getlocal, thread, index)
if ok and name ~= nil then
upvalues[name] = value
else
if index == 1 then -- no variables in scope
failure = failure + 1
end
break
end
end
if failure > 1 then
break
end
end
return upvalues
end
local function get_terra_types()
--[=[
Return key-value list of a terra types available in the current scope.
--]=]
local types = {}
-- First iterate over globally defined types. This includes primitive types
for k, v in pairs(_G) do
if terralib.types.istype(v) then
types[k] = v
types[tostring(v)] = v
end
end
-- Terra structs or type aliases can be defined with the local keyword,
-- so we have to iterate over the local lua variables too.
local upvalues = get_local_vars()
for k, v in pairs(upvalues) do
if terralib.types.istype(v) then
types[k] = v
types[tostring(v)] = v
end
end
return types
end
local function striplist(a)
--[=[
Convert a terra list into a lua table.
--]=]
local b = {}
for k, v in pairs(a) do
b[k] = v
end
return b
end
local serpent = require("serpent")
local function serialize_table(tab)
return serpent.dump(tab, {sortkeys = true})
end
local function deserialize_table(str)
return serpent.load(str)
end
local function serialize_pointertofunction(func)
assert(terralib.types.istype(func) and func:ispointertofunction())
func = func.type
local param = striplist(func.parameters)
local ret
if tuple.istuple(func.returntype) then
ret = tuple.unpacktuple(func.returntype)
ret = striplist(ret)
else
ret = {func.returntype}
end
local func_array = {["param"] = param, ["ret"] = ret}
return serialize_table(func_array)
end
local function deserialize_types(context, a)
local gettype = function(str)
local T
if str:match("&") then
local Tp = context[str:sub(2,-1)]
T = terralib.types.pointer(Tp)
else
T = context[str]
end
return T
end
local b = terralib.newlist(a)
return b:map(function(t) return gettype(t) end)
end
local function deserialize_pointertofunction(str)
local ok, obj = deserialize_table(str)
assert(ok)
local type_list = get_terra_types()
local param = deserialize_types(type_list, obj.param)
local ret = deserialize_types(type_list, obj.ret)
return param -> ret
end
return {
get_local_vars = get_local_vars,
get_terra_types = get_terra_types,
serialize_table = serialize_table,
deserialize_table = deserialize_table,
serialize_pointertofunction = serialize_pointertofunction,
deserialize_pointertofunction = deserialize_pointertofunction,
}