2 local function parse_pair(pair, value_first)
3 if pair:sub(1, 1) == "#" then
7 local idx = pair:find(" ")
10 local first, second = pair:sub(1, idx - 1), pair:sub(idx + 1)
12 if value_first and first:sub(1, 1) ~= "[" then
22 local function parse_spec(name, value_first)
23 local f = io.open("spec/" .. name, "r")
28 if l:sub(1, 1) == "\t" then
29 local key, val = parse_pair(l:sub(2), value_first)
34 table.insert(top, key)
37 local key, val = parse_pair(l, value_first)
52 local casemap = parse_spec("casemap")
54 local function camel_case(snake)
55 if casemap[snake] then
62 local idx = snake:find("_") or #snake + 1
65 .. snake:sub(1, 1):upper()
66 .. snake:sub(2, idx - 1)
68 snake = snake:sub(idx + 1)
76 for name, fields in pairs(parse_spec("client/enum")) do
77 local camel = camel_case(name)
78 funcs = funcs .. "func luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tswitch val {\n"
80 for _, var in ipairs(fields) do
81 funcs = funcs .. "\tcase mt."
82 .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
83 .. ":\n\t\t" .. (var == "no" and "l.PushNil()" or "l.PushString(\"" .. var .. "\")") .. "\n"
86 funcs = funcs .. "\t}\n}\n\n"
89 for name, fields in pairs(parse_spec("client/flag")) do
90 local camel = camel_case(name)
91 funcs = funcs .. "func luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tl.NewTable()\n"
93 for _, var in ipairs(fields) do
94 funcs = funcs .. "\tif val&mt."
95 .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "")
96 .. " != 0 {\n\t\tl.PushBoolean(true)\n\t\tl.SetField(-2, \"" .. var .. "\")\n\t}\n"
99 funcs = funcs .. "}\n\n"
103 string = "l.PushString(string(VAL))",
104 fixed_string = "l.PushString(string(VAL[:]))",
105 boolean = "l.PushBoolean(bool(VAL))",
106 integer = "l.PushInteger(int(VAL))",
107 number = "l.PushNumber(float64(VAL))",
108 vec2 = "luaPushVec2(l, [2]float64{float64(VAL[0]), float64(VAL[1])})",
109 vec3 = "luaPushVec3(l, [3]float64{float64(VAL[0]), float64(VAL[1]), float64(VAL[2])})",
110 box1 = "luaPushBox1(l, [2]float64{float64(VAL[0]), float64(VAL[1])})",
111 box2 = "luaPushBox2(l, [2][2]float64{{float64(VAL[0][0]), float64(VAL[0][1])}, {float64(VAL[1][0]), float64(VAL[1][1])}})",
112 box3 = "luaPushBox3(l, [2][3]float64{{float64(VAL[0][0]), float64(VAL[0][1]), float64(VAL[0][2])}, {float64(VAL[1][0]), float64(VAL[1][1]), float64(VAL[1][2])}})",
115 local function push_fields(fields, indent)
118 for name, type in pairs(fields) do
119 if name:sub(1, 1) ~= "[" then
120 local camel = "val." .. camel_case(name)
123 local condition = fields["[" .. name .. "]"]
126 impl = impl .. indent .. "if " .. condition .. " {\n"
130 if push_type[type] then
131 impl = impl .. idt .. push_type[type]:gsub("VAL", camel) .. "\n"
133 impl = impl .. idt .. "luaPush" .. camel_case(type) .. "(l, " .. camel .. ")\n"
136 impl = impl .. idt .. "l.SetField(-2, \"" .. name .. "\")\n"
139 impl = impl .. indent .. "}\n"
147 for name, fields in pairs(parse_spec("client/struct", true)) do
148 local camel = camel_case(name)
150 .. "func luaPush" .. camel .. "(l *lua.State, val mt." .. camel .. ") {\n\tl.NewTable()\n"
151 .. push_fields(fields, "\t")
155 local to_string_impl = ""
156 local to_lua_impl = ""
158 for name, fields in pairs(parse_spec("client/pkt", true)) do
159 local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n"
161 to_string_impl = to_string_impl
162 .. case .. "\t\treturn \"" .. name .. "\"\n"
165 to_lua_impl = to_lua_impl .. case .. push_fields(fields, "\t\t")
169 local f = io.open("convert.go", "w")
171 // generated by mkconvert.lua, DO NOT EDIT
175 "github.com/Shopify/go-lua"
176 "github.com/anon55555/mt"
180 func pktToString(pkt *mt.Pkt) string {
181 switch pkt.Cmd.(type) {
182 ]] .. to_string_impl .. [[
188 func pktToLua(l *lua.State, pkt *mt.Pkt) {
194 l.PushString(pktToString(pkt))
195 l.SetField(-2, "_type")
196 switch val := pkt.Cmd.(type) {
197 ]] .. to_lua_impl .. [[