-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathvar.lua
More file actions
120 lines (113 loc) · 3.33 KB
/
var.lua
File metadata and controls
120 lines (113 loc) · 3.33 KB
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
local var = {}
require 'stringx'
require 'tablex'
function var.getvar(n, tblctx)
tblctx = tblctx or _G
local ns = string.split(n, '.', true)
if #ns > 1 then return var.getvar(table.join(table.slice(ns, 2), '.'), tblctx[ns[1]]) end
local is = string.split(n, '[', true)
if #is == 1 then return tblctx[n] end
assert(#is == 2, 'unsupported syntax')
local it = string.split(is[2], ']', true)
assert(#it == 2, 'unsupported syntax')
assert(it[2] == '', 'unsupported syntax')
local i = it[1]
i = tonumber(i)
return tblctx[is[1]][i]
end
function var.setvar(n, v, tblctx)
tblctx = tblctx or _G
local ns = string.split(n, '.', true)
if #ns > 1 then
if tblctx[ns[1]] == nil then tblctx[ns[1]] = {} end
var.setvar(table.join(table.slice(ns, 2), '.'), v, tblctx[ns[1]])
return
end
local is = string.split(n, '[', true)
if #is == 1 then
tblctx[n] = v
return
end
assert(#is == 2, 'unsupported syntax')
local it = string.split(is[2], ']', true)
assert(#it == 2, 'unsupported syntax')
assert(it[2] == '', 'unsupported syntax')
local i = it[1]
i = tonumber(i)
tblctx[is[1]][i] = v
end
function var.getlocals(level)
local ret = {}
local i = 0
while true do
i = i + 1
if level then
local name, value = debug.getlocal(level + 1, i)
if not name then return ret end
ret[name] = value
else
if not pcall(
function()
ret[i] = var.getlocals(i)
end
) then break end
if not next(ret[i]) then break end
end
end
return ret
end
function var.f(str)
str = str:gsub(
'{(.-)}',
function(name0)
local value, opts, name = nil, {pctopt = 's'}, name0
if name:sub(-1, -1) == '=' then
opts.equal = true
name = name:sub(1, -2)
end
if name:find(':') then
local p = string.split(name, ':')
assert(#p == 2, 'incorrect syntax')
name = p[1]
opts.pctopt = p[2]
end
for i = 1, 1e100 do
local n, v = debug.getlocal(4, i)
if not n then break end
if name == n then
value = v;
break
end
end
if value == nil and _G[name] then value = _G[name] end
if value ~= nil then
value = string.format('%' .. opts.pctopt, value)
if opts.equal then value = name .. '=' .. value end
return value
else
return string.format('{%s}', name0)
end
end
)
return str
end
function var.unittest()
a = 'x1'
assert(var.getvar 'a' == 'x1')
b = {c = 'x2'}
assert(var.getvar 'b.c' == 'x2')
d = {'x3', 'y3', 'z3'}
assert(var.getvar 'd[3]' == 'z3')
e = {f = {'a', 'b'}}
assert(var.getvar 'e.f[1]' == 'a')
var.setvar('e.f[1]', 'A')
assert(var.getvar 'e.f[1]' == 'A')
var.setvar('g.h', 'x')
assert(g.h == 'x')
local l1 = 'a'
local l2 = 'b'
local L = var.getlocals(1)
assert(L.l1 == 'a' and L.l2 == 'b')
print(debug.getinfo(1, 'S').source, 'tests passed')
end
return var