19 local function generate(name)
20 local fnname, index, child, childfn, childtype
23 local open = name:find("%[")
24 local clos = name:find("%]")
27 index = name:sub(open + 1, clos - 1)
28 child = name:sub(clos + 1)
29 childfn, childtype = generate(child)
30 fnname = (index == "" and "Slice" or "Vec" .. index) .. childfn
32 type = "[" .. index .. "]" .. childtype
34 fnname = camel_case(name)
36 local c = name:sub(1, 1)
37 if c == c:upper() then
42 if not readers[fnname] then
43 local fun = "func Read" .. fnname .. "(l *lua.LState, val lua.LValue, ptr *" .. type .. ") {\n"
46 fun = fun .. "\tif val.Type() != lua.LTTable {\n\t\tpanic(\"invalid value for "
47 .. name .. ": must be a table\")\n\t}\n"
52 tbl := val.(*lua.LTable)
54 *ptr = make(]] .. type .. [[, n)
56 Read]] .. childfn .. [[(l, l.RawGetInt(tbl, i+1), &(*ptr)[i])
60 local n = tonumber(index)
61 for i, v in ipairs({"x", "y", "z"}) do
67 .. "\tRead" .. childfn
68 .. "(l, l.GetField(val, \"" .. v .. "\"), &(*ptr)[" .. (i - 1) .. "])\n"
72 local is_float = type == "float32" or type == "float64"
74 fun = fun .. "\tif val.Type() != lua.LTNumber {\n\t\tpanic(\"invalid value for "
75 .. name .. ": must be a number\")\n\t}\n"
76 .. "\t*ptr = " .. type .. "("
77 .. (is_float and "" or "math.Round(float64(")
78 .. "val.(lua.LNumber)"
79 .. (is_float and "" or "))")
91 for _, use in ipairs(external) do
95 local function signature(name, prefix, type)
96 local camel = camel_case(name)
97 return "func Read" .. camel .. "(l *lua.LState, val lua.LValue, ptr *" .. prefix .. camel .. ") {\n"
100 for name, fields in spairs(parse_spec("server/enum")) do
101 local camel = camel_case(name)
102 local fun = signature(name, "mt.")
105 for _, var in ipairs(fields) do
106 local equals = "*ptr = mt." .. apply_prefix(fields, var) .. "\n"
109 fun = fun .. "\tif val.Type() == lua.LTNil {\n\t\t" .. equals .. "\t\treturn\n\t}\n"
111 impl = impl .. "\tcase \"" .. var .. "\":\n\t\t" .. equals
116 .. "\tif val.Type() != lua.LTString {\n\t\tpanic(\"invalid value for "
117 .. camel .. ": must be a string\")\n\t}\n"
118 .. "\tstr := string(val.(lua.LString))\n"
119 .. "\tswitch str {\n" .. impl
120 .. "\tdefault:\n\t\tpanic(\"invalid value for " .. name .. ": \" + str)\n\t}\n}\n\n"
125 for name, fields in spairs(parse_spec("server/flag")) do
126 local camel = camel_case(name)
127 local fun = signature(name, "mt.")
128 .. "\tif val.Type() != lua.LTTable {\n\t\tpanic(\"invalid value for "
129 .. camel .. ": must be a table\")\n\t}\n"
131 for _, var in ipairs(fields) do
132 fun = fun .. "\tif l.GetField(val, \"" .. var .. "\") == lua.LTrue {\n"
133 .. "\t\t*ptr = *ptr | mt." .. apply_prefix(fields, var) .. "\n\t}\n"
140 local function fields_fromlua(fields, indent)
143 for name, type in spairs(fields) do
144 impl = impl .. indent .. "Read" .. generate(type) .. "(l, l.GetField(val, \"" .. name .. "\"), &ptr."
145 .. camel_case(name) .. ")\n"
151 for name, fields in spairs(parse_spec("server/struct", true)) do
152 local camel = camel_case(name)
153 readers[camel] = signature(name, "mt.")
154 .. "\tif val.Type() != lua.LTTable {\n"
155 .. "\t\tpanic(\"invalid value for " .. camel .. ": must be a table\")\n\t}\n"
156 .. fields_fromlua(fields, "\t")
162 for name, fields in spairs(parse_spec("server/pkt", true)) do
164 .. "\tcase \"" .. name .. "\"" .. "" .. ":\n"
165 .. "\t\tptr := &mt.ToSrv" .. camel_case(name) .. "{}\n"
169 .. "\t\tval := l.CheckTable(3)\n"
170 .. fields_fromlua(fields, "\t\t")
174 .. "\t\treturn ptr\n"
178 for _, fn in spairs(readers) do
179 if type(fn) == "string" then
184 local f = io.open("read_auto.go", "w")
186 // generated by read_mkauto.lua, DO NOT EDIT
190 "github.com/anon55555/mt"
191 "github.com/yuin/gopher-lua"
196 func ReadCmd(l *lua.LState) mt.Cmd {
197 str := l.CheckString(2)
202 panic("invalid packet type: " + str)