summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@samsung.com>2020-05-21 17:29:23 +0200
committerDaniel Kolesa <d.kolesa@samsung.com>2020-05-21 17:29:23 +0200
commita7d475be472616f6b5e5d301f4a2646464370e5d (patch)
treecbfede3b4d75fc7d5b112b51ef7cfd6f499d42ab
parentc493e80c216c71373bfa4898841ffaca32dd18a9 (diff)
elua: remove old lua bindings generator
-rw-r--r--src/scripts/elua/apps/empty.txt0
-rw-r--r--src/scripts/elua/apps/lualian.lua65
-rw-r--r--src/scripts/elua/modules/lualian.lua718
3 files changed, 0 insertions, 783 deletions
diff --git a/src/scripts/elua/apps/empty.txt b/src/scripts/elua/apps/empty.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/scripts/elua/apps/empty.txt
diff --git a/src/scripts/elua/apps/lualian.lua b/src/scripts/elua/apps/lualian.lua
deleted file mode 100644
index f0837d7e35..0000000000
--- a/src/scripts/elua/apps/lualian.lua
+++ /dev/null
@@ -1,65 +0,0 @@
1-- Lualian application
2-- for use with Elua
3
4local lualian = require("lualian")
5local getopt = require("getopt")
6
7local gen_file = function(opts, i, fname)
8 local printv = opts["v"] and print or function() end
9 printv("Generating for file: " .. fname)
10 local ofile = opts["o"] and opts["o"][i] or nil
11 local fstream = io.stdout
12 if ofile then
13 printv(" Output file: " .. ofile)
14 fstream = io.open(ofile, "w")
15 if not fstream then
16 error("Cannot open output file: " .. ofile)
17 end
18 else
19 printv(" Output file: printing to stdout...")
20 end
21 lualian.generate(fname, fstream)
22end
23
24getopt.parse {
25 usage = "Usage: %prog [OPTIONS] file1.eo file2.eo ... fileN.eo",
26 args = arg,
27 descs = {
28 { category = "General" },
29
30 { "h", "help", nil, help = "Show this message.", metavar = "CATEGORY",
31 callback = getopt.help_cb(io.stdout)
32 },
33 { "v", "verbose", false, help = "Be verbose." },
34
35 { category = "Generator" },
36
37 { "I", "include", true, help = "Include a directory.", metavar = "DIR",
38 list = {}
39 },
40 { "o", "output", true, help = "Specify output file name(s), by "
41 .. "default goes to stdout.",
42 list = {}
43 }
44 },
45 error_cb = function(parser, msg)
46 io.stderr:write(msg, "\n")
47 getopt.help(parser, io.stderr)
48 end,
49 done_cb = function(parser, opts, args)
50 if not opts["h"] then
51 for i, v in ipairs(opts["I"] or {}) do
52 lualian.include_dir(v)
53 end
54 if os.getenv("EFL_RUN_IN_TREE") then
55 lualian.system_directory_add()
56 end
57 lualian.load_eot_files()
58 for i, fname in ipairs(args) do
59 gen_file(opts, i, fname)
60 end
61 end
62 end
63}
64
65return true
diff --git a/src/scripts/elua/modules/lualian.lua b/src/scripts/elua/modules/lualian.lua
deleted file mode 100644
index e515aaf8bc..0000000000
--- a/src/scripts/elua/modules/lualian.lua
+++ /dev/null
@@ -1,718 +0,0 @@
1-- Elua lualian module
2
3local cutil = require("cutil")
4local util = require("util")
5local log = require("eina.log")
6local eolian = require("eolian")
7
8local M = {}
9
10local dom
11
12local type_type = eolian.type_type
13local class_type = eolian.class_type
14local func_type = eolian.function_type
15local obj_scope = eolian.object_scope
16local param_dir = eolian.parameter_dir
17
18local gen_unit
19local gen_state
20
21local get_state = function()
22 if not gen_state then
23 gen_state = eolian.new()
24 end
25 return assert(gen_state, "could not create eolian state")
26end
27
28cutil.init_module(function()
29 dom = log.Domain("lualian")
30 if not dom:is_valid() then
31 log.err("Could not register log domain: lualian")
32 error("Could not register log domain: lualian")
33 end
34end, function()
35 dom:unregister()
36 dom = nil
37end)
38
39local lua_kw = {
40 ["and"] = true, ["end"] = true, ["in"] = true, ["local"] = true,
41 ["nil"] = true, ["not"] = true, ["or"] = true, ["repeat"] = true,
42 ["then"] = true, ["until"] = true
43}
44
45local kw_t = function(n)
46 if lua_kw[n] then
47 return n .. "_"
48 end
49 return n
50end
51
52local int_builtin = {
53 ["byte" ] = true, ["short"] = true, ["int"] = true, ["long"] = true,
54 ["llong"] = true,
55
56 ["int8" ] = true, ["int16"] = true, ["int32"] = true, ["int64"] = true,
57 ["int128"] = true,
58
59 ["intptr"] = true
60}
61
62local num_others = {
63 ["size" ] = true, ["ssize" ] = true, ["ptrdiff"] = true,
64 ["float"] = true, ["double"] = true
65}
66
67local is_num = function(x)
68 if not x then
69 return false
70 end
71 if num_others [x ] then return true end
72 if int_builtin[x ] then return true end
73 if int_builtin["u" .. x] then return true end
74 return false
75end
76
77local known_out = {
78 ["Evas_Coord"] = function(expr) return ("tonumber(%s)"):format(expr) end,
79 ["bool"] = function(expr) return ("((%s) ~= 0)"):format(expr) end,
80 ["char"] = function(expr) return ("string.char(%s)"):format(expr) end
81}
82
83local known_in = {
84 ["Evas_Coord"] = function(expr) return expr end,
85 ["bool"] = function(expr) return expr end
86}
87
88local known_ptr_out = {
89 ["const char"] = function(expr) return ("ffi.string(%s)"):format(expr) end
90}
91
92local known_ptr_in = {
93 ["const char"] = function(expr) return expr end
94}
95
96local convfuncs = {}
97
98local build_calln = function(tps, expr, isin)
99 return expr
100end
101
102local typeconv = function(tps, expr, isin)
103 if tps:type_get() == type_type.POINTER then
104 local base = tps:base_type_get()
105 local f = (isin and known_ptr_in or known_ptr_out)[base:c_type_get(eolian.c_type_type.DEFAULT)]
106 if f then return f(expr) end
107 return build_calln(tps, expr, isin)
108 end
109
110 local tp = tps:short_name_get()
111
112 if is_num(tp) then
113 return isin and expr or ("tonumber(%s)"):format(expr)
114 end
115
116 local f = (isin and known_in or known_out)[tp]
117 if f then
118 return f(expr)
119 end
120
121 return build_calln(tps, expr, isin)
122end
123
124local Node = util.Object:clone {
125 generate = function(self, s)
126 end,
127
128 gen_children = function(self, s)
129 local len = #self.children
130
131 local evs = self.events
132 local evslen
133 if evs then evslen = #evs end
134 local hasevs = evs and evslen > 0
135
136 local hasprops = false
137 local nprops = 0
138 local props = {}
139
140 for i, v in ipairs(self.children) do
141 v.parent_node = self
142 if v.generate_prop then
143 if v:generate_prop(props) then
144 nprops = nprops + 1
145 end
146 hasprops = true
147 end
148 v:generate(s, (not hasevs) and (not hasprops) and (i == len))
149 end
150
151 if hasevs then
152 s:write(" __events = {\n")
153 for i, v in ipairs(evs) do
154 v.parent_node = self
155 v:generate(s, i == evslen)
156 end
157 s:write(" }", hasprops and "," or "", "\n")
158 end
159
160 if hasprops then
161 if hasevs then
162 s:write("\n")
163 end
164 s:write(" __properties = {\n")
165 local pi = 0
166 for k, v in pairs(props) do
167 pi = pi + 1
168 s:write(" [\"", k, "\"] = { ", table.concat(v, ", "),
169 " }", pi ~= nprops and "," or "", "\n")
170 end
171 s:write(" }\n")
172 end
173 end
174}
175
176local Method = Node:clone {
177 __ctor = function(self, meth)
178 self.method = meth
179 end,
180
181 gen_proto = function(self)
182 if self.cached_proto then return self.cached_proto end
183
184 local meth = self.method
185 local pars = meth:parameters_get()
186 local rett = meth:return_type_get(func_type.METHOD)
187
188 local proto = {
189 name = meth:name_get()
190 }
191 proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void"
192 local args, cargs, vargs = { "self" }, {}, {}
193 proto.args, proto.cargs, proto.vargs = args, cargs, vargs
194 local rets = {}
195 proto.rets = rets
196 local allocs = {}
197 proto.allocs = allocs
198
199 proto.full_name = meth:full_c_name_get(func_type.METHOD)
200
201 local fulln = proto.full_name
202
203 if rett then
204 rets[#rets + 1] = typeconv(rett, "v", false)
205 end
206
207 for v in pars do
208 local dir, tps, nm = v:direction_get(), v:type_get(), kw_t(v:name_get())
209 local tp = tps:c_type_get(eolian.c_type_type.PARAM)
210 if dir == param_dir.OUT or dir == param_dir.INOUT then
211 if dir == param_dir.INOUT then
212 args[#args + 1] = nm
213 end
214 cargs [#cargs + 1] = tp .. " *" .. nm
215 vargs [#vargs + 1] = nm
216 allocs[#allocs + 1] = { tp, nm, (dir == param_dir.INOUT)
217 and typeconv(tps, nm, true) or nil }
218 rets [#rets + 1] = typeconv(tps, nm .. "[0]", false)
219 else
220 args [#args + 1] = nm
221 cargs [#cargs + 1] = tp .. " " .. nm
222 vargs [#vargs + 1] = typeconv(tps, nm, true)
223 end
224 end
225
226 if #cargs == 0 then cargs[1] = "void" end
227
228 self.cached_proto = proto
229
230 return proto
231 end,
232
233 generate = function(self, s, last)
234 local proto = self:gen_proto()
235 s:write(" ", proto.name, proto.suffix or "", " = function(",
236 table.concat(proto.args, ", "), ")\n")
237 s:write( " eo.__do_start(self, __class)\n")
238 for i, v in ipairs(proto.allocs) do
239 s:write(" local ", v[2], " = ffi.new(\"", v[1], "[1]\")\n")
240 end
241 local genv = (proto.ret_type ~= "void")
242 s:write(" ", genv and "local v = " or "", "__lib.",
243 proto.full_name, "(", table.concat(proto.vargs, ", "), ")\n")
244 s:write(" eo.__do_end()\n")
245 if #proto.rets > 0 then
246 s:write(" return ", table.concat(proto.rets, ", "), "\n")
247 end
248 s:write(" end", last and "" or ",", last and "\n" or "\n\n")
249 end,
250
251 gen_ffi = function(self, s)
252 local proto = self:gen_proto()
253 local ret = proto.ret_type
254 if ret:match("[a-zA-Z0-9_]$") then
255 ret = ret .. " "
256 end
257 local cproto = {
258 " ", ret, proto.full_name, "(", table.concat(proto.cargs, ", "),
259 ");\n"
260 }
261 s:write(table.concat(cproto))
262 end
263}
264
265local Property = Method:clone {
266 __ctor = function(self, prop, ftype)
267 self.property = prop
268 self.isget = (ftype == func_type.PROP_GET)
269 self.ftype = ftype
270 end,
271
272 gen_proto = function(self)
273 if self.cached_proto then return self.cached_proto end
274
275 local prop = self.property
276 local keys = prop:property_keys_get(self.ftype):to_array()
277 local vals = prop:property_values_get(self.ftype):to_array()
278 local rett = prop:return_type_get(self.ftype)
279
280 local proto = {
281 name = prop:name_get(),
282 suffix = (self.isget and "_get" or "_set"),
283 nkeys = #keys,
284 nvals = #vals
285 }
286 proto.ret_type = rett and rett:c_type_get(eolian.c_type_type.RETURN) or "void"
287 local args, cargs, vargs = { "self" }, {}, {}
288 proto.args, proto.cargs, proto.vargs = args, cargs, vargs
289 local rets = {}
290 proto.rets = rets
291 local allocs = {}
292 proto.allocs = allocs
293
294 proto.full_name = prop:full_c_name_get(self.ftype)
295
296 local fulln = proto.full_name
297 if #keys > 0 then
298 for i, v in ipairs(keys) do
299 local nm = kw_t(v:name_get())
300 local tps = v:type_get()
301 local tp = tps:c_type_get(eolian.c_type_type.PARAM)
302 args [#args + 1] = nm
303 cargs[#cargs + 1] = tp .. " " .. nm
304 vargs[#vargs + 1] = typeconv(tps, nm, true)
305 end
306 end
307 proto.kprop = #keys > 0
308
309 if #vals > 0 then
310 if self.isget then
311 if #vals == 1 and not rett then
312 local tps = vals[1]:type_get()
313 proto.ret_type = tps:c_type_get(eolian.c_type_type.PARAM)
314 rets[#rets + 1] = typeconv(tps, "v", false)
315 else
316 for i, v in ipairs(vals) do
317 local dir, tps, nm = v:direction_get(), v:type_get(),
318 kw_t(v:name_get())
319 local tp = tps:c_type_get(eolian.c_type_type.PARAM)
320 cargs [#cargs + 1] = tp .. " *" .. nm
321 vargs [#vargs + 1] = nm
322 allocs[#allocs + 1] = { tp, nm }
323 rets [#rets + 1] = typeconv(tps, nm .. "[0]", false)
324 end
325 end
326 else
327 for i, v in ipairs(vals) do
328 local dir, tps, nm = v:direction_get(), v:type_get(),
329 kw_t(v:name_get())
330 local tp = tps:c_type_get(eolian.c_type_type.PARAM)
331 args [#args + 1] = nm
332 cargs[#cargs + 1] = tp .. " " .. nm
333 vargs[#vargs + 1] = typeconv(tps, nm, true)
334 end
335 end
336 end
337
338 if #cargs == 0 then cargs[1] = "void" end
339
340 self.cached_proto = proto
341
342 return proto
343 end,
344
345 generate_prop = function(self, props)
346 local proto = self:gen_proto()
347 local prop = props[proto.name]
348 local hasprop = true
349 if not prop then
350 prop = { 0, 0, 0, 0, "false", "false" }
351 props[proto.name] = prop
352 hasprop = false
353 end
354 if self.isget then
355 prop[1] = proto.nkeys
356 prop[3] = math.max(proto.nvals, 1)
357 prop[5] = "true"
358 else
359 prop[2] = proto.nkeys
360 prop[4] = math.max(proto.nvals, 1)
361 prop[6] = "true"
362 end
363 return not hasprop
364 end
365}
366
367local Event = Node:clone {
368 __ctor = function(self, ename, etype, ecname)
369 self.ename = ename
370 self.etype = etype
371 self.ecname = ecname
372 end,
373
374 generate = function(self, s, last)
375 s:write(" [\"", self.ename, "\"] = __lib.",
376 "_" .. self.ecname, last and "\n" or ",\n")
377 end,
378
379 gen_ffi = function(self, s)
380 s:write(" extern const Eo_Event_Description ",
381 "_" .. self.ecname, ";\n")
382 end
383}
384
385local gen_ns = function(klass, s)
386 local nspaces = klass:namespaces_get():to_array()
387 if #nspaces > 1 then
388 local lnspaces = {}
389 for i = 2, #nspaces do
390 lnspaces[i - 1] = '"' .. nspaces[i]:lower() .. '"'
391 end
392 s:write("local __M = util.get_namespace(M, { ",
393 table.concat(lnspaces, ", "), " })\n")
394 return "__M"
395 else
396 return "M"
397 end
398end
399
400local Mixin = Node:clone {
401 __ctor = function(self, iface, klass, ch, evs)
402 self.klass = klass
403 self.children = ch
404 self.events = evs
405 self.iface = iface
406 end,
407
408 generate = function(self, s)
409 dom:log(log.level.INFO, " Generating for interface/mixin: "
410 .. self.klass:name_get())
411
412 s:write("ffi.cdef [[\n")
413 self:gen_ffi(s)
414 s:write("]]\n\n")
415
416 gen_ns(self.klass, s)
417
418 s:write("__body = {\n")
419 self:gen_children(s)
420 s:write("}\n")
421
422 local knu = self.klass:name_get():gsub("%.", "_")
423 if not self.iface then
424 s:write(("__body[\"__mixin_%s\"] = true\n"):format(knu))
425 else
426 s:write(("__body[\"__iface_%s\"] = true\n"):format(knu))
427 end
428 end,
429
430 gen_ffi = function(self, s)
431 s:write(" const Eo_Class *", self.klass:c_get_function_name_get(),
432 "(void);\n")
433 for i, v in ipairs(self.children) do
434 v.parent_node = self
435 v:gen_ffi(s)
436 end
437 if self.events then
438 for i, v in ipairs(self.events) do
439 v.parent_node = self
440 v:gen_ffi(s)
441 end
442 end
443 end
444}
445
446local build_pn = function(fn, pn)
447 if fn == pn then
448 return kw_t(pn)
449 end
450 return fn .. "_" .. pn
451end
452
453local Class = Node:clone {
454 __ctor = function(self, klass, parents, mixins, ch, evs)
455 self.klass = klass
456 self.parents = parents
457 self.interfaces = interfaces
458 self.mixins = mixins
459 self.children = ch
460 self.events = evs
461 end,
462
463 generate = function(self, s)
464 dom:log(log.level.INFO, " Generating for class: "
465 .. self.klass:name_get())
466
467 s:write("ffi.cdef [[\n")
468 self:gen_ffi(s)
469 s:write("]]\n\n")
470
471 local mname = gen_ns(self.klass, s)
472
473 s:write("__body = {\n")
474 self:gen_ctor(s)
475 self:gen_children(s)
476 s:write("}\n")
477
478 -- write the constructor
479 s:write(([[
480
481%s.%s = function(parent, ...)
482 return eo.__ctor_common(__class, parent, eo.class_get("%s").__eo_ctor,
483 1, ...)
484end
485]]):format(mname, self.klass:short_name_get(), self.klass:name_get():gsub("%.",
486 "_")))
487 end,
488
489 gen_ffi = Mixin.gen_ffi,
490
491 gen_ctor = function(self, s)
492 local ctors = self.klass:constructors_get()
493 if not ctors then return end
494 -- collect constructor information
495 s:write(" __eo_ctor = function(self, ")
496 local cfuncs, parnames, upars = {}, {}, {}
497 for ctor in ctors do
498 local cfunc = ctor:function_get()
499 local cn = cfunc:name_get()
500 local tp = cfunc:type_get()
501 if tp == func_type.PROPERTY or tp == func_type.PROP_SET
502 or tp == func_type.METHOD then
503 cfuncs[#cfuncs + 1] = cfunc
504 if tp ~= func_type.METHOD then
505 for par in cfunc:property_keys_get(func_type.PROP_SET) do
506 parnames[#parnames + 1] = build_pn(cn, par:name_get())
507 end
508 end
509 local iter = (tp ~= func_type.METHOD)
510 and cfunc:property_values_get(func_type.PROP_SET)
511 or cfunc:parameters_get()
512 for par in iter do
513 if par:direction_get() ~= param_dir.OUT then
514 parnames[#parnames + 1] = build_pn(cn, par:name_get())
515 end
516 end
517 end
518 end
519 s:write(table.concat(parnames, ", "))
520 if #parnames == 0 then
521 s:write("__func")
522 else
523 s:write(", __func")
524 end
525 s:write(")\n")
526 -- write ctor body
527 local j = 1
528 for i, cfunc in ipairs(cfuncs) do
529 local tp = cfunc:type_get()
530 s:write(" self:", cfunc:name_get())
531 if cfunc:type_get() ~= func_type.METHOD then
532 s:write("_set")
533 end
534 s:write("(")
535 local fpars = {}
536 if tp ~= func_type.METHOD then
537 for par in cfunc:property_keys_get(func_type.PROP_SET) do
538 fpars[#fpars + 1] = parnames[j]
539 j = j + 1
540 end
541 end
542 local iter = (tp ~= func_type.METHOD)
543 and cfunc:property_values_get(func_type.PROP_SET)
544 or cfunc:parameters_get()
545 for par in iter do
546 if par:direction_get() ~= param_dir.OUT then
547 fpars[#fpars + 1] = parnames[j]
548 j = j + 1
549 end
550 end
551 s:write(table.concat(fpars, ", "))
552 s:write(")\n")
553 end
554 s:write(" if __func then __func() end\n")
555 s:write(" end")
556 if #self.children > 0 then
557 s:write(",\n\n")
558 else
559 s:write("\n")
560 end
561 end
562}
563
564local File = Node:clone {
565 __ctor = function(self, fname, klass, ch)
566 self.fname = fname:match(".+/(.+)") or fname
567 self.klass = klass
568 self.children = ch
569 end,
570
571 generate = function(self, s)
572 local kls = self.klass
573 local ckls = self.children[1]
574
575 local kn = kls:name_get()
576
577 dom:log(log.level.INFO, "Generating for file: " .. self.fname)
578 dom:log(log.level.INFO, " Class : " .. kn)
579
580 local knu = kn:gsub("%.", "_")
581
582 local pars = ckls.parents or {}
583 local mins = ckls.mixins or {}
584
585 -- serialize both
586 local pv = {}
587 local mv = {}
588 for i = 1, #pars do pv[i] = '"' .. pars[i]:gsub("%.", "_") .. '"' end
589 for i = 1, #mins do mv[i] = '"' .. mins[i]:gsub("%.", "_") .. '"' end
590 pars = (#pars > 0) and ("{" .. table.concat(pv, ", ") .. "}") or "nil"
591 mins = (#mins > 0) and ("{" .. table.concat(mv, ", ") .. "}") or "nil"
592
593 s:write(([[
594-- EFL LuaJIT bindings: %s (class %s)
595-- For use with Elua; automatically generated, do not modify
596
597local cutil = require("cutil")
598local util = require("util")
599local ffi = require("ffi")
600local eo = require("eo")
601
602local M, __lib = ...
603
604local __class
605local __body
606
607local init = function()
608 __class = __lib.%s()
609 eo.class_register("%s", %s, %s, __body, __class)
610end
611
612cutil.init_module(init, function() end)
613
614]]):format(self.fname, kn, kls:c_get_function_name_get(), knu, pars, mins))
615
616 self:gen_children(s)
617
618 s:write([[
619
620return M
621]])
622
623 local first = true
624 for name, v in pairs(convfuncs) do
625 if first then
626 print("\nRequired conversion functions:")
627 first = false
628 end
629 print(" " .. name)
630 end
631 end
632}
633
634local gen_contents = function(klass)
635 local cnt = {}
636 -- first try properties
637 local props = klass:functions_get(func_type.PROPERTY):to_array()
638 for i, v in ipairs(props) do
639 local gscope = v:scope_get(func_type.PROP_GET)
640 local sscope = v:scope_get(func_type.PROP_SET)
641 if (gscope == obj_scope.PUBLIC or sscope == obj_scope.PUBLIC) then
642 local ftype = v:type_get()
643 local fread = (ftype == func_type.PROPERTY or ftype == func_type.PROP_GET)
644 local fwrite = (ftype == func_type.PROPERTY or ftype == func_type.PROP_SET)
645 if fwrite and sscope == obj_scope.PUBLIC then
646 cnt[#cnt + 1] = Property(v, func_type.PROP_SET)
647 end
648 if fread and gscope == obj_scope.PUBLIC then
649 cnt[#cnt + 1] = Property(v, func_type.PROP_GET)
650 end
651 end
652 end
653 -- then methods
654 local meths = klass:functions_get(func_type.METHOD):to_array()
655 for i, v in ipairs(meths) do
656 if v:scope_get(func_type.METHOD) == obj_scope.PUBLIC then
657 cnt[#cnt + 1] = Method(v)
658 end
659 end
660 -- events
661 local evs = {}
662 local events = klass:events_get():to_array()
663 for i, v in ipairs(events) do
664 evs[#evs + 1] = Event(v:name_get(), v:type_get(), v:c_name_get())
665 end
666 return cnt, evs
667end
668
669local gen_class = function(klass)
670 local tp = klass:type_get()
671 if tp == class_type.UNKNOWN then
672 error(klass:name_get() .. ": unknown type")
673 elseif tp == class_type.MIXIN or tp == class_type.INTERFACE then
674 return Mixin(tp == class_type.INTERFACE, klass, gen_contents(klass))
675 end
676 local inherits = klass:inherits_get():to_array()
677 -- figure out the correct lookup order
678 local parents = {}
679 local mixins = {} -- also includes ifaces, they're separated later
680 for i = 1, #inherits do
681 local tp = inherits[i]:type_get()
682 if tp == class_type.REGULAR or tp == class_type.ABSTRACT then
683 parents[#parents + 1] = v
684 elseif tp == class_type.INTERFACE or tp == class_type.MIXIN then
685 mixins[#mixins + 1] = v
686 else
687 error(klass:name_get() .. ": unknown inherit " .. v)
688 end
689 end
690 return Class(klass, parents, mixins, gen_contents(klass))
691end
692
693M.include_dir = function(dir)
694 if not get_state():directory_add(dir) then
695 error("Failed including directory: " .. dir)
696 end
697end
698
699M.load_eot_files = function()
700 return get_state():all_eot_files_parse()
701end
702
703M.system_directory_add = function()
704 return get_state():system_directory_add()
705end
706
707M.generate = function(fname, fstream)
708 local unit = get_state():file_parse(fname)
709 if unit == nil then
710 error("Failed parsing file: " .. fname)
711 end
712 gen_unit = unit
713 local sfn = fname:match(".*[\\/](.+)$") or fname
714 local klass = get_state():class_by_file_get(sfn)
715 File(fname, klass, { gen_class(klass) }):generate(fstream or io.stdout)
716end
717
718return M