forked from zeromq/zproject
-
Notifications
You must be signed in to change notification settings - Fork 0
/
zproject_lua_ffi.gsl
146 lines (138 loc) · 4.73 KB
/
zproject_lua_ffi.gsl
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Generate minimal Lua language bindings that use CFFI.
#
# These are not meant to be idiomatic, but to provide a minimal platform
# of FFI function bindings on which to base idiomatic Lua code.
#
# This is a code generator built using the iMatix GSL code generation
# language. See https://github.com/zeromq/gsl for details.
#
# Copyright (c) the Contributors as noted in the AUTHORS file.
# This file is part of zproject.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
register_target ("lua_ffi", "Lua FFI binding")
# Target provides name space isolation for its functions
function target_lua_ffi
function register_type (struct, pointer)
if count(project->lua_types.type, type.name = my.struct) = 0
new project->lua_types.type
type.name = my.struct
type.pointer = my.pointer
endnew
endif
endfunction
function resolve_container (container)
if my.container.variadic
elsif my.container.type = "nothing"
elsif my.container.type = "anything" | my.container.type = "sockish"
elsif my.container.type = "boolean"
elsif my.container.type = "byte"
elsif my.container.type = "integer" | my.container.type = "file_size" | my.container.type = "time"
elsif my.container.type = "number"
elsif my.container.type = "size"
elsif my.container.type = "real"
elsif my.container.type = "buffer"
elsif my.container.type = "FILE"
elsif my.container.type = "string" | my.container.type = "format"
elsif my.container.callback
else
register_type ("$(my.container.type:c,no)_t", "$(my.container.type:c,no)_p")
endif
endfunction
function resolve_method (method)
my.method.python_name = "$(my.method.name:c)"
if regexp.match ("^(is|from)$", my.method.python_name) # matches keyword
my.method.python_name += "_"
endif
for my.method.argument where !argument.variadic
resolve_container (argument)
endfor
for my.method.return as ret
resolve_container (ret)
endfor
endfunction
function resolve_class (class)
register_type("$(class.c_name)_t", "$(class.c_name)_p")
for my.class.callback_type as method
resolve_method (method)
endfor
for my.class.constructor as method
resolve_method (method)
endfor
for my.class.destructor as method
resolve_method (method)
endfor
for my.class.method
resolve_method (method)
endfor
endfunction
function generate_binding
directory.create ("bindings/lua_ffi")
output "bindings/lua_ffi/$(project.name:c)_ffi.lua"
>$(project.GENERATED_WARNING_HEADER_FOR_LUA:)
>
>$(project.name:c)_ffi = {}
>$(project.name:c)_ffi.ffi = require ("ffi")
>
>-- typedefs simulating C standard library
>-- see https://github.com/eliben/pycparser/blob/master/utils/fake_libc_include/_fake_defines.h
>$(project.name:c)_ffi.ffi.cdef [[
>typedef struct __FILE FILE;
>typedef int time_t;
>typedef int off_t;
>]]
>
>-- czmq_prelude.h
>$(project.name:c)_ffi.ffi.cdef [[
>typedef unsigned char byte;
>typedef int SOCKET;
>]]
>$(project.name:c)_ffi.ffi.cdef [[
for project->lua_types.type as t
>typedef struct _$(t.name:c) $(t.name:c);
endfor
for class where defined (class.api) & class.private = "0"
for class.callback_type
>// $(callback_type.description:no,block)
>$(c_callback_typedef (callback_type):)
>
endfor
endfor
for class where defined (class.api) & class.private = "0"
>// CLASS: $(class.name)
for class. as f
if class(f) = "XML item" & (name(f) = 'constructor' | name(f) = 'destructor')
>// $(f.description:no,block)
>$(c_method_signature (f):);
>
endif
endfor
for class.actor
>// $(actor.description:no,block)
>$(PROJECT.PREFIX)_EXPORT void
> $(actor.name:c) (zsock_t *pipe, void *args);
>
endfor
for class.method
>// $(method.description:no,block)
>$(c_method_signature (method):);
>
endfor
endfor
>]]
>
>$(project.name:c)_ffi.$(prefix) = $(project.name:c)_ffi.ffi.load ("$(project.libname)")
>return $(project.name:c)_ffi
endfunction
if count (class, defined (class.api) & class.private = "0")
# Container for UDTs used by this module
new lua_types
endnew
for class where defined (class.api) & class.private = "0"
resolve_class (class)
endfor
generate_binding ()
endif
endfunction