+\ ---- Primitives ---- {{{
+
+: make-primitive ( cfa -- )
+ bl word
+ count
+
+ \ 2dup ." Defining primitive " type ." ..." cr
+
+ cstr>charlist
+ drop symbol-type
+
+ 2dup
+
+ symbol-table obj@
+ cons
+ symbol-table obj!
+
+ rot primitive-proc-type ( var prim )
+ global-env obj@ define-var
+;
+
+: arg-count-error
+ bold fg red ." Incorrect argument count." reset-term cr
+ abort
+;
+
+: ensure-arg-count ( args n -- )
+ dup 0= if
+ drop nil objeq? false = if
+ arg-count-error
+ then
+ else
+ -rot 2dup nil objeq? if
+ arg-count-error
+ then
+
+ cdr rot 1- recurse
+ then
+;
+
+: arg-type-error
+ bold fg red ." Incorrect argument type." reset-term cr
+ abort
+;
+
+: ensure-arg-type ( arg type -- arg )
+ istype? false = if
+ arg-type-error
+ then
+;
+
+include scheme-primitives.4th
+
+\ }}}
+
+\ ---- Loading files ---- {{{
+
+: charlist>cstr ( charlist addr -- n )
+
+ dup 2swap ( origaddr addr charlist )
+
+ begin
+ 2dup nil objeq? false =
+ while
+ 2dup cdr 2swap car
+ drop ( origaddr addr charlist char )
+ -rot 2swap ( origaddr charlist addr char )
+ over !
+ 1+ -rot ( origaddr nextaddr charlist )
+ repeat
+
+ 2drop ( origaddr finaladdr )
+ swap -
+;
+
+: load ( addr n -- )
+ open-input-file
+
+ empty-parse-str
+
+ begin
+ 2dup read-port
+
+ 2dup EOF character-type objeq? if
+ 2drop close-port
+ exit
+ then
+
+ global-env obj@ eval
+ 2drop
+ again
+;
+
+\ }}}
+