("+" . #("[!v,!v,!v...]*" "addition operator: overload xtm_addition to add support for new types" (arg1 arg2...)))
("-" . #("[!v,!v,!v...]*" "subtraction operator: overload xtm_subtraction to add support for new types" (arg1 arg2...)))
("*" . #("[!v,!v,!v...]*" "multiplication operator: overload xtm_multiplication to add support for new types" (arg1 arg2...)))
("/" . #("[!v,!v,!v...]*" "division operator: overload xtm_division to add support for new types" (arg1 arg2...)))
("%" . #("[!v,!v,!v]*" "modulo operator: overload xtm_modulo to add support for new types" (arg1 arg2)))
("set!" . #("[!v,!v,!v]*" "set var to value" (var value)))
;; pointer/tuple/array/vector set/ref
("pref" . #("[!v,!v*,i64]*" "pointer-(de)reference" (ptr idx)))
("pref-ptr" . #("[!v*,!v*,i64]*" "pointer-(de)reference" (ptr idx)))
("pset!" . #("[!v,!v*,i64,!v]*" "pointer-set" (ptr idx val)))
("pfill!" . #("[!v,!v*,!v...]*" "pointer-fill fill ptr with values" (ptr v1...)))
("tref" . #("[!v,!v*,i64]*" "tuple-(de)reference" (tuple idx)))
("tref-ptr" . #("[!v*,!v*,i64]*" "tuple-(de)reference" (tuple idx)))
("tset!" . #("[!v,!v*,i64,!v]*" "tuple-set" (tuple idx val)))
("tfill!" . #("[!v,!v*,!v...]*" "tuple-fill fill tuple with values" (tuple v1...)))
("aref" . #("[!v,!v*,i64]*" "array-(de)reference" (array idx)))
("aref-ptr" . #("[!v*,!v*,i64]*" "array-(de)reference" (array idx)))
("aset!" . #("[!v,!v*,i64,!v]*" "array-set" (array idx val)))
("afill!" . #("[!v,!v*,!v...]*" "array-fill fill array with values" (array v1...)))
("vref" . #("[!v,!v*,i64]*" "vector-(de)reference" (vector idx)))
("vref-ptr" . #("[!v*,!v*,i64]*" "vector-(de)reference" (vector idx)))
("vset!" . #("[!v,!v*,i64,!v]*" "vector-set" (vector idx val)))
("vfill!" . #("[!v,!v*,!v...]*" "vector-fill fill vector with values" (vector v1...)))
;; printing
("println" . #("[void,!v...]*" "generic print function - to add support for NewType, overload print:[void,NewType]*" (val1...)))
;; memory allocation
("alloc" . #("[!v*,i64]*" "allocate memory from current zone with size (optional, default = 1)" (optional-size)))
("zalloc" . #("[!v*,i64]*" "allocate memory from current zone with size (optional, default = 1)" (optional-size)))
("halloc" . #("[!v*,i64]*" "allocate memory from the heap with size (optional, default = 1)" (optional-size)))
("salloc" . #("[!v*,i64]*" "allocate memory from the stack zone with size (optional, default = 1)" (optional-size)))
;; Extempore runtime stuff
("callback" . #("[i1,i64,sym,args...]*" "set callback for closure at time with args" (time closure args...)))
;; special scheme macros
("call-as-xtlang" . #("[String*,!v]*" "the body of this (scheme) macro will be executed as xtlang" (body)))))
;;
;; language builtins - the cache is just used for documentation at
;; this stage, the actual builtins are handled in the compiler (mostly
;; in first-transform). In the future, however, we could integrate
;; that stuff into the builtin-cache
;;
;; (name . #(type-str docstring args))
;;
;; The other differences between this and the closure-list are that
;; the type is stored as a string rather than a list (so that we can
;; handle weird/overloaded/varargs things nicely for documentation
;; purposes) and also that "body" is replaced by "args"
;;
(define impc:ti:print-builtin-cache
(lambda ()
(println '*impc:ti:builtin-cache*: *impc:ti:builtin-cache*)))