]> git.lizzy.rs Git - hydra-dragonfire.git/blob - tolua/generate.lua
Create README.md
[hydra-dragonfire.git] / tolua / generate.lua
1 #!/usr/bin/env lua
2 dofile("../parse_spec.lua")
3
4 local funcs = ""
5
6 for name, fields in spairs(parse_spec("client/enum")) do
7         local camel = camel_case(name)
8         funcs = funcs .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\tswitch val {\n"
9
10         for _, var in ipairs(fields) do
11                 funcs = funcs .. "\tcase mt." .. apply_prefix(fields, var) .. ":\n\t\t" ..
12                         (var == "no" and "return lua.LNil" or "return lua.LString(\"" .. var .. "\")") .. "\n"
13         end
14
15         funcs = funcs .. "\t}\n\tpanic(\"impossible\")\n\treturn lua.LNil\n}\n\n"
16 end
17
18 for name, fields in spairs(parse_spec("client/flag")) do
19         local camel = camel_case(name)
20         funcs = funcs .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
21
22         for _, var in ipairs(fields) do
23                 funcs = funcs .. "\tif val&mt." .. apply_prefix(fields, var)
24                         .. " != 0 {\n\t\tl.SetField(tbl, \"" .. var  .. "\", lua.LTrue)\n\t}\n"
25         end
26
27         funcs = funcs .. "\treturn tbl\n}\n\n"
28 end
29
30 local tolua = {
31         string = "lua.LString(string(VAL))",
32         fixed_string = "lua.LString(string(VAL[:]))",
33         boolean = "lua.LBool(VAL)",
34         number = "lua.LNumber(VAL)",
35         vec2 = "Vec2(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
36         vec3 = "Vec3(l, [3]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1]), lua.LNumber(VAL[2])})",
37         box1 = "Box1(l, [2]lua.LNumber{lua.LNumber(VAL[0]), lua.LNumber(VAL[1])})",
38         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])}})",
39         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])}})",
40 }
41
42 local function fields_tolua(fields, indent)
43         local impl = ""
44
45         for name, type in spairs(fields) do
46                 if name:sub(1, 1) ~= "{" then
47                         local camel = "val." .. camel_case(name)
48
49                         local idt = indent
50                         local condition = fields["{" .. name .. "}"]
51
52                         if condition then
53                                 impl = impl .. indent .. "if " .. condition .. " {\n"
54                                 idt = idt .. "\t"
55                         end
56
57                         impl = impl .. idt .. "l.SetField(tbl, \"" .. name .. "\", "
58                         if tolua[type] then
59                                 impl = impl .. tolua[type]:gsub("VAL", camel)
60                         else
61                                 impl = impl .. camel_case(type) .. "(l, " .. camel .. ")"
62                         end
63                         impl = impl .. ")\n"
64
65                         if condition then
66                                 impl = impl .. indent .. "}\n"
67                         end
68                 end
69         end
70
71         return impl
72 end
73
74 for name, fields in spairs(parse_spec("client/struct", true)) do
75         local camel = camel_case(name)
76         funcs = funcs
77                 .. "func " .. camel .. "(l *lua.LState, val mt." .. camel .. ") lua.LValue {\n\ttbl := l.NewTable()\n"
78                 .. fields_tolua(fields, "\t")
79                 .. "\treturn tbl\n}\n\n"
80 end
81
82 local pkt_type_impl = ""
83 local pkt_impl = ""
84
85 for name, fields in spairs(parse_spec("client/pkt", true)) do
86         local case = "\tcase *mt.ToClt" .. camel_case(name) .. ":\n"
87
88         pkt_type_impl = pkt_type_impl
89                 .. case .. "\t\treturn lua.LString(\"" .. name .. "\")\n"
90
91         if next(fields) then
92                 pkt_impl = pkt_impl .. case .. fields_tolua(fields, "\t\t")
93         end
94 end
95
96 local f = io.open("generated.go", "w")
97 f:write([[
98 // generated by generate.lua, DO NOT EDIT
99 package tolua
100
101 import (
102         "github.com/anon55555/mt"
103         "github.com/yuin/gopher-lua"
104 )
105
106 ]] .. funcs .. [[
107 func PktType(pkt *mt.Pkt) lua.LString {
108         switch pkt.Cmd.(type) {
109 ]] .. pkt_type_impl .. [[
110         }
111         panic("impossible")
112         return ""
113 }
114
115 func Pkt(l *lua.LState, pkt *mt.Pkt) lua.LValue {
116         if pkt == nil {
117                 return lua.LNil
118         }
119         tbl := l.NewTable()
120         l.SetField(tbl, "_type", PktType(pkt))
121         switch val := pkt.Cmd.(type) {
122 ]] .. pkt_impl .. [[
123         }
124         return tbl
125 }
126 ]])
127 f:close()