1 \ ==== Type predilcates ==== {{{
3 :noname ( args -- boolobj )
4 nil objeq? boolean-type
5 ; 1 make-fa-primitive null?
7 :noname ( args -- boolobj )
8 boolean-type istype? -rot 2drop boolean-type
9 ; 1 make-fa-primitive boolean?
11 :noname ( args -- boolobj )
12 symbol-type istype? -rot 2drop boolean-type
13 ; 1 make-fa-primitive symbol?
15 :noname ( args -- boolobj )
16 fixnum-type istype? -rot 2drop boolean-type
17 ; 1 make-fa-primitive fixnum?
19 :noname ( args -- boolobj )
20 flonum-type istype? -rot 2drop boolean-type
21 ; 1 make-fa-primitive flonum?
23 :noname ( args -- boolobj )
24 ratnum-type istype? -rot 2drop boolean-type
25 ; 1 make-fa-primitive ratnum?
27 :noname ( args -- boolobj )
28 character-type istype? -rot 2drop boolean-type
29 ; 1 make-fa-primitive char?
31 :noname ( args -- boolobj )
32 string-type istype? -rot 2drop boolean-type
33 ; 1 make-fa-primitive string?
35 :noname ( args -- boolobj )
36 pair-type istype? -rot 2drop boolean-type
37 ; 1 make-fa-primitive pair?
39 :noname ( args -- boolobj )
40 primitive-proc-type istype? if
43 compound-proc-type istype?
46 -rot 2drop boolean-type
47 ; 1 make-fa-primitive procedure?
49 :noname ( args -- boolobj )
50 port-type istype? -rot 2drop boolean-type
51 ; 1 make-fa-primitive port?
55 \ ==== Type conversions ==== {{{
57 :noname ( args -- fixnum )
58 2dup 1 ensure-arg-count
59 car character-type ensure-arg-type
62 ; make-primitive char->integer
64 :noname ( args -- char )
65 2dup 1 ensure-arg-count
66 car fixnum-type ensure-arg-type
69 ; make-primitive integer->char
71 : fixnum-to-charlist ( fixnum -- charlist )
74 [char] 0 character-type nil cons
78 nil 2swap ( charlist fixnum )
83 2dup swap 10 mod swap ( charlist fixnum fixnummod )
84 2swap swap 10 / swap ( charlist fixnummod fixnumdiv )
85 -2rot ( fixnumdiv charlist fixnummod )
87 drop [char] 0 + character-type 2swap
88 cons ( fixnumdiv newcharlist )
96 :noname ( args -- string )
97 2dup 1 ensure-arg-count
98 car fixnum-type ensure-arg-type
102 fixnum-to-charlist ( fixnum charlist )
104 [char] - character-type 2swap cons
108 ; make-primitive number->string
110 :noname ( args -- symbol )
111 2dup 1 ensure-arg-count
112 car string-type ensure-arg-type
116 2dup car [char] - character-type objeq? if
120 2dup car [char] + character-type objeq? if
128 2dup nil objeq? false =
130 2dup car drop [char] 0 - -rot
131 2swap swap 10 * + -rot
140 ; make-primitive string->number
142 :noname ( args -- string )
143 2dup 1 ensure-arg-count
144 car symbol-type ensure-arg-type
149 ; make-primitive symbol->string
151 :noname ( args -- symbol )
152 2dup 1 ensure-arg-count
153 car string-type ensure-arg-type
158 ; make-primitive string->symbol
160 :noname ( charlist -- string )
161 2dup 1 ensure-arg-count
170 pair-type ensure-arg-type
174 ; make-primitive list->string
176 :noname ( string -- charlist )
177 2dup 1 ensure-arg-count
178 car string-type ensure-arg-type
189 ; make-primitive string->list
193 \ ==== Numeric types ==== {{{
197 :noname ( fixnum fixnum -- boolobj )
199 ; 2 make-fa-primitive fix:=
201 :noname ( fixnum fixnum -- boolobj )
202 drop swap drop < boolean-type
203 ; 2 make-fa-primitive fix:<
205 :noname ( fixnum fixnum -- boolobj )
206 drop swap drop > boolean-type
207 ; 2 make-fa-primitive fix:>
209 :noname ( fixnum fixnum -- boolobj )
210 drop swap drop <= boolean-type
211 ; 2 make-fa-primitive fix:<=
213 :noname ( fixnum fixnum -- boolobj )
214 drop swap drop >= boolean-type
215 ; 2 make-fa-primitive fix:>=
217 :noname ( fixnum -- boolobj )
219 ; 1 make-fa-primitive fix:zero?
221 :noname ( fixnum -- boolobj )
223 ; 1 make-fa-primitive fix:positive?
225 :noname ( fixnum -- boolobj )
227 ; 1 make-fa-primitive fix:negative?
229 :noname ( fixnum fixnum -- fixnum' )
230 drop swap drop + fixnum-type
231 ; 2 make-fa-primitive fix:+
233 :noname ( fixnum fixnum -- fixnum' )
234 drop swap drop - fixnum-type
235 ; 2 make-fa-primitive fix:-
237 :noname ( fixnum fixnum -- fixnum' )
238 drop swap drop * fixnum-type
239 ; 2 make-fa-primitive fix:*
241 :noname ( fixnum fixnum -- fixnum' )
242 drop swap drop / fixnum-type
243 ; 2 make-fa-primitive fix:quotient
245 :noname ( fixnum fixnum -- fixnum' )
246 drop swap drop mod fixnum-type
247 ; 2 make-fa-primitive fix:remainder
249 :noname ( fixnum -- fixnum+1 )
251 ; 1 make-fa-primitive fix:1+
253 :noname ( fixnum -- fixnum-1 )
255 ; 1 make-fa-primitive fix:-1+
257 :noname ( fixnum -- -fixnum )
259 ; 1 make-fa-primitive fix:neg
261 :noname ( fixnum -- -fixnum )
263 ; 1 make-fa-primitive fix:abs
265 :noname ( fixnum fixnum -- fixnum' )
266 drop swap drop gcd fixnum-type
267 ; 2 make-fa-primitive fix:gcd
271 :noname ( flonum flonum -- bool )
273 ; 2 make-fa-primitive flo:=
275 :noname ( flonum flonum -- bool )
276 drop swap drop f< boolean-type
277 ; 2 make-fa-primitive flo:<
279 :noname ( flonum flonum -- bool )
280 drop swap drop f> boolean-type
281 ; 2 make-fa-primitive flo:>
283 :noname ( flonum flonum -- bool )
284 drop swap drop f<= boolean-type
285 ; 2 make-fa-primitive flo:<=
287 :noname ( flonum flonum -- bool )
288 drop swap drop f>= boolean-type
289 ; 2 make-fa-primitive flo:>=
291 :noname ( flonum -- bool )
292 drop 0.0 = boolean-type
293 ; 1 make-fa-primitive flo:zero?
295 :noname ( flonum -- bool )
296 drop 0.0 f> boolean-type
297 ; 1 make-fa-primitive flo:positive?
299 :noname ( flonum -- bool )
300 drop 0.0 f< boolean-type
301 ; 1 make-fa-primitive flo:negative?
304 :noname ( flonum1 flonum2 -- flonum1+flonum2 )
305 drop swap drop f+ flonum-type
306 ; 2 make-fa-primitive flo:+
308 :noname ( flonum1 flonum2 -- flonum1-flonum2 )
309 drop swap drop f- flonum-type
310 ; 2 make-fa-primitive flo:-
312 :noname ( flonum1 flonum2 -- flonum1*flonum2 )
313 drop swap drop f* flonum-type
314 ; 2 make-fa-primitive flo:*
316 :noname ( flonum1 flonum2 -- flonum1/flonum2 )
317 drop swap drop f/ flonum-type
318 ; 2 make-fa-primitive flo:/
320 :noname ( flonum1 flonum2 -- flonum1/flonum2 )
321 drop swap drop f/ flonum-type
322 ; 2 make-fa-primitive flo:/
325 :noname ( flonum -- bool )
327 fnan? swap finf? or invert
328 ; 1 make-fa-primitive flo:finite?
331 :noname ( flonum -- flonum )
333 ; 1 make-fa-primitive flo:neg
335 :noname ( flonum -- flonum )
337 ; 1 make-fa-primitive flo:abs
339 :noname ( flonum -- flonum )
341 ; 1 make-fa-primitive flo:exp
343 :noname ( flonum -- flonum )
345 ; 1 make-fa-primitive flo:log
347 :noname ( flonum -- flonum )
349 ; 1 make-fa-primitive flo:sin
351 :noname ( flonum -- flonum )
353 ; 1 make-fa-primitive flo:cos
355 :noname ( flonum -- flonum )
357 ; 1 make-fa-primitive flo:tan
359 :noname ( flonum -- flonum )
361 ; 1 make-fa-primitive flo:asin
363 :noname ( flonum -- flonum )
365 ; 1 make-fa-primitive flo:acos
367 :noname ( flonum -- flonum )
369 ; 1 make-fa-primitive flo:atan
371 :noname ( flonum -- flonum )
373 ; 1 make-fa-primitive flo:sqrt
375 :noname ( flonum flonum -- flonum )
376 drop swap drop f^ flonum-type
377 ; 2 make-fa-primitive flo:expt
379 :noname ( flonum -- flonum )
381 ; 1 make-fa-primitive flo:floor
383 :noname ( flonum -- flonum )
385 ; 1 make-fa-primitive flo:ceiling
387 :noname ( flonum -- flonum )
389 ; 1 make-fa-primitive flo:truncate
391 :noname ( flonum -- flonum )
393 ; 1 make-fa-primitive flo:round
395 :noname ( flonum -- flonum )
396 drop floor f->i fixnum-type
397 ; 1 make-fa-primitive flo:floor->exact
399 :noname ( flonum -- flonum )
400 drop ceiling f->i fixnum-type
401 ; 1 make-fa-primitive flo:ceiling->exact
403 :noname ( flonum -- flonum )
404 drop truncate f->i fixnum-type
405 ; 1 make-fa-primitive flo:truncate->exact
407 :noname ( flonum -- flonum )
408 drop f->i fixnum-type
409 ; 1 make-fa-primitive flo:round->exact
411 :noname ( flonum flonum -- flonum )
412 drop swap drop f/ fatan flonum-type
413 ; 2 make-fa-primitive flo:atan2
417 ' make-rational 2 make-fa-primitive make-rational
419 :noname ( ratnum -- fixnum )
421 ; 1 make-fa-primitive rat:numerator
423 :noname ( ratnum -- fixnum )
425 ; 1 make-fa-primitive rat:denominator
429 :noname ( fixnum -- flonum )
430 drop i->f flonum-type
431 ; 1 make-fa-primitive fixnum->flonum
435 \ ==== Pairs and Lists ==== {{{
437 :noname ( arg1 arg2 -- pair )
439 ; 2 make-fa-primitive cons
441 :noname ( pair-obj -- obj )
443 ; pair-type 1 make-fa-type-primitive car
445 :noname ( args -- obj )
447 ; pair-type 1 make-fa-type-primitive cdr
449 :noname ( pair obj -- ok )
450 2swap pair-type ensure-arg-type
455 ; 2 make-fa-primitive set-car!
457 :noname ( pair obj -- ok )
458 2swap pair-type ensure-arg-type
463 ; 2 make-fa-primitive set-cdr!
467 \ ==== Polymorphic equality testing ==== {{{
469 :noname ( arg1 arg2 -- bool )
471 ; 2 make-fa-primitive eq?
475 \ ==== Input/Output ==== {{{
478 console-i/o-port obj@
479 ; 0 make-fa-primitive console-i/o-port
482 current-input-port obj@
483 ; 0 make-fa-primitive current-input-port
485 :noname ( args -- charobj )
487 2drop current-input-port obj@
489 car port-type ensure-arg-type
493 ; make-primitive read-char
495 :noname ( args -- charobj )
497 2drop current-input-port obj@
499 car port-type ensure-arg-type
503 ; make-primitive peek-char
505 :noname ( args -- stringobj )
507 2drop current-input-port obj@
509 car port-type ensure-arg-type
513 ; make-primitive read-line
515 : charlist>cstr ( charlist addr -- n )
517 dup 2swap ( origaddr addr charlist )
523 drop ( origaddr addr charlist char )
524 -rot 2swap ( origaddr charlist addr char )
526 1+ -rot ( origaddr nextaddr charlist )
529 2drop ( origaddr finaladdr )
533 :noname ( args -- finalResult )
537 ; string-type 1 make-fa-type-primitive load
539 :noname ( args -- obj )
541 ; 0 make-fa-primitive read
545 :noname ( obj -- none )
547 ; 1 make-fa-primitive write
549 : displaypair ( pairobj -- )
553 nil? if 2drop exit then
554 pair-type istype? if space recurse exit then
558 : displaychar ( charobj -- )
561 : (displaystring) ( charlist -- )
570 : displaystring ( stringobj -- )
571 drop pair-type (displaystring)
575 pair-type istype? if ." (" displaypair ." )" exit then
576 character-type istype? if displaychar exit then
577 string-type istype? if displaystring exit then
582 :noname ( stringobj -- none )
584 ; string-type 1 make-fa-type-primitive display-string
586 :noname ( charobj -- none )
588 ; character-type 1 make-fa-type-primitive display-character
590 :noname ( obj -- none )
592 ; 1 make-fa-primitive display
594 :noname ( args -- none )
596 ; 0 make-fa-primitive newline
600 \ ==== Evaluation ==== {{{
602 :noname ( args -- result )
605 nil? false = if car then ( proc argvals )
608 ; make-primitive apply
610 :noname ( proc -- result )
613 ( Note that we get to this point either when
614 make-continuation is originally called or when
615 restore-continuation is called. Since we don't
616 want to call proc again following a restore,
617 we use the boolean values placed on the parameter
618 stack by make-continuation and restore-continuation
619 to detect which call got us here and act accordingly. )
628 ; 1 make-fa-primitive call-with-current-continuation
632 \ ==== Miscellaneous ==== {{{
634 ( Produce a recoverable exception. )
635 :noname ( args -- result )
643 2dup car space display
656 recoverable-exception throw
657 ; make-primitive error
659 ( Generate a temporary unique symbol. Used in the creation of hygienic macros. )
660 :noname ( args -- result )
661 [char] _ character-type nil cons
663 ; 0 make-fa-primitive gensym
665 ( Generate the NONE object indicating an unspecified return value. )
666 :noname ( args -- result )
668 ; 0 make-fa-primitive none