1 ! Copyright (C) 2010 Anton Gorenko.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types alien.parser arrays ascii
4 classes.parser classes.struct combinators combinators.short-circuit
5 gobject-introspection.repository gobject-introspection.types kernel
6 locals make math.parser namespaces parser sequences
7 splitting.monotonic vocabs.parser words words.constant ;
8 IN: gobject-introspection.ffi
10 : def-c-type ( c-type-name base-c-type -- )
11 swap (CREATE-C-TYPE) typedef ;
13 : defer-c-type ( c-type-name -- c-type )
14 deferred-type swap (CREATE-C-TYPE) [ typedef ] keep ;
16 ! [ fake-definition ] [ undefined-def define ] bi ;
18 :: defer-types ( types type-info-class -- )
20 [ c-type>> defer-c-type ]
21 [ name>> qualified-name ] bi
22 type-info-class new swap register-type
25 : def-alias-c-type ( base-c-type c-type-name -- c-type )
26 (CREATE-C-TYPE) [ typedef ] keep ;
28 : alias-c-type-name ( alias -- c-type-name )
29 ! <workaround for alises w/o c:type (Atk)
30 [ c-type>> ] [ name>> ] bi or ;
34 :: def-alias ( alias -- )
35 alias type>> get-type-info
36 [ c-type>> alias alias-c-type-name def-alias-c-type ]
37 [ clone ] bi alias name>> qualified-name register-type ;
39 : def-aliases ( aliases -- )
42 GENERIC: type>c-type ( type -- c-type )
44 M: atomic-type type>c-type get-type-info c-type>> ;
45 M: enum-type type>c-type get-type-info c-type>> ;
46 M: bitfield-type type>c-type get-type-info c-type>> ;
47 M: record-type type>c-type get-type-info c-type>> <pointer> ;
48 M: union-type type>c-type get-type-info c-type>> <pointer> ;
49 M: boxed-type type>c-type get-type-info c-type>> <pointer> ;
50 M: callback-type type>c-type get-type-info c-type>> ;
51 M: class-type type>c-type get-type-info c-type>> <pointer> ;
52 M: interface-type type>c-type get-type-info c-type>> <pointer> ;
54 M: boxed-array-type type>c-type
55 name>> simple-type new swap >>name type>c-type ;
57 M: c-array-type type>c-type
58 element-type>> type>c-type <pointer> ;
60 M: fixed-size-array-type type>c-type
61 [ element-type>> type>c-type ] [ fixed-size>> ] bi 2array ;
63 ! <workaround for <type/> (in some signals and properties)
64 PREDICATE: incorrect-type < simple-type name>> not ;
65 M: incorrect-type type>c-type drop void* ;
68 GENERIC: parse-const-value ( str data-type -- value )
70 M: atomic-type parse-const-value
72 { "gint" [ string>number ] }
73 { "gdouble" [ string>number ] }
76 M: utf8-type parse-const-value drop ;
78 : const-value ( const -- value )
79 [ value>> ] [ type>> ] bi parse-const-value ;
81 : def-const ( const -- )
82 [ c-identifier>> create-in dup reset-generic ]
83 [ const-value ] bi define-constant ;
85 : def-consts ( consts -- )
88 : define-enum-member ( member -- )
89 [ c-identifier>> create-in dup reset-generic ]
90 [ value>> ] bi define-constant ;
92 : def-enum-type ( enum -- )
93 [ members>> [ define-enum-member ] each ]
94 [ c-type>> int def-c-type ] bi ;
96 : def-bitfield-type ( bitfield -- )
99 GENERIC: parameter-type>c-type ( data-type -- c-type )
101 M: data-type parameter-type>c-type type>c-type ;
102 M: varargs-type parameter-type>c-type drop void* ;
104 : parameter-c-type ( parameter -- c-type )
105 [ type>> parameter-type>c-type ] keep
106 direction>> "in" = [ <pointer> ] unless ;
108 GENERIC: return-type>c-type ( data-type -- c-type )
110 M: data-type return-type>c-type type>c-type ;
111 M: none-type return-type>c-type drop void ;
113 : return-c-type ( return -- c-type )
114 type>> return-type>c-type ;
116 : parameter-name ( parameter -- name )
117 dup type>> varargs-type?
118 [ drop "varargs" ] [ name>> "!incorrect-name!" or ] if ;
120 : error-parameter ( -- parameter )
124 "none" >>transfer-ownership
125 simple-type new "GLib.Error" >>name >>type ;
127 : ?suffix-parameters-with-error ( callable -- parameters )
128 [ parameters>> ] [ throws?>> ] bi
129 [ error-parameter suffix ] when ;
131 : parameter-names&types ( callable -- names types )
132 [ [ parameter-c-type ] map ] [ [ parameter-name ] map ] bi ;
134 : def-function ( function -- )
136 [ return>> return-c-type ]
138 [ drop current-library get ]
139 [ ?suffix-parameters-with-error parameter-names&types ]
140 } cleave make-function define-inline ;
142 : def-functions ( functions -- )
143 [ def-function ] each ;
145 GENERIC: type>data-type ( type -- data-type )
147 M: type type>data-type
148 [ simple-type new ] dip name>> >>name ;
150 : word-started? ( word letter -- ? )
151 [ letter? ] [ LETTER? ] bi* and ; inline
153 : camel-case>underscore-separated ( str -- str' )
154 [ word-started? not ] monotonic-split "_" join >lower ;
156 : type>parameter-name ( type -- name )
157 name>> camel-case>underscore-separated ;
159 : type>parameter ( type -- parameter )
160 [ parameter new ] dip {
161 [ type>parameter-name >>name ]
162 [ type>data-type >>type ]
163 [ drop "in" >>direction "none" >>transfer-ownership ]
166 :: def-method ( method type -- )
168 [ return>> return-c-type ]
170 [ drop current-library get ]
172 ?suffix-parameters-with-error
173 type type>parameter prefix
174 parameter-names&types
176 } cleave make-function define-inline ;
178 : def-methods ( methods type -- )
179 [ def-method ] curry each ;
181 : def-callback-type ( callback -- )
183 [ drop current-library get ]
184 [ return>> return-c-type ]
186 [ ?suffix-parameters-with-error parameter-names&types ]
187 } cleave make-callback-type define-inline ;
189 GENERIC: field-type>c-type ( data-type -- c-type )
191 M: simple-type field-type>c-type type>c-type ;
192 M: inner-callback-type field-type>c-type drop void* ;
193 M: array-type field-type>c-type type>c-type ;
195 : field>struct-slot ( field -- slot )
197 [ dup bits>> [ drop uint ] [ type>> field-type>c-type ] if ]
200 [ drop ] ! [ writable?>> [ read-only , ] unless ]
201 [ bits>> [ bits: , , ] when* ] bi
203 ] tri <struct-slot-spec> ;
205 : def-record-type ( record -- )
208 [ c-type>> create-class-in ]
209 [ fields>> [ field>struct-slot ] map ] bi
211 ] [ c-type>> void def-c-type ] if ;
213 : def-record ( record -- )
216 [ constructors>> def-functions ]
217 [ functions>> def-functions ]
218 [ [ methods>> ] keep def-methods ]
221 : def-union-type ( union -- )
222 c-type>> void def-c-type ;
224 : private-record? ( record -- ? )
227 [ name>> "Class" tail? ]
228 [ name>> "Private" tail? ]
229 [ name>> "Iface" tail? ]
232 : def-union ( union -- )
235 [ constructors>> def-functions ]
236 [ functions>> def-functions ]
237 [ [ methods>> ] keep def-methods ]
240 : find-existing-boxed-type ( boxed -- type/f )
242 dup [ c-type? ] [ "c-type" word-prop ] bi or
246 : def-boxed-type ( boxed -- )
247 c-type>> void def-c-type ;
249 : signal-name ( signal type -- name )
250 swap [ c-type>> ] [ name>> ] bi* ":" glue ;
252 : user-data-parameter ( -- parameter )
256 "none" >>transfer-ownership
257 simple-type new "gpointer" >>name >>type ;
259 :: def-signal ( signal type -- )
261 [ drop current-library get ]
262 [ return>> return-c-type ]
265 parameters>> type type>parameter prefix
266 user-data-parameter suffix parameter-names&types
268 } cleave make-callback-type define-inline ;
270 : def-signals ( signals type -- )
271 [ def-signal ] curry each ;
273 : def-class-type ( class -- )
274 c-type>> void def-c-type ;
276 : def-class ( class -- )
279 [ constructors>> def-functions ]
280 [ functions>> def-functions ]
281 [ [ methods>> ] keep def-methods ]
282 [ [ signals>> ] keep def-signals ]
285 : def-interface-type ( interface -- )
286 c-type>> void def-c-type ;
288 : def-interface ( class -- )
290 [ def-interface-type ]
291 [ functions>> def-functions ]
292 [ [ methods>> ] keep def-methods ]
293 [ [ signals>> ] keep def-signals ]
296 : defer-enums ( enums -- ) enum-info defer-types ;
297 : defer-bitfields ( bitfields -- ) bitfield-info defer-types ;
298 : defer-unions ( unions -- ) union-info defer-types ;
299 : defer-callbacks ( callbacks -- ) callback-info defer-types ;
300 : defer-interfaces ( interfaces -- ) interface-info defer-types ;
301 : defer-classes ( class -- ) class-info defer-types ;
303 : defer-boxeds ( boxeds -- )
306 dup find-existing-boxed-type
307 [ nip ] [ c-type>> defer-c-type ] if*
309 [ name>> qualified-name ] bi
310 boxed-info new swap register-type
313 : defer-records ( records -- )
314 [ private-record? ] partition
315 [ begin-private record-info defer-types end-private ]
316 [ record-info defer-types ] bi* ;
318 : def-enums ( enums -- ) [ def-enum-type ] each ;
319 : def-bitfields ( bitfields -- ) [ def-bitfield-type ] each ;
320 : def-unions ( unions -- ) [ def-union ] each ;
321 : def-callbacks ( callbacks -- ) [ def-callback-type ] each ;
322 : def-interfaces ( interfaces -- ) [ def-interface ] each ;
323 : def-classes ( classes -- ) [ def-class ] each ;
325 : def-boxeds ( boxeds -- )
326 [ find-existing-boxed-type not ] filter
327 [ def-boxed-type ] each ;
329 : def-records ( records -- )
330 [ private-record? ] partition
331 [ begin-private [ def-record ] each end-private ]
332 [ [ def-record ] each ] bi* ;
334 : def-namespace ( namespace -- )
336 [ consts>> def-consts ]
338 [ enums>> defer-enums ]
339 [ bitfields>> defer-bitfields ]
340 [ records>> defer-records ]
341 [ unions>> defer-unions ]
342 [ boxeds>> defer-boxeds ]
343 [ callbacks>> defer-callbacks ]
344 [ interfaces>> defer-interfaces ]
345 [ classes>> defer-classes ]
347 [ aliases>> def-aliases ]
349 [ enums>> def-enums ]
350 [ bitfields>> def-bitfields ]
351 [ records>> def-records ]
352 [ unions>> def-unions ]
353 [ boxeds>> def-boxeds ]
354 [ callbacks>> def-callbacks ]
355 [ interfaces>> def-interfaces ]
356 [ classes>> def-classes ]
358 [ functions>> def-functions ]
361 : def-ffi-repository ( repository -- )
362 namespace>> def-namespace ;