gdjn  Diff

Differences From Artifact [eeaa9e3ddf]:

To Artifact [37b502b2c6]:


    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")))))