aboutsummaryrefslogtreecommitdiff
path: root/convert/push_mkauto.lua
blob: 3e1f290f6ccffd254b5d21990aa0d3a28988eb72 (plain)
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
#!/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))",
	fixed_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/anon55555/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()