FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
lua_enum/enum.lua at main · Peter-Greek/lua_enum · GitHub
Peter-Greek
/
lua_enum
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
0
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
lua_enum
/
enum.lua
Copy path
More file actions
More file actions
Latest commit
History
History
History
142 lines (123 loc) · 3.34 KB
Breadcrumbs
lua_enum
/
enum.lua
Copy path
File metadata and controls
142 lines (123 loc) · 3.34 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
local
ENUM_RUN_TESTS
=
true
local
function
_pair
(
k
,
v
,
is_auto
)
return
{
__enum_key
=
k
,
__enum_val
=
v
,
__enum_auto
=
is_auto
==
true
}
end
local
function
_symbol
(
name
)
return
function
(
v
)
--
if user wrote NAME (x) then v is provided
if
v
~=
nil
then
return
_pair
(
name
,
v
,
false
)
end
--
if user wrote NAME with no parentheses, we need a bare value in the list
--
but Lua cannot place a function call-less identifier into a list without evaluating it
--
so we return an auto marker by making the symbol itself evaluate to this marker:
return
_pair
(
name
,
nil
,
true
)
end
end
local
function
_build
(
list
)
local
enum
=
{}
local
next_auto
=
1
for
i
=
1
,
#
list
do
local
item
=
list
[
i
]
if
type
(
item
)
==
"
table
"
and
item
.
__enum_key
~=
nil
then
local
key
=
item
.
__enum_key
if
item
.
__enum_auto
then
enum
[
key
]
=
next_auto
next_auto
=
next_auto
+
1
else
local
v
=
item
.
__enum_val
enum
[
key
]
=
v
--
C++ style: after explicit value, next implicit continues from v+1
if
type
(
v
)
==
"
number
"
then
next_auto
=
v
+
1
end
end
end
end
return
enum
end
local
function
_stack_contains_func
(
target_func
,
max_depth
)
max_depth
=
max_depth
or
12
for
level
=
2
,
max_depth
do
local
info
=
debug.getinfo
(
level
,
"
f
"
)
if
not
info
then
break
end
if
info
.
func
==
target_func
then
return
true
end
end
return
false
end
ENUM
=
setmetatable
({}, {
__call
=
function
(
_
,
enumName
)
local
prev_mt
=
getmetatable
(
_G
)
local
prev_index
=
prev_mt
and
prev_mt
.
__index
or
nil
--
function that invoked: ENUM "NAME"
local
caller
=
debug.getinfo
(
2
,
"
f
"
).
func
local
caller_co
=
coroutine.running
()
local
sym_cache
=
{}
local
function
guarded_index
(
t
,
k
)
--
preserve any prior __index behavior
if
type
(
prev_index
)
==
"
function
"
then
local
v
=
prev_index
(
t
,
k
)
if
v
~=
nil
then
return
v
end
elseif
type
(
prev_index
)
==
"
table
"
then
local
v
=
prev_index
[
k
]
if
v
~=
nil
then
return
v
end
end
--
real globals
local
v
=
rawget
(
t
,
k
)
if
v
~=
nil
then
return
v
end
--
only during the same call chain + same coroutine
if
coroutine.running
()
~=
caller_co
then
return
nil
end
if
not
_stack_contains_func
(
caller
)
then
return
nil
end
v
=
sym_cache
[
k
]
if
not
v
then
--
IMPORTANT: return a value that can appear in the list without parentheses
--
We make the global lookup itself return the AUTO marker table,
--
but we also want parentheses support. So we return a callable table:
local
auto_marker
=
_pair
(
k
,
nil
,
true
)
v
=
setmetatable
(
auto_marker
, {
__call
=
function
(
_
,
arg
)
return
_pair
(
k
,
arg
,
false
)
end
})
sym_cache
[
k
]
=
v
end
return
v
end
local
tmp_mt
=
{}
if
prev_mt
then
for
k
,
v
in
pairs
(
prev_mt
)
do
tmp_mt
[
k
]
=
v
end
end
tmp_mt
.
__index
=
guarded_index
setmetatable
(
_G
,
tmp_mt
)
return
function
(
list
)
setmetatable
(
_G
,
prev_mt
)
local
enum
=
_build
(
list
)
rawset
(
_G
,
enumName
,
enum
)
return
enum
end
end
})
if
ENUM_RUN_TESTS
then
--
note: use ENUM
local
x
=
ENUM
"
HOUSING_e
"
({
APARTMENT
,
--
1
HOUSE
,
--
2
MANSION
,
--
3
SHOP
(
10
),
--
10
OFFICE
,
--
11
WAREHOUSE
(
20
),
--
20
GARAGE
,
--
21
TRAILER
,
--
22
HIGHENDAPARTMENT
,
--
23
})
print
(
HOUSING_e
.
APARTMENT
,
HOUSING_e
.
HIGHENDAPARTMENT
,
HOUSING_e
.
NONEXISTENT
)
end
return
ENUM
Back
|
FazBrowse Home
|
New Git URL