Differences From
Artifact [eeaa9e3ddf]:
72 72 [ ;((<gd-sym> :%init) spec)
73 73 :binds (map bind-def
74 74 (or (spec :binds) []))
75 75 :methods (map bind-def
76 76 (or (spec :methods) []))
77 77 :ops (map bind-def
78 78 (or (spec :ops) []))
79 + :indexed (or (spec :indexed) false)
79 80 :ctors (or (spec :ctors) {})
80 - :mode (spec :mode)])
81 + :mode (spec :mode)
82 + :c-repr (spec :c-repr)])
81 83 :binds []
82 84 :methods []
83 85 :ctors {}
84 86 :ops []
85 87 :mode :
88 + :c-type (fn [me]
89 + (string (or (me :c-repr)
90 + (string "gd_" (:name me)))))
86 91 :enum (fn [me]
87 92 (string "GDEXTENSION_VARIANT_TYPE_" (:scream me)))
88 93 ))
89 94
90 95 (defn env: [v dflt]
91 96 (or ((os/environ) v) dflt))
92 97
................................................................................
121 126 (has-value? x)))
122 127 (def variants (map |(:@new <gd-type> $) ~[
123 128 {:id variant :binds [get-ptr-constructor
124 129 get-ptr-destructor
125 130 get-ptr-operator-evaluator
126 131 get-ptr-internal-getter
127 132 get-ptr-builtin-method
133 + get-indexed set-indexed
134 + get-named set-named
128 135 get-type
129 136 booleanize]}
130 - {:id bool }
137 + {:id bool }
138 + {:id int }
139 + {:id float }
131 140 {:id color }
132 141
133 - ,;(map |{:id $} vector-types)
134 - ,;(map |{:id $
142 + ,;(map |{:id $ :mode :dc} vector-types)
143 + ,;(map |{:id $ :mode :dc
135 144 :methods '[get set size resize fill clear
136 145 append append_array insert remove-at
137 146 has is-empty find rfind count
138 147 reverse slice duplicate]
139 148 :ctors {:empty []}
140 149 }
141 150 packed-types)
142 - {:id array
143 - :binds [ref set-typed]
144 - :ctors {:empty []}}
145 - {:id dictionary
151 + {:id array :mode :dc
152 + :binds [ref set-typed operator-index operator-index-const]
153 + :methods [size is-empty clear]
154 + :ctors {:empty []}
155 + :indexed true}
156 + {:id dictionary :mode :dc
146 157 :binds [set-typed operator-index operator-index-const]
147 - :ctors {:empty []}}
158 + :methods [size is-empty clear]
159 + :ctors {:empty []}
160 + :indexed true}
148 161
149 162 {:id string-name :mode :dc
150 163 :ops [equal]
151 164 :binds [new-with-utf8-chars
152 165 new-with-utf8-chars-and-len]
153 166 :methods [length
154 167 ends-with begins-with
................................................................................
198 211 get-reference-count]}
199 212 {:id script :binds [get-source-code set-source-code]}
200 213 {:id file-access :binds [open close store-string get-as-text]}
201 214 {:id resource-loader :binds [add-resource-format-loader
202 215 remove-resource-format-loader]}
203 216 {:id resource-saver :binds [add-resource-format-saver
204 217 remove-resource-format-saver]}
218 + {:id script-language-extension}
219 + {:id script-extension}
205 220 ]))
206 221
207 222 (def global-enums (map |(:from <gd-sym> $) '[
208 223 error
209 224 ]))
210 225
211 226 (def singletons (map |(:from <gd-sym> $) '[
................................................................................
224 239 (def api {
225 240 :decls @[]
226 241 :aliases @[]
227 242 :calls @[]
228 243 :defer-calls @[] # dependency Hel bypass
229 244 :types @[]
230 245 :method-defs @[]
246 + :methods-inline @[]
247 + :wrappers @[]
231 248 })
232 249 (def config (env: "gd_config" "double_64"))
233 250 (def sizes (do
234 251 (var sz-list nil)
235 252 (loop [cfg :in (api-spec "builtin_class_sizes")
236 253 :until (not= nil sz-list)]
237 254 (when (= config (cfg "build_configuration"))
................................................................................
246 263 (case (sizes x)
247 264 4 small
248 265 8 big
249 266 (error (string "bad type size " (sizes x) " for " x))))
250 267 (case x
251 268 "int" (bp "int" "int32_t" "int64_t")
252 269 "float" (bp "float" "float" "double")
253 - "bool" "bool"))
270 + "bool" "bool"
271 + "object" "GDExtensionObjectPtr"))
254 272 (defn variant:gd->c [x]
255 273 (def v (find |(= x (:tall (:@new <gd-sym> {:id ($ :id)}))) variants))
256 274 (string "gd_" (:name v)))
257 275 (defn translate-type [st &opt flags]
258 276 (defn fl [x] (string/check-set (or flags :) x))
259 277 (match (string/split "::" st)
260 278 # enums can be directly mapped to a C
................................................................................
342 360 (def id (string "gd_" (:tall class) "_" (e "name")))
343 361 # the underlying type is IMPORTANT! godot enums
344 362 # appear to use the godot int type, which (at present)
345 363 # is always 8 bytes long. this means trying to write
346 364 # a godot "enum" to a plain old C enum will, if you
347 365 # are very lucky, cause your program to barf all over
348 366 # the stack and immediately segfault
349 - (ln "typedef enum %s : int64_t {" id)
367 + (ln "typedef enum %s : GDExtensionInt {" id)
350 368 # thank the gods for C23. this would have been really
351 369 # unpleasant otherwise
352 370 (each n (e "values")
353 371 (def ident (:from-snek <gd-sym> (n "name")))
354 372 (def sym (:@new <gd-sym> ident))
355 373 (ln "\t%s_%s = %d," id (:name sym) (n "value"))
356 374 (ln "\t/* %s */"
................................................................................
399 417 (def name (:from-snek <gd-sym> (v "name")))
400 418 (ln "\tgd_%s_%s = %d," (:tall e) (:name name) (v "value"))
401 419 (when (v "description")
402 420 (ln "\t/* %s */" (v "description"))))
403 421 (ln "} gd_%s;\n" (:tall e))
404 422 )
405 423
424 + (add (api :wrappers)
425 + (string
426 + "auto getWrap = "
427 + "(GDExtensionInterfaceGetVariantFromTypeConstructor)"
428 + `getProc("get_variant_from_type_constructor");`
429 + "\nauto getCast = "
430 + "(GDExtensionInterfaceGetVariantToTypeConstructor)"
431 + `getProc("get_variant_to_type_constructor");` "\n"))
406 432 (loop [v :in variants
407 433 :let [vsz (or (sizes (:tall v))
408 434 (sizes (string (v :id) )))]]
409 435 (add (api :aliases) # these are all opaque objects
410 436 "typedef _opaque(%d) gd_%s;"
411 437 vsz (:name v))
412 438 (add (api :decls ) "struct {")
413 439 (def my-enum (:enum v))
414 440 (add-methods v (v :binds))
415 441 (add-enums v)
442 + (unless (= (v :id) 'variant)
443 + (add (api :decls)
444 + "\tGDExtensionVariantFromTypeConstructorFunc wrap;")
445 + (add (api :decls)
446 + "\tGDExtensionTypeFromVariantConstructorFunc cast;")
447 + (add (api :wrappers) "t -> gd_%s.wrap = getWrap(%s);"
448 + (:name v) (:enum v))
449 + (add (api :wrappers) "t -> gd_%s.cast = getCast(%s);"
450 + (:name v) (:enum v))
451 + (def ct (or (prim:gd->c (:name v))
452 + (variant:gd->c (:tall v))))
453 + (add (api :methods-inline)
454 + (string "static inline %s\n"
455 + "gd_variant_to_%s\n"
456 + "(\tgd_variant const* const v\n"
457 + ") {\n"
458 + "\textern struct gdjn_typeDB* _g_typeDB;"
459 + "\t%s ret = {};\n"
460 + "\t_g_typeDB -> gd_%s.cast(&ret, (void*)v);\n"
461 + "\treturn ret;\n"
462 + "}\n")
463 + ct (:name v)
464 + ct (:name v) )
465 + (add (api :methods-inline)
466 + (string "static inline gd_variant\n"
467 + "gd_variant_of_%s\n"
468 + "(\t%s v\n"
469 + ") {\n"
470 + "\textern struct gdjn_typeDB* _g_typeDB;"
471 + "\tgd_variant ret = {};\n"
472 + "\t_g_typeDB -> gd_%s.wrap(&ret, &v);\n"
473 + "\treturn ret;\n"
474 + "}\n")
475 + (:name v)
476 + ct
477 + (:name v)
478 + ))
416 479
417 480 # bind builtins
418 481 # WHY IS THIS *YET ANOTHER* COMPLETELY DIFFERENT API
419 482 # for the SAME LITERAL THING fuck youuuuu
420 483 (when (has-key? gdclasses (:tall v)) (loop [m :in (v :methods)
421 484 :let [method (get-in gdclasses [(:tall v) :methods
422 485 (:sulk m)])]]
................................................................................
427 490 (translate-type (method :return_type))))
428 491 (def args (method:args method (:tall v)
429 492 (if (method :is_const) :c :)))
430 493
431 494 (def impl @[])
432 495 (unless (= return-type "void")
433 496 (array/push impl
434 - (string/format "typeof(%s) ret;" return-type)))
497 + (string/format "typeof(%s) ret = {};" return-type)))
435 498 (array/push impl
436 499 (string/format "_g_typeDB -> gd_%s.%s("
437 500 (:name v) (:name m)))
438 501
439 502
440 503 (array/push impl
441 504 (string "\t" (if (method :is_static)
................................................................................
619 682 (print "\ntypedef struct gdjn_typeDB {")
620 683 (loop [d :in (api :decls)]
621 684 (print "\t" d))
622 685 (print "} gdjn_typeDB;")
623 686 (each t (api :types) (print t))
624 687 (print c-fetch-decl ";")
625 688 (each m (api :method-defs)
626 - (print (m :dfn) ";")))
689 + (print (m :dfn) ";"))
690 + (each m (api :methods-inline)
691 + (print m)))
627 692
628 693 "loader" (do
629 694 (print "#include <stdlib.h>\n"
630 695 "#include <stdio.h>\n"
631 696 "#include <assert.h>\n"
632 697 "#include \"interface.h\"\n\n"
633 - "static gdjn_typeDB* _g_typeDB;\n\n"
698 + "gdjn_typeDB* _g_typeDB;\n\n"
634 699 # HORRID HACK
635 700
636 701 c-fetch-decl "{\n"
637 702 ;(map |(string "\t" $ "\n")
638 703 [ "_g_typeDB = t;"
639 704 ;(api :calls)
705 + "{"
706 + ;(api :wrappers)
707 + "}"
640 708 ;(api :defer-calls) ])
641 709 "}")
642 710 (each m (api :method-defs)
643 711 (print (m :dfn) "{\n\t" (string/join (m :impl) "\n\t") "\n}\n")))))