diff options
Diffstat (limited to 'tolua/generate.lua')
-rwxr-xr-x | tolua/generate.lua | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/tolua/generate.lua b/tolua/generate.lua new file mode 100755 index 0000000..7c2d5a7 --- /dev/null +++ b/tolua/generate.lua @@ -0,0 +1,129 @@ +#!/usr/bin/env lua +dofile("../parse_spec.lua") + +local funcs = "" + +for name, fields in spairs(parse_spec("client/enum")) do + local camel = camel_case(name) + funcs = funcs .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n" + + for _, var in ipairs(fields) do + funcs = funcs .. "\tcase mt." + .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "") + .. ":\n\t\t" .. (var == "no" and "return lua.LNil" or "return lua.LString(\"" .. var .. "\")") .. "\n" + end + + funcs = funcs .. "\t}\n\tpanic(\"impossible\")\n\treturn lua.LNil\n}\n\n" +end + +for name, fields in spairs(parse_spec("client/flag")) do + local camel = camel_case(name) + funcs = funcs .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n" + + for _, var in ipairs(fields) do + funcs = funcs .. "\tif val&mt." + .. (fields.prefix or "") .. camel_case(var) .. (fields.postfix or "") + .. " != 0 {\n\t\tl.SetField(tbl, \"" .. var .. "\", lua.LTrue)\n\t}\n" + end + + funcs = funcs .. "\treturn tbl\n}\n\n" +end + +local to_lua = { + string = "lua.LString(string(VAL))", + fixed_string = "lua.LString(string(VAL[:]))", + boolean = "lua.LBool(VAL)", + number = "lua.LNumber(VAL)", + vec2 = "Vec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})", + vec3 = "Vec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})", + box1 = "Box1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})", + box2 = "Box2(l, [2][2]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1])}})", + box3 = "Box3(l, [2][3]lua.LNumber{{lua.LNumber(VAL[0][0]), lua.LNumber(VAL[0][1]), lua.LNumber(VAL[0][2])}, {lua.LNumber(VAL[1][0]), lua.LNumber(VAL[1][1]), lua.LNumber(VAL[1][2])}})", +} + +local function fields_to_lua(fields, indent) + local impl = "" + + for name, type in spairs(fields) do + if name:sub(1, 1) ~= "[" then + local camel = "val." .. camel_case(name) + + local idt = indent + local condition = fields["[" .. name .. "]"] + + if condition then + impl = impl .. indent .. "if " .. condition .. " {\n" + idt = idt .. "\t" + end + + impl = impl .. idt .. "l.SetField(tbl, \"" .. name .. "\", " + if to_lua[type] then + impl = impl .. to_lua[type]:gsub("VAL", camel) + else + impl = impl .. camel_case(type) .. "(l, " .. camel .. ")" + end + impl = impl .. ")\n" + + if condition then + impl = impl .. indent .. "}\n" + end + end + end + + return impl +end + +for name, fields in spairs(parse_spec("client/struct", true)) do + local camel = camel_case(name) + funcs = funcs + .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n" + .. fields_to_lua(fields, "\t") + .. "\treturn tbl\n}\n\n" +end + +local to_string_impl = "" +local to_lua_impl = "" + +for name, fields in spairs(parse_spec("client/pkt", true)) do + local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n" + + to_string_impl = to_string_impl + .. case .. "\t\treturn lua.LString(\"" .. name .. "\")\n" + + if next(fields) then + to_lua_impl = to_lua_impl .. case .. fields_to_lua(fields, "\t\t") + end +end + +local f = io.open("generated.go", "w") +f:write([[ +// generated by generate.lua, DO NOT EDIT +package tolua + +import ( + "github.com/anon55555/mt" + "github.com/yuin/gopher-lua" +) + +]] .. funcs .. [[ +func PktType(pkt *mt.Pkt) lua.LString { + switch pkt.Cmd.(type) { +]] .. to_string_impl .. [[ + } + panic("impossible") + return "" +} + +func Pkt(l *lua.LState, pkt *mt.Pkt) lua.LValue { + if pkt == nil { + return lua.LNil + } + tbl := l.NewTable() + l.SetField(tbl, "_type", PktType(pkt)) + switch val := pkt.Cmd.(type) { +]] .. to_lua_impl .. [[ + } + return tbl +} +]]) +f:close() |