#!/usr/bin/env lua require("spec") local funcs = "" for name, fields in spairs(parse_spec("client/enum")) do local camel = camel_case(name) funcs = funcs .. "func Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n" for _, var in ipairs(fields) do funcs = funcs .. "\tcase mt." .. apply_prefix(fields, var) .. ":\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 Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n" for _, var in ipairs(fields) do funcs = funcs .. "\tl.SetField(tbl, \"" .. var .. "\", lua.LBool(val&mt." .. apply_prefix(fields, var) .. " != 0))\n" end funcs = funcs .. "\treturn tbl\n}\n\n" end local tolua = { string = "lua.LString(string(VAL))", boolean = "lua.LBool(VAL)", number = "lua.LNumber(VAL)", vec2 = "PushVec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})", vec3 = "PushVec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})", box1 = "PushBox1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})", box2 = "PushBox2(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 = "PushBox3(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_tolua(fields, indent) local impl = "" for name, type in spairs(fields) do local c = name:sub(1, 1) if c ~= "{" and c ~= "%" then local camel = "val." .. camel_case(name) local idt = indent local condition = fields["{" .. name .. "}"] local typeparam = fields["%" .. name .. "%"] if condition then impl = impl .. indent .. "if " .. condition .. " {\n" idt = idt .. "\t" end impl = impl .. idt .. "l.SetField(tbl, \"" .. name .. "\", " if tolua[type] then impl = impl .. tolua[type]:gsub("VAL", camel) else impl = impl .. "Push" .. camel_case(type) .. (typeparam and "[" .. typeparam .. "]" or "") .. "(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 Push" .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n" .. fields_tolua(fields, "\t") .. "\treturn tbl\n}\n\n" end local pkt_type_impl = "" local pkt_impl = "" for name, fields in spairs(parse_spec("client/pkt", true)) do local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n" pkt_type_impl = pkt_type_impl .. case .. "\t\treturn lua.LString(\"" .. name .. "\")\n" if next(fields) then pkt_impl = pkt_impl .. case .. fields_tolua(fields, "\t\t") end end local f = io.open("push_auto.go", "w") f:write([[ // generated by push_mkauto.lua, DO NOT EDIT package convert import ( "github.com/dragonfireclient/mt" "github.com/yuin/gopher-lua" ) ]] .. funcs .. [[ func PushPktType(pkt *mt.Pkt) lua.LString { switch pkt.Cmd.(type) { ]] .. pkt_type_impl .. [[ } panic("impossible") return "" } func PushPkt(l *lua.LState, pkt *mt.Pkt) lua.LValue { if pkt == nil { return lua.LNil } tbl := l.NewTable() switch val := pkt.Cmd.(type) { ]] .. pkt_impl .. [[ } return tbl } ]]) f:close()