No matching definitions.

tur/r7rs/prelude

stdlib/r7rs/prelude.tur

the R7RS dialect's prelude: the core procedures.

Auto-loaded, LAST in the stdlib autoload list, when the ENTRY file is #lang r7rs (LangTraits.prelude). Read as R7RS itself so its bodies get Scheme truthiness and the Scheme reader; written in Turmeric's own shapes (defn, [...] parameter vectors, if) because every Turmeric form passes through the Scheme lowering untouched, and a prelude that reads as plainly as the stdlib it adapts is easier to keep honest.

NAMES. Every procedure here is spelled r7rs-<name>, never <name>: a top-level redefinition of an auto-loaded stdlib name (car, list, length, ...) is an error, and list.tur owns those on its carrier list. scheme_lower.c's rename table maps the Scheme spelling to the one here at every unquoted occurrence in a #lang r7rs file, so a Scheme program says (car l) and calls r7rs-car. A procedure added here is added to that table in the same change, or Scheme code cannot reach it.

REPRESENTATION (r7rs-lang-plan D3/D4, R3). Every Scheme type is an ordinary Turmeric type, and its predicate is is? against that type:

pair          R7rsPair, a heap struct of two `any` fields (`a`/`d`: the
              names `car`/`cdr` would meet the stdlib's `car` in `.field`
              method lookup); mutable through `(set! (.a p) v)`, which is
              the region-noted field store.
empty list    R7rsNull, one process-wide value (r7rs-null-value__).
char          R7rsChar, an opaque over the Unicode scalar value -- disjoint
              from int, which is what `char?` vs `integer?` needs.
string        Turmeric's cstr.  R7RS strings are mutable and these are
              not: `string-set!`/`string-fill!` are the one R7RS surface
              this stage declines, and says so rather than aliasing.
vector        (Vec any) -- `#(...)` reads as the same F_VEC `[...]` does.
bytevector    R7rsBytevector over a (Vec int) of 0..255.
eof-object    R7rsEof, one value.
symbol        Sym (stdlib/sym.tur); `string->symbol` interns at runtime
              through stdlib/sym-dynamic.tur, loaded below.
values        R7rsValues over a Scheme list; `(values x)` is x itself.

quote builds these at runtime through r7rs-list / r7rs-cons / r7rs-vector / r7rs-char__ (scheme_lower.c's datum walker); the static .rodata table D4 wants is deferred with the literal-mutation question.

ADAPTORS, NOT REIMPLEMENTATIONS, on the Saffron prelude's rule: each of these forwards to a typed stdlib operation where one exists. The numeric surface is R5's, ports are R8's, error/raise are R6's.

Since: r7rs-lang-plan R2, R3

defstruct

R7rsPair

(defstruct R7rsPair :heap [a :any d :any])

---- the types --------------------------------------------------------

defstruct

R7rsNull

(defstruct R7rsNull [tag :int])
defstruct

R7rsEof

(defstruct R7rsEof [tag :int])
defopaque

R7rsChar

(defopaque R7rsChar :int)
defstruct

R7rsBytevector

(defstruct R7rsBytevector :heap [bytes :(Vec int)])
defstruct

R7rsValues

(defstruct R7rsValues [items :any])
defstruct

R7rsError

(defstruct R7rsError :heap [message :any irritants :any kind :int])

the R7RS error object (R6): a message and a list of irritants. Declared here, ahead of display, because a typed parameter's forward declaration needs the struct to exist.

defn

r7rs-error-object?

(r7rs-error-object? [x] :bool)
defn

r7rs-error-object-message

(r7rs-error-object-message [e :R7rsError] :any)
defn

r7rs-error-object-irritants

(r7rs-error-object-irritants [e :R7rsError] :any)
defn

r7rs-error-kind__

(r7rs-error-kind__ [e :R7rsError] :int)

R7: 0 for error/raise, 1 a file error, 2 a read error; file-error? and read-error? answer from it.

defn

r7rs-fail-any__

(r7rs-fail-any__ [msg :cstr] :any)

internal: an "it is an error" condition, in a position that needs an any. It raises an error object with this message, which a program can guard (r7rs-type-errors-are-uncatchable-panics), through r7rs-raise-type__ so that its callers stay out of CPS; the panic is only reached with no hook installed. (A bare (panic ...) in the value position of an any-returning function is emitted as a void return by the compiled back end, hence the helper.) -bool, -int and -cstr are its twins for other positions.

defn

r7rs-signal__

(r7rs-signal__ [msg :cstr] :any)

internal: R10 -- an error a program can guard: raise an error object with this message. For "it is an error" conditions the procedure detects, where r7rs-fail-any__'s panic would end the program.

defn

r7rs-fail-bool__

(r7rs-fail-bool__ [msg :cstr] :bool)
defn

r7rs-type-name__

(r7rs-type-name__ [x])

internal: type-of as an any, so two names compare through the dynamic = (no static cstr equality is autoloaded).

defn

r7rs-null?

(r7rs-null? [p] :bool)

#t for the empty list. The predicates are FUNCTIONS, and the rest of this file tests through them rather than with an inline (is? x T): the inline test narrows x to T in its then-branch, and a narrowed heap value is unique -- a second use of it is TUR-E0201 "cannot copy unique value". A call leaves x an any, and each later use crosses the seam on its own.

defn

r7rs-pair?

(r7rs-pair? [p] :bool)

#t for a pair.

defn

r7rs-cons

(r7rs-cons [a d] :any)

a fresh pair; the cdr may be anything (an improper list). Returns any, as does every procedure that hands out a pair: a statically typed heap struct is a unique value in Turmeric, and a Scheme variable holding one must be usable any number of times.

defn

r7rs-car

(r7rs-car [p :R7rsPair] :any)

the fields. An any argument crosses the seam with one tag check; (car '()) is the checked-cast panic naming both types.

defn

r7rs-cdr

(r7rs-cdr [p :R7rsPair] :any)
defn

r7rs-set-car!

(r7rs-set-car! [p :R7rsPair v] :nil)

the mutators. (set! (.a p) v) is the region-noted field store (CLAUDE.md, Region Store Hooks), so a value built inside a with-region bracket and stored here blocks the rewind.

defn

r7rs-set-cdr!

(r7rs-set-cdr! [p :R7rsPair v] :nil)
defstruct

R7rsBox

(defstruct R7rsBox :heap [v :any])

internal: the heap cell of a set! variable a lambda captures (r7rs-lang-plan R10). A compiled closure copies the variables it captures, so without the cell (set! sum ...) inside a do loop or a for-each lambda updated the closure's copy and the enclosing procedure still read the old value. scheme_lower.c's assignment conversion binds such a variable to one of these; reads and set!s go through it.

defn

r7rs-box__

(r7rs-box__ [x] :any)
defn

r7rs-unbox__

(r7rs-unbox__ [b :R7rsBox] :any)
defn

r7rs-box-set!__

(r7rs-box-set!__ [b :R7rsBox x] :nil)
defn

r7rs-caar

(r7rs-caar [p] :any)
defn

r7rs-cadr

(r7rs-cadr [p] :any)
defn

r7rs-cdar

(r7rs-cdar [p] :any)
defn

r7rs-cddr

(r7rs-cddr [p] :any)
defn

r7rs-caddr

(r7rs-caddr [p] :any)
defn

r7rs-snoc__

(r7rs-snoc__ [last x] :any)

internal: the (Cons any) cells a variadic any rest parameter arrives packed in, as a Scheme list. T8: the list builders that call no user procedure append at a tail pointer (r7rs-snoc__), so each is a self tail call the compiler lowers to a loop (map, which calls one, reverses instead -- see r7rs-map1__). The natural (R7rsPair x (self ...)) recursion used one C frame per element and overflowed the stack on a list of about a million, at every optimization level and on both back ends. Each builder makes its first pair itself, so no scratch head is allocated (a pair is never freed).

defn

r7rs-chain->list-go__

(r7rs-chain->list-go__ [c :(Cons any) last] :any)
defn

r7rs-chain->list__

(r7rs-chain->list__ [c :(Cons any)] :any)
defn

r7rs-list

(r7rs-list [& xs :any] :any)

(list e ...).

defn

r7rs-list-go__

(r7rs-list-go__ [slow fast] :bool)

#t for a proper list (terminates on a cycle: two cursors).

defn

r7rs-list?

(r7rs-list? [p] :bool)
defn

r7rs-length-go__

(r7rs-length-go__ [p n :int] :int)

the number of elements of a proper list.

defn

r7rs-length

(r7rs-length [p] :int)
defn

r7rs-list-tail

(r7rs-list-tail [p k :int] :any)

the list after its first k elements.

defn

r7rs-list-ref

(r7rs-list-ref [p k :int] :any)

the k-th element, zero-based.

defn

r7rs-append-go__

(r7rs-append-go__ [p b last] :any)

two lists, the first copied (quasiquote's splice).

defn

r7rs-append2__

(r7rs-append2__ [a b] :any)
defn

r7rs-append-all__

(r7rs-append-all__ [c :(Cons any)] :any)

the lists joined, each but the last copied (R7RS 6.4): (append) is (), (append x) is x, and the last may be any object.

defn

r7rs-append

(r7rs-append [& ls :any] :any)
defn

r7rs-reverse-go__

(r7rs-reverse-go__ [p acc] :any)

a reversed copy.

defn

r7rs-reverse

(r7rs-reverse [p] :any)
defn

r7rs-list-copy-go__

(r7rs-list-copy-go__ [p last] :any)

a shallow copy.

defn

r7rs-list-copy

(r7rs-list-copy [p] :any)
defn

r7rs-map1-go__

(r7rs-map1-go__ [f l acc] :any)

apply f to each element, into a fresh list (one list). map builds in reverse and reverses at the end, NOT at a tail pointer: f can capture a continuation, and re-entering it must not change a list map already returned (r7rs-continuations pins this). The accumulator a re-entry resumes from is shared, never mutated, and the final reverse is a fresh list each time.

defn

r7rs-map1__

(r7rs-map1__ [f l] :any)
defn

r7rs-for-each1__

(r7rs-for-each1__ [f l] :nil)

apply f to each element, for effect.

defn

r7rs-any-null__

(r7rs-any-null__ [ls] :bool)

R7: true when any list in ls is exhausted (the multi-list map/for-each stop at the shortest, R7RS 6.10).

defn

r7rs-cars-go__

(r7rs-cars-go__ [ls last] :any)
defn

r7rs-cars__

(r7rs-cars__ [ls] :any)
defn

r7rs-cdrs-go__

(r7rs-cdrs-go__ [ls last] :any)
defn

r7rs-cdrs__

(r7rs-cdrs__ [ls] :any)
defn

r7rs-head-of__

(r7rs-head-of__ [ls k :int] :any)

internal: the car of the k-th (0-based) list of ls.

defn

r7rs-mapn-go__

(r7rs-mapn-go__ [f ls n :int acc] :any)

The many-list map and for-each call f on the heads of the lists INSIDE the loop body (T8). Calling it through r7rs-apply-list__, or any helper, made the step a call into a separate CPS procedure that resumed the loop from inside its own frame, so every element nested a C frame and a million-element (map + a b) overflowed at -O2. n is the number of lists: 1 (string-map and vector-map come here with one) to 8, the dynamic call's argument limit (TUR_FAT_SHIM_MAX_ARITY; apply's is the same, and past it apply packs the rest as a list). Only the CALL of f is spelled per arity; the heads past the fourth come through r7rs-head-of__, an argument, not a resume point (r7rs-map-for-each-at-most-four-sequences).

defn

r7rs-mapn__

(r7rs-mapn__ [f ls] :any)
defn

r7rs-for-eachn-go__

(r7rs-for-eachn-go__ [f ls n :int] :bool)
defn

r7rs-for-eachn__

(r7rs-for-eachn__ [f ls] :nil)
defn

r7rs-map

(r7rs-map [f l & more :any] :any)

(map f list1 list2 ...): R7: any number of lists, stopping at the shortest; the one-list case keeps its direct call.

defn

r7rs-for-each

(r7rs-for-each [f l & more :any] :nil)

(for-each f list1 list2 ...), for effect.

defn

r7rs-same-ref__

(r7rs-same-ref__ [a b] :bool)

internal: identity of two heap values (a pair, a vector, a bytevector, a record) by their carrier word. Inline C on the compiled path, a native under the interpreter; typed helpers per type would each need the seam's pointer cast, and this asks one question of the tagged words directly.

defn

r7rs-same-pair__

(r7rs-same-pair__ [a b] :bool)
defn

r7rs-char-code__

(r7rs-char-code__ [c :R7rsChar] :int)

internal, typed: a char's scalar value.

defn

r7rs-eqv?

(r7rs-eqv? [a b] :bool)

R7RS 6.1: identity on booleans, numbers, characters, symbols and the empty list; pointer identity on pairs, vectors and records; two values of different runtime types are never eqv.

defn

r7rs-eqv-by-value?__

(r7rs-eqv-by-value?__ [a] :bool)

internal: the types eqv? compares by value.

defn

r7rs-eq?

(r7rs-eq? [a b] :bool)

same as eqv? here (chars and ints are immediate, and a bignum is compared by value, which R7RS allows of eq? on numbers).

defn

r7rs-not

(r7rs-not [x] :bool)

#t only for #f (R7RS 6.3).

defn

r7rs-memv

(r7rs-memv [x l])

---- membership and association ----------------------------------------

defn

r7rs-memq

(r7rs-memq [x l])
defn

r7rs-member-by__

(r7rs-member-by__ [x l eq] :any)
defn

r7rs-member

(r7rs-member [x l & cmp :any] :any)

R7: an optional third argument is the equivalence.

defn

r7rs-assv

(r7rs-assv [x l])
defn

r7rs-assq

(r7rs-assq [x l])
defn

r7rs-assoc-by__

(r7rs-assoc-by__ [x l eq] :any)
defn

r7rs-assoc

(r7rs-assoc [x l & cmp :any] :any)

R7: an optional third argument is the equivalence.

defn

r7rs-boolean?

(r7rs-boolean? [x] :bool)

---- type predicates ---------------------------------------------------

defn

r7rs-string?

(r7rs-string? [x] :bool)
defn

r7rs-symbol?

(r7rs-symbol? [x] :bool)
defn

r7rs-procedure?

(r7rs-procedure? [x] :bool)
defn

r7rs-char?

(r7rs-char? [x] :bool)
defn

r7rs-vector?

(r7rs-vector? [x] :bool)
defn

r7rs-bytevector?

(r7rs-bytevector? [x] :bool)
defn

r7rs-eof-object?

(r7rs-eof-object? [x] :bool)
defn

r7rs-values?__

(r7rs-values?__ [x] :bool)
defn

r7rs-eof-object

(r7rs-eof-object)
defn

r7rs-fixnum?__

(r7rs-fixnum?__ [x] :bool)

---- numbers (R5: the tower over int64 and double) --------------------

R7RS 6.2 over three representations: an exact integer is Turmeric's int64 when it fits and an R7rsBig when it does not (T1: exact integers are unbounded), and an inexact real is a double. There are no exact rationals yet (T2), so (/ 7 2) is the inexact 3.5 (not 7/2). The int64 path stays the fast one: +, -, * check for overflow and only then compute on bignums, and a bignum result that fits is an int again, so an R7rsBig is never a number int64 could hold. Exactness is the representation: exact? is an int or a bignum, inexact? a float, and the arithmetic on mixed operands is inexact. No complex numbers: (sqrt -4) is +nan.0.

The lowering routes every + - * / = < > <= >= in call position through the binary helpers here (r7rs-add2__ ...), folding n-ary uses and handling (+), (- x), (/ x); the variadic r7rs-+ ... are what a bare + in value position names, so (apply + xs) and (map + a b) work. The prelude itself is exempt from that rewrite (it is where the raw operators are allowed to appear), so the helpers below may use them. r7rs-fixnum?__ / r7rs-flonum?__ -- the representation tests; integer? is the R7RS predicate (7.0 is an integer) and is not the one to use to pick a printer.

defn

r7rs-flonum?__

(r7rs-flonum?__ [x] :bool)
defn

r7rs-float-nan?__

(r7rs-float-nan?__ [x :float] :bool)
defn

r7rs-float-infinite?__

(r7rs-float-infinite?__ [x :float] :bool)
defn

r7rs-float-integral?__

(r7rs-float-integral?__ [x :float] :bool)
defn

r7rs-int->float__

(r7rs-int->float__ [x :int] :float)
defn

r7rs-float->int__

(r7rs-float->int__ [x :float] :int)

an integral double as an int64, for an argument that must be one (an index, a count, a character code). T0: a double outside int64 is an error, where the C conversion saturated to a silent wrong answer. exact itself goes through r7rs-exact, which makes a bignum.

defstruct

R7rsBig

(defstruct R7rsBig :heap [digits :cstr])

---- bignums (T1) ---------------------------------------------------------

An R7rsBig holds the canonical decimal spelling of an exact integer outside int64; the arithmetic is the C of stdlib/r7rs/bignum.tur (the interpreter's natives run the same file). r7rs-big-norm__ is the one constructor, so a value that fits is always an int.

defn

r7rs-big?

(r7rs-big? [x] :bool)
defn

r7rs-big-digits__

(r7rs-big-digits__ [b :R7rsBig] :cstr)
defn

r7rs-big-norm__

(r7rs-big-norm__ [s :cstr] :any)
defn

r7rs-big__

(r7rs-big__ [s :cstr] :any)

the reader's constructor: a literal outside int64 reads as (r7rs-big__ "<digits>"), as a char reads as (r7rs-char__ n).

defn

r7rs-exint?

(r7rs-exint? [x] :bool)

an exact integer: an int or a bignum.

defn

r7rs-any-big?__

(r7rs-any-big?__ [a b] :bool)
defn

r7rs-any-exotic?__

(r7rs-any-exotic?__ [a b] :bool)

either operand is a bignum or a ratio: off the int64/double fast paths.

defn

r7rs-dec__

(r7rs-dec__ [x] :cstr)

an exact integer's decimal spelling, for the bignum core.

defn

r7rs-dec-done__

(r7rs-dec-done__ [x s :cstr] :nil)

T8: release what r7rs-dec__ made: an int's spelling is fresh, a bignum's is its own digits.

defn

r7rs-big2__

(r7rs-big2__ [op :int a b] :any)

one bignum-core operation (the R7BN_* codes of bignum.tur) on two exact integers, normalized. The operand spellings are released, and so is the result's when it fits an int (a bignum keeps it).

defn

r7rs-big-cmp-of__

(r7rs-big-cmp-of__ [a b] :int)

two exact integers compared by the core.

defn

r7rs-big-cmp-float-of__

(r7rs-big-cmp-float-of__ [a d :float] :int)
defn

r7rs-big-neg?__

(r7rs-big-neg?__ [x] :bool)
defstruct

R7rsRatio

(defstruct R7rsRatio :heap [num :any den :any])

---- exact rationals (T2) ---------------------------------------------------

An R7rsRatio is an exact non-integer: numerator and denominator are exact integers (an int or a bignum), in lowest terms, the denominator greater than 1 and the sign on the numerator. r7rs-make-ratio__ is the one constructor, so a ratio is never a number an integer could be, and (/ 6 3) is the integer 2. Tests go through r7rs-ratio?, not a bare is?, which would narrow the value to the (unique) heap struct.

defn

r7rs-ratio?

(r7rs-ratio? [x] :bool)
defn

r7rs-ratio-num__

(r7rs-ratio-num__ [r :R7rsRatio] :any)
defn

r7rs-ratio-den__

(r7rs-ratio-den__ [r :R7rsRatio] :any)
defn

r7rs-exrat?

(r7rs-exrat? [x] :bool)

an exact rational: an exact integer or a ratio.

defn

r7rs-num-of__

(r7rs-num-of__ [x] :any)

an exact rational's parts (an integer is itself over 1).

defn

r7rs-den-of__

(r7rs-den-of__ [x] :any)
defn

r7rs-make-ratio__

(r7rs-make-ratio__ [n d] :any)

n/d in lowest terms; n and d exact integers, d nonzero. An integer when d divides n.

defn

r7rs-ratio-of-str__

(r7rs-ratio-of-str__ [s :cstr] :any)

the value of an "n/d" (or "n") spelling, as the number parser and the exact value of a double produce it.

defn

r7rs-ratio__

(r7rs-ratio__ [s :cstr] :any)

the reader's constructor: an exact non-integer literal reads as (r7rs-ratio__ "<n>/<d>"), as a char reads as (r7rs-char__ n).

defn

r7rs-exint-cmp__

(r7rs-exint-cmp__ [a b] :int)

two exact integers: -1, 0 or 1.

defn

r7rs-rat-arith__

(r7rs-rat-arith__ [op :int a b] :any)

+ - * (op 0 1 2) on two exact rationals.

defn

r7rs-rat-cmp__

(r7rs-rat-cmp__ [a b] :int)

two exact rationals, exactly: -1, 0 or 1 (the denominators are positive, so cross-multiplying keeps the order).

defn

r7rs-cmp-rat-any__

(r7rs-cmp-rat-any__ [a b] :int)

a comparison with a ratio: against a double through the double's exact value; 2 when a double is a NaN.

defstruct

R7rsComplex

(defstruct R7rsComplex :heap [re :any im :any])

---- complex numbers (T6) ------------------------------------------------

An R7rsComplex is a non-real number: its real and imaginary parts are reals (an int, a bignum, a ratio or a double). r7rs-make-rect__ is the one constructor, so an exact-zero imaginary part is always the real itself (R7RS 6.2.6), and a complex number is exact or inexact as a whole: when either part is inexact, both are. An inexact one keeps a 0.0 imaginary part, so (real? 1.0+0.0i) is #f. Tests go through r7rs-cplx?, not a bare is? (the unique-narrowing reason r7rs-ratio? gives).

defn

r7rs-cplx?

(r7rs-cplx? [x] :bool)
defn

r7rs-cplx-re__

(r7rs-cplx-re__ [z :R7rsComplex] :any)
defn

r7rs-cplx-im__

(r7rs-cplx-im__ [z :R7rsComplex] :any)
defn

r7rs-any-cplx?__

(r7rs-any-cplx?__ [a b] :bool)
defn

r7rs-re-of__

(r7rs-re-of__ [x] :any)

any number's parts; a real's imaginary part is exact 0.

defn

r7rs-im-of__

(r7rs-im-of__ [x] :any)
defn

r7rs-exact-zero?__

(r7rs-exact-zero?__ [x] :bool)
defn

r7rs-make-rect__

(r7rs-make-rect__ [re im] :any)

re + im i, from two reals.

defn

r7rs-complex-of-str__

(r7rs-complex-of-str__ [s :cstr] :any)

the reader's constructor: a non-real literal reads as (r7rs-complex__ "<re> <im>"), each part a real's spelling.

defn

r7rs-complex__

(r7rs-complex__ [s :cstr] :any)
defn

r7rs-ratio-to-float__

(r7rs-ratio-to-float__ [n d] :float)
defn

r7rs-to-float__

(r7rs-to-float__ [x] :float)
defn

r7rs-real?

(r7rs-real? [x] :bool)
defn

r7rs-number?

(r7rs-number? [x] :bool)
defn

r7rs-complex?

(r7rs-complex? [x] :bool)
defn

r7rs-real-finite?__

(r7rs-real-finite?__ [x] :bool)

T6: a complex number is finite when both parts are, infinite or a NaN when either is.

defn

r7rs-finite?

(r7rs-finite? [x] :bool)
defn

r7rs-real-infinite?__

(r7rs-real-infinite?__ [x] :bool)
defn

r7rs-infinite?

(r7rs-infinite? [x] :bool)
defn

r7rs-real-nan?__

(r7rs-real-nan?__ [x] :bool)
defn

r7rs-nan?

(r7rs-nan? [x] :bool)
defn

r7rs-rational?

(r7rs-rational? [x] :bool)
defn

r7rs-integer?

(r7rs-integer? [x] :bool)
defn

r7rs-exact?

(r7rs-exact? [x] :bool)

A complex number is exact or inexact as a whole (r7rs-make-rect__), so its real part answers for it.

defn

r7rs-inexact?

(r7rs-inexact? [x] :bool)
defn

r7rs-exact-integer?

(r7rs-exact-integer? [x] :bool)
defn

r7rs-exact-rational?

(r7rs-exact-rational? [x] :bool)
defn

r7rs-both-int?__

(r7rs-both-int?__ [a b] :bool)

---- exact arithmetic: int64, then bignums (T1) --------------------------

defn

r7rs-big-arith__

(r7rs-big-arith__ [op :int a b] :any)

+ - * (op 0 1 2) with a bignum or ratio operand: inexact when the other one is, exact rationals (T2) when either is a ratio, else the bignum core.

defn

r7rs-cplx-arith__

(r7rs-cplx-arith__ [op :int a b] :any)

T6: + - * on complex numbers, part by part through the real operators.

defn

r7rs-real-arith__

(r7rs-real-arith__ [op :int a b] :any)
defn

r7rs-intflo?__

(r7rs-intflo?__ [x] :bool)

the binary operators the lowering emits. Two ints take the int64 path unless it overflows (T1: then the bignum core, where D8 had a panic); a bignum operand goes to the core; two ints or doubles take the dynamic operator, which promotes a mixed pair to inexact; and anything else is not a number, the raised error ((+ 'a 1)) where the dynamic operator panicked.

defn

r7rs-intflos?__

(r7rs-intflos?__ [a b] :bool)
defn

r7rs-add2__

(r7rs-add2__ [a b] :any)
defn

r7rs-sub2__

(r7rs-sub2__ [a b] :any)
defn

r7rs-mul2__

(r7rs-mul2__ [a b] :any)
defn

r7rs-div-exact__

(r7rs-div-exact__ [a b] :any)

T2: exact on exact operands, a ratio when the quotient is not an integer ((/ 7 2) is 7/2, where it was 3.5), and division by exact zero is an error. Two ints that divide stay on int64 (-1 aside: INT64_MIN / -1 leaves it).

defn

r7rs-div2__

(r7rs-div2__ [a b] :any)
defn

r7rs-cplx-div__

(r7rs-cplx-div__ [a b] :any)

T6: (a+bi)/(c+di) = ((ac+bd) + (bc-ad)i) / (c^2+d^2).

defn

r7rs-cmp-int-float__

(r7rs-cmp-int-float__ [i :int d :float] :int)

R10: an exact integer and an inexact real compare EXACTLY (R7RS 6.2.6 asks comparisons to be transitive): (= 9007199254740992.0 9007199254740993) is #f, where converting the integer to a double made the two equal. r7rs-cmp-int-float__ answers -1, 0 or 1 for i against d, and 2 when d is a NaN (every comparison false).

defn

r7rs-mixed?__

(r7rs-mixed?__ [a b] :bool)
defn

r7rs-cmp-mixed__

(r7rs-cmp-mixed__ [a b] :int)
defn

r7rs-cmp-big__

(r7rs-cmp-big__ [a b] :int)

against a double through the double's exact value -- so (= (- (expt 2 1000) 1) (inexact (expt 2 1000))) is #f. -1, 0 or 1, and 2 when a double is a NaN.

defn

r7rs-cmp-slow__

(r7rs-cmp-slow__ [a b] :int)
defn

r7rs-cmp-cplx__

(r7rs-cmp-cplx__ [a b] :int)

T6: complex numbers are equal part by part and otherwise unordered (2, as a NaN is): < on a non-real is #f.

defn

r7rs-cmp-real__

(r7rs-cmp-real__ [a b] :int)
defn

r7rs-slow?__

(r7rs-slow?__ [a b] :bool)
defn

r7rs-cmp-error__

(r7rs-cmp-error__ [who :cstr a b] :bool)

The comparisons: two ints first, then the exact slow path, then two doubles; anything else is not a number, raised ((< 'a 1)).

defn

r7rs-numeq2__

(r7rs-numeq2__ [a b] :bool)
defn

r7rs-lt2__

(r7rs-lt2__ [a b] :bool)
defn

r7rs-gt2__

(r7rs-gt2__ [a b] :bool)
defn

r7rs-le2__

(r7rs-le2__ [a b] :bool)
defn

r7rs-ge2__

(r7rs-ge2__ [a b] :bool)
defn

r7rs-fold-num__

(r7rs-fold-num__ [f l acc])

The variadic procedures a bare operator names in value position.

defn

r7rs-args__

(r7rs-args__ [xs :(Cons any)] :any)
defn

r7rs-+

(r7rs-+ [& xs :any])
defn

r7rs-*

(r7rs-* [& xs :any])
defn

r7rs--

(r7rs-- [x & xs :any])
defn

r7rs-/

(r7rs-/ [x & xs :any])
defn

r7rs-chain-cmp__

(r7rs-chain-cmp__ [f x l] :bool)
defn

r7rs-=

(r7rs-= [x & xs :any] :bool)
defn

r7rs-<

(r7rs-< [x & xs :any] :bool)
defn

r7rs->

(r7rs-> [x & xs :any] :bool)
defn

r7rs-<=

(r7rs-<= [x & xs :any] :bool)
defn

r7rs->=

(r7rs->= [x & xs :any] :bool)
defn

r7rs-zero?

(r7rs-zero? [x] :bool)

---- predicates, min/max, abs ------------------------------------------- A bignum or a ratio is never zero (a zero is an int); a bignum's sign is its spelling's, a ratio's its numerator's.

defn

r7rs-positive?

(r7rs-positive? [x] :bool)
defn

r7rs-negative?

(r7rs-negative? [x] :bool)
defn

r7rs-int-of__

(r7rs-int-of__ [x who :cstr] :int)

an integer argument that must fit int64 (an index, a count, a character code): a bignum there is the error who.

defn

r7rs-exint-of__

(r7rs-exint-of__ [x who :cstr] :any)

an integer argument as an exact integer (an int or a bignum); an inexact integer converts exactly, anything else (a ratio, T2) is the error who. Raised through r7rs-fail-any__, not raise: this is reachable from = (through the exact comparison of a ratio and a double), and a raise there makes every procedure that compares numbers effectful, which compiles it to CPS and costs the tail-call trampoline (tests/fixtures/r7rs-tail-calls).

defn

r7rs-fail-int__

(r7rs-fail-int__ [msg :cstr] :int)
defn

r7rs-even?

(r7rs-even? [x] :bool)

an inexact integer is tested as a double, so a large one (1e30, which is even) needs no int64 conversion.

defn

r7rs-odd?

(r7rs-odd? [x] :bool)
defn

r7rs-abs

(r7rs-abs [x])
defn

r7rs-min2__

(r7rs-min2__ [a b])

inexact contagion (R7RS 6.2.6): if any argument is inexact the result is inexact.

defn

r7rs-max2__

(r7rs-max2__ [a b])
defn

r7rs-any-inexact?__

(r7rs-any-inexact?__ [l] :bool)
defn

r7rs-contagion__

(r7rs-contagion__ [r l])
defn

r7rs-min

(r7rs-min [x & xs :any])
defn

r7rs-max

(r7rs-max [x & xs :any])
defn

r7rs-idiv-int__

(r7rs-idiv-int__ [op :int x :int y :int] :any)

quotient, remainder or modulo (the bignum core's codes 3, 4, 5) on two integers, exactly: int64 when both are ints (INT64_MIN / -1 is the one quotient that leaves int64, so -1 goes to the core), the bignum core otherwise.

defn

r7rs-idiv-arg__

(r7rs-idiv-arg__ [x who :cstr] :any)

T8: the message is built only on the failing path (it was built, and leaked, on every call).

defn

r7rs-idiv__

(r7rs-idiv__ [op :int a b who :cstr] :any)
defn

r7rs-quotient-i__

(r7rs-quotient-i__ [a b] :any)
defn

r7rs-remainder-i__

(r7rs-remainder-i__ [a b] :any)
defn

r7rs-modulo-i__

(r7rs-modulo-i__ [a b] :any)
defn

r7rs-floor-quotient-i__

(r7rs-floor-quotient-i__ [a b] :any)
defn

r7rs-floor-remainder-i__

(r7rs-floor-remainder-i__ [a b] :any)
defn

r7rs-truncate-quotient-i__

(r7rs-truncate-quotient-i__ [a b] :any)
defn

r7rs-truncate-remainder-i__

(r7rs-truncate-remainder-i__ [a b] :any)
defn

r7rs-idiv-result__

(r7rs-idiv-result__ [r a b] :any)

an inexact argument makes the result inexact (R7RS 6.2.6, (truncate/ -5.0 -2) is 2.0 and -1.0); the -i__ forms above compute on the exact integers.

defn

r7rs-quotient

(r7rs-quotient [a b] :any)
defn

r7rs-remainder

(r7rs-remainder [a b] :any)
defn

r7rs-modulo

(r7rs-modulo [a b] :any)
defn

r7rs-floor-quotient

(r7rs-floor-quotient [a b] :any)
defn

r7rs-floor-remainder

(r7rs-floor-remainder [a b] :any)
defn

r7rs-truncate-quotient

(r7rs-truncate-quotient [a b] :any)
defn

r7rs-truncate-remainder

(r7rs-truncate-remainder [a b] :any)
defn

r7rs-igcd__

(r7rs-igcd__ [a :int b :int] :int)

gcd and lcm on the bignum core (code 6); the answers are non-negative. T2: every ratio operation normalizes through gcd, so two ints (INT64_MIN aside, whose magnitude leaves int64) take Euclid's loop on int64.

defn

r7rs-gcd2__

(r7rs-gcd2__ [a b] :any)
defn

r7rs-gcd-go__

(r7rs-gcd-go__ [l acc] :any)
defn

r7rs-gcd

(r7rs-gcd [& xs :any] :any)
defn

r7rs-lcm2__

(r7rs-lcm2__ [a b] :any)
defn

r7rs-lcm-go__

(r7rs-lcm-go__ [l acc] :any)
defn

r7rs-lcm

(r7rs-lcm [& xs :any] :any)
defn

r7rs-rat-floor__

(r7rs-rat-floor__ [x] :any)

---- rounding and exactness ---------------------------------------------- T2: a ratio rounds exactly to an exact integer: floor is the floor quotient of its parts (the denominator is positive), round takes ties to even.

defn

r7rs-rat-round__

(r7rs-rat-round__ [x] :any)
defn

r7rs-floor

(r7rs-floor [x] :any)
defn

r7rs-ceiling

(r7rs-ceiling [x] :any)
defn

r7rs-truncate

(r7rs-truncate [x] :any)
defn

r7rs-round

(r7rs-round [x] :any)

to the nearest integer, ties to even (rint for a double).

defn

r7rs-exact

(r7rs-exact [x] :any)

a finite double's exact value: an int, a bignum at any size (T1), or the ratio it is (T2: (exact .5) is 1/2; a double is a dyadic fraction, so (exact .3) is 5404319552844595/18014398509481984).

defn

r7rs-exact-real__

(r7rs-exact-real__ [x] :any)
defn

r7rs-inexact

(r7rs-inexact [x] :any)
defn

r7rs-exact->inexact

(r7rs-exact->inexact [x])
defn

r7rs-inexact->exact

(r7rs-inexact->exact [x])
defn

r7rs-num-den__

(r7rs-num-den__ [x :float d :float] :any)

an exact integer is its own numerator over 1, and a ratio (T2) has its parts. R10: an inexact real is a dyadic fraction, so its lowest terms are found by doubling until it is integral -- (numerator 5.5) is 11.0 and (denominator 5.5) 2.0 -- with the answer inexact (R7RS 6.2.6).

defn

r7rs-num-den-of__

(r7rs-num-den-of__ [x] :any)
defn

r7rs-numerator

(r7rs-numerator [x] :any)
defn

r7rs-denominator

(r7rs-denominator [x] :any)
defn

r7rs-square

(r7rs-square [x])

---- powers, roots, transcendental --------------------------------------

defn

r7rs-isqrt__

(r7rs-isqrt__ [n] :any)

floor of the square root of a non-negative exact integer, exact (the bignum core's code 8; Newton's iteration).

defn

r7rs-exact-sqrt?__

(r7rs-exact-sqrt?__ [n] :bool)

exact when the argument is an exact perfect square (T2: or a ratio of two, (sqrt 4/9) is 2/3), else inexact. T6: a negative real has an imaginary root, exact when its negation's root is ((sqrt -4) is +2i), and a complex argument takes the principal root.

defn

r7rs-sqrt

(r7rs-sqrt [x] :any)
defn

r7rs-cf-re__

(r7rs-cf-re__ [z] :float)

---- complex transcendental (T6) -----------------------------------------

On doubles, part by part: r7rs-cf__ builds a+bi from two of them. A complex answer is inexact (R7RS 6.2.6 lets a transcendental function be).

defn

r7rs-cf-im__

(r7rs-cf-im__ [z] :float)
defn

r7rs-cf__

(r7rs-cf__ [a :float b :float] :any)
defn

r7rs-cosh__

(r7rs-cosh__ [x :float] :float)
defn

r7rs-sinh__

(r7rs-sinh__ [x :float] :float)
defn

r7rs-cplx-sqrt__

(r7rs-cplx-sqrt__ [a :float b :float] :any)

the principal root of a+bi: the real part is never negative, and the imaginary part takes b's sign (-0.0 counts as +, so (sqrt -1.0-0.0i) is +1.0i, as the conformance suite has it).

defn

r7rs-cplx-exp__

(r7rs-cplx-exp__ [z] :any)
defn

r7rs-cplx-log__

(r7rs-cplx-log__ [z] :any)

log|z| + i arg z, the principal branch; a negative real lands here too, with arg pi.

defn

r7rs-cplx-sin__

(r7rs-cplx-sin__ [z] :any)
defn

r7rs-cplx-cos__

(r7rs-cplx-cos__ [z] :any)
defn

r7rs-cplx-asin__

(r7rs-cplx-asin__ [z] :any)

asin z = -i log(iz + sqrt(1 - z^2)); acos z = pi/2 - asin z; atan z = (log(1 + iz) - log(1 - iz)) / 2i.

defn

r7rs-cplx-atan__

(r7rs-cplx-atan__ [z] :any)
defn

r7rs-int->string-radix__

(r7rs-int->string-radix__ [x :int radix :int] :cstr)

---- number <-> string ---------------------------------------------------

defn

r7rs-radix-of__

(r7rs-radix-of__ [xs :(Cons any) who :cstr] :int)
defn

r7rs-number->string

(r7rs-number->string [x & xs :any] :cstr)
defn

r7rs-cplx->string__

(r7rs-cplx->string__ [z radix :int] :cstr)

T6: <re><sign><im>i, the imaginary part signed ("+inf.0" and "-2" already are). As chibi writes it, an exact-zero real part is left out and an exact unit imaginary part is bare: +2i, 1-i, +i. An inexact zero real part stays, so 0.0+1.0i reads back inexact.

defn

r7rs-cplx-im-spelling__

(r7rs-cplx-im-spelling__ [im radix :int] :cstr)

the signed imaginary part and its i, fresh.

defn

r7rs-join-fresh__

(r7rs-join-fresh__ [a :cstr sep :cstr b :cstr] :cstr)

T8: a ++ sep ++ b, freeing the fresh a and b (sep is a literal).

defn

r7rs-exact-unit?__

(r7rs-exact-unit?__ [x v :int] :bool)
defn

r7rs-fail-cstr__

(r7rs-fail-cstr__ [msg :cstr] :cstr)
defn

r7rs-number-of__

(r7rs-number-of__ [s :cstr radix :int who :cstr] :any)

internal: T0 -- s read as a number in radix, through the one R7RS number parser (stdlib/r7rs/numsyntax.tur, the source reader's too): the number, #f when s is not number syntax, and an error a program can guard -- who and the reason -- when s IS a number the tower cannot hold. A long integer is a bignum (T1), 1/2 a ratio (T2) and 1+2i a complex number (T6). Never a different number.

defn

r7rs-number-syntax?__

(r7rs-number-syntax?__ [s :cstr] :bool)

internal: s is number syntax at all, refused or not (write bars such a symbol: '|1/2|).

defn

r7rs-string->number

(r7rs-string->number [s0 & xs :any])

#f when the string is not a number in the radix.

defn

r7rs-char__

(r7rs-char__ [c :int] :R7rsChar)

the reader's constructor: #\a reads as (r7rs-char__ 97).

defn

r7rs-char->integer

(r7rs-char->integer [c :R7rsChar] :int)
defn

r7rs-integer->char

(r7rs-integer->char [n :int] :R7rsChar)
defn

r7rs-char=2__

(r7rs-char=2__ [a :R7rsChar b :R7rsChar] :bool)
defn

r7rs-char<2__

(r7rs-char<2__ [a :R7rsChar b :R7rsChar] :bool)
defn

r7rs-char>2__

(r7rs-char>2__ [a :R7rsChar b :R7rsChar] :bool)
defn

r7rs-char<=2__

(r7rs-char<=2__ [a :R7rsChar b :R7rsChar] :bool)
defn

r7rs-char>=2__

(r7rs-char>=2__ [a :R7rsChar b :R7rsChar] :bool)
defn

r7rs-char=?

(r7rs-char=? [a b & xs :any] :bool)

The char comparisons take two or more arguments (R7: they were binary).

defn

r7rs-char<?

(r7rs-char<? [a b & xs :any] :bool)
defn

r7rs-char>?

(r7rs-char>? [a b & xs :any] :bool)
defn

r7rs-char<=?

(r7rs-char<=? [a b & xs :any] :bool)
defn

r7rs-char>=?

(r7rs-char>=? [a b & xs :any] :bool)
defn

r7rs-char-upcase

(r7rs-char-upcase [c :R7rsChar] :R7rsChar)

(scheme char): ASCII answers inline, everything else from the Unicode tables of stdlib/r7rs/unicode.tur (R10; generated, see tools/gen-r7rs-unicode.py).

defn

r7rs-char-downcase

(r7rs-char-downcase [c :R7rsChar] :R7rsChar)
defn

r7rs-char-alphabetic?

(r7rs-char-alphabetic? [c :R7rsChar] :bool)
defn

r7rs-char-numeric?

(r7rs-char-numeric? [c :R7rsChar] :bool)
defn

r7rs-char-whitespace?

(r7rs-char-whitespace? [c :R7rsChar] :bool)
defn

r7rs-blen__

(r7rs-blen__ [s :cstr] :int)

---- strings: the byte-level primitives (inline C with interpreter twins in interpreter_natives.c) ---------------------------------------------------

T3: these count and cut BYTES of a cstr. The prelude uses them on text it built itself (tokens, escapes, number spellings); a Scheme program's strings go through the character-level procedures of the T3 section below. r7rs-blen__ -- a cstr's length in bytes.

defn

r7rs-utf8-count__

(r7rs-utf8-count__ [s :cstr] :int)

T3: the number of characters in UTF-8 text.

defn

r7rs-utf8-at__

(r7rs-utf8-at__ [s :cstr off :int] :int)

T3: the character at byte offset off of UTF-8 text and its width, packed as scalar * 8 + width (a stray byte is itself, width 1).

defn

r7rs-utf8-ref__

(r7rs-utf8-ref__ [s :cstr i :int] :int)

T3: the scalar value of the i-th character of UTF-8 text (a scan from the start: a literal is short, and a program that indexes a long string builds a mutable one).

defn

r7rs-string-ref-code__

(r7rs-string-ref-code__ [s :cstr i :int] :int)
defn

r7rs-cstr-free__

(r7rs-cstr-free__ [s :cstr] :nil)

T8: release a scratch string the caller made and no value holds (a spelling already copied into a port buffer, a decimal spelling the bignum core has read). Never a string a Scheme value owns.

defn

r7rs-string-append2__

(r7rs-string-append2__ [a :cstr b :cstr] :cstr)
defn

r7rs-bsubstring__

(r7rs-bsubstring__ [s :cstr start :int end :int] :cstr)
defn

r7rs-cstr<__

(r7rs-cstr<__ [a :cstr b :cstr] :bool)
defn

r7rs-string-of-code__

(r7rs-string-of-code__ [c :int] :cstr)
defn

r7rs-int->string__

(r7rs-int->string__ [x :int] :cstr)
defn

r7rs-float->string__

(r7rs-float->string__ [x :float] :cstr)
defn

r7rs-range-start__

(r7rs-range-start__ [r] :int)

R7: the optional [start [end]] tail most sequence procedures take, defaulting to 0 and len.

defn

r7rs-range-end__

(r7rs-range-end__ [r len :int] :int)
defn

r7rs-range-check__

(r7rs-range-check__ [who :cstr start :int end :int len :int] :nil)

A range out of bounds raises an error object a program can guard, the start and end its irritants (r7rs-srfi-plan S7; it was a panic, docs/reported/r7rs-type-errors-are-uncatchable-panics.md).

defstruct

R7rsString

(defstruct R7rsString :heap [cps :(Vec int)])

---- strings (T3): characters, and mutable ones ---------------------------

A Scheme string is one of two things. A literal -- and a string from Turmeric, symbol->string, number->string, the case procedures, read -- is a cstr: immutable UTF-8, which R7RS allows of a literal. A string a procedure newly allocates -- make-string, string, string-copy, substring, string-append, list->string, vector->string, string-map, utf8->string, read-string -- is an R7rsString: its characters as code points in a vector, so string-ref and string-set! are constant time. Every string procedure takes either and counts characters, never bytes: (string-length "\x3BB;") is 1. Turmeric's cstr is unchanged (9.1): an R7rsString crosses into a Turmeric cstr parameter as a fresh UTF-8 copy (the elaborator's Scheme seam calls r7rs-str__, elab_call.c), and mutating a cstr string is the named error. Tests go through r7rs-mstring?, not a bare is?, which would narrow the value to the (unique) heap struct.

defn

r7rs-mstring?

(r7rs-mstring? [x] :bool)
defn

r7rs-mstring-cps__

(r7rs-mstring-cps__ [s :R7rsString] :(Vec int))
defn

r7rs-mk-string__

(r7rs-mk-string__ [v :(Vec int)] :any)
defn

r7rs-cps-go__

(r7rs-cps-go__ [s :cstr off :int n :int v :(Vec int)] :(Vec int))

UTF-8 text's characters as a fresh code-point vector. A cstr is walked by byte offset (r7rs-utf8-at__ answers the character there and its width); a port buffer would do the decoding too, but an R7rsIo is a unique handle, and a loop that reads from it and passes it on uses it twice where a Turmeric entry checks ownership.

defn

r7rs-cps-of-cstr__

(r7rs-cps-of-cstr__ [s :cstr] :(Vec int))
defn

r7rs-cps__

(r7rs-cps__ [s] :(Vec int))

any string's characters: an R7rsString's own vector (read it, do not keep it), a cstr's decoded afresh.

defn

r7rs-str__

(r7rs-str__ [x] :cstr)

characters [a, b) of a code-point vector as UTF-8, by halves (each byte is copied log n times, never n). r7rs-str__ -- any string as a cstr: a cstr is itself, an R7rsString is encoded afresh. The conversion at every seam: the prelude's own C and ports take cstr, and the elaborator calls it where a Scheme call passes a string to a Turmeric cstr parameter.

defn

r7rs-cps-range-go__

(r7rs-cps-range-go__ [v :(Vec int) i :int end :int out :(Vec int)] :(Vec int))

characters [a, b) of a vector as a fresh vector.

defn

r7rs-cps-range__

(r7rs-cps-range__ [v :(Vec int) a :int b :int] :(Vec int))
defn

r7rs-immutable__

(r7rs-immutable__ [who :cstr] :nil)

the named error for mutating a cstr-backed string.

defn

r7rs-fail-nil__

(r7rs-fail-nil__ [msg :cstr] :nil)
defn

r7rs-fail-char__

(r7rs-fail-char__ [msg :cstr] :R7rsChar)
defn

r7rs-string-length

(r7rs-string-length [s] :int)
defn

r7rs-string-ref

(r7rs-string-ref [s i :int] :R7rsChar)
defn

r7rs-string-set!

(r7rs-string-set! [s i :int c :R7rsChar] :nil)

T3: the mutators, on an R7rsString; a cstr-backed string is the named error.

defn

r7rs-fill-go__

(r7rs-fill-go__ [v :(Vec int) i :int end :int c :int] :nil)
defn

r7rs-string-fill!

(r7rs-string-fill! [s c :R7rsChar & r :any] :nil)
defn

r7rs-copy-fwd__

(r7rs-copy-fwd__ [dst :(Vec int) at :int src :(Vec int) i :int end :int] :nil)

string-copy! copies front to back when the destination starts at or before the source and back to front otherwise, so a copy within one string is right when the ranges overlap (R7RS 6.7).

defn

r7rs-copy-bwd__

(r7rs-copy-bwd__ [dst :(Vec int) at :int src :(Vec int) start :int i :int] :nil)
defn

r7rs-string-copy!

(r7rs-string-copy! [to at :int from & r :any] :nil)
defn

r7rs-string-append-go__

(r7rs-string-append-go__ [c :(Cons any) out :(Vec int)] :(Vec int))
defn

r7rs-string-append

(r7rs-string-append [& xs :any] :any)

a new (mutable) string.

defn

r7rs-string-copy

(r7rs-string-copy [s & r :any] :any)

a new (mutable) string of the characters [start, end).

defn

r7rs-substring

(r7rs-substring [s start :int end :int] :any)
defn

r7rs-string<2__

(r7rs-string<2__ [a b] :bool)

The string comparisons take two or more arguments (R7). Characters compare by scalar value, which is UTF-8's byte order, so both sides are compared as UTF-8.

defn

r7rs-string=2__

(r7rs-string=2__ [a b] :bool)
defn

r7rs-string>2__

(r7rs-string>2__ [a b] :bool)
defn

r7rs-string<=2__

(r7rs-string<=2__ [a b] :bool)
defn

r7rs-string>=2__

(r7rs-string>=2__ [a b] :bool)
defn

r7rs-string=?

(r7rs-string=? [a b & xs :any] :bool)
defn

r7rs-string<?

(r7rs-string<? [a b & xs :any] :bool)
defn

r7rs-string>?

(r7rs-string>? [a b & xs :any] :bool)
defn

r7rs-string<=?

(r7rs-string<=? [a b & xs :any] :bool)
defn

r7rs-string>=?

(r7rs-string>=? [a b & xs :any] :bool)
defn

r7rs-string->symbol

(r7rs-string->symbol [s] :Sym)
defn

r7rs-symbol->string

(r7rs-symbol->string [s :Sym] :cstr)
defn

r7rs-string->list-acc__

(r7rs-string->list-acc__ [v :(Vec int) i :int j :int acc] :any)

a loop (see r7rs-snoc__).

defn

r7rs-string->list-go__

(r7rs-string->list-go__ [v :(Vec int) i :int end :int] :any)
defn

r7rs-string->list

(r7rs-string->list [s & r :any] :any)
defn

r7rs-list->string-go__

(r7rs-list->string-go__ [l out :(Vec int)] :(Vec int))
defn

r7rs-list->string

(r7rs-list->string [l] :any)

a new (mutable) string of the chars.

defn

r7rs-vector-from-chain__

(r7rs-vector-from-chain__ [c :(Cons any) v :(Vec any)] :(Vec any))

---- vectors and bytevectors -------------------------------------------

defn

r7rs-vector

(r7rs-vector [& xs :any] :(Vec any))
defn

r7rs-make-vector-go__

(r7rs-make-vector-go__ [n :int fill v :(Vec any)] :(Vec any))
defn

r7rs-make-vector

(r7rs-make-vector [n :int & fill :any] :(Vec any))
defn

r7rs-index-error__

(r7rs-index-error__ [who :cstr v i :int] :any)

An index out of range raises an error object a program can guard (SRFI 64's test-error tests exactly this), where vec-get's own check panics (docs/reported/r7rs-type-errors-are-uncatchable-panics.md).

defn

r7rs-vector-ref

(r7rs-vector-ref [v :(Vec any) i :int] :any)
defn

r7rs-vector-set!

(r7rs-vector-set! [v :(Vec any) i :int x] :nil)
defn

r7rs-vector-length

(r7rs-vector-length [v :(Vec any)] :int)
defn

r7rs-vector->list-acc__

(r7rs-vector->list-acc__ [v :(Vec any) i :int j :int acc] :any)
defn

r7rs-vector->list-go__

(r7rs-vector->list-go__ [v :(Vec any) i :int end :int] :any)
defn

r7rs-vector->list

(r7rs-vector->list [v :(Vec any) & r :any] :any)
defn

r7rs-list->vector-go__

(r7rs-list->vector-go__ [l v :(Vec any)] :(Vec any))
defn

r7rs-list->vector

(r7rs-list->vector [l] :(Vec any))
defn

r7rs-vector-fill-go__

(r7rs-vector-fill-go__ [v :(Vec any) x i :int end :int] :nil)
defn

r7rs-vector-fill!

(r7rs-vector-fill! [v :(Vec any) x & r :any] :nil)
defn

r7rs-byte?__

(r7rs-byte?__ [x] :bool)

A byte outside 0..255, or not an exact integer, raises an error object a program can guard, as an index out of range does (r7rs-srfi-plan S7: SRFI 4 and 66 range-check their octets through these).

defn

r7rs-byte-error__

(r7rs-byte-error__ [who :cstr x] :any)
defn

r7rs-bytes-from-chain__

(r7rs-bytes-from-chain__ [c :(Cons any) v :(Vec int)] :(Vec int))
defn

r7rs-bytevector

(r7rs-bytevector [& xs :any] :any)
defn

r7rs-make-bytevector-go__

(r7rs-make-bytevector-go__ [n :int fill :int v :(Vec int)] :(Vec int))
defn

r7rs-make-bytevector

(r7rs-make-bytevector [n :int & fill :any] :any)
defn

r7rs-bytevector-bytes__

(r7rs-bytevector-bytes__ [b :R7rsBytevector] :(Vec int))
defn

r7rs-bytevector-u8-ref

(r7rs-bytevector-u8-ref [b :R7rsBytevector i :int] :int)
defn

r7rs-bytevector-u8-set!

(r7rs-bytevector-u8-set! [b :R7rsBytevector i :int x] :nil)
defn

r7rs-bytevector-length

(r7rs-bytevector-length [b :R7rsBytevector] :int)
defn

r7rs-values

(r7rs-values [& xs :any])

---- multiple values (plan Section 8, Q1: a carrier over a list) --------

defn

r7rs-values-items__

(r7rs-values-items__ [v :R7rsValues] :any)
defn

r7rs-floor/

(r7rs-floor/ [a b])

R5: the procedures that return two values sit after r7rs-values. (They had to, then: a variadic's forward declaration did not carry its rest parameter. R7 fixed that, so the ordering is now only tidiness.)

defn

r7rs-truncate/

(r7rs-truncate/ [a b])
defn

r7rs-exact-integer-sqrt

(r7rs-exact-integer-sqrt [x])
defn

r7rs-expt-exact__

(r7rs-expt-exact__ [b e] :any)

exact for an exact base and a non-negative exact exponent (the bignum core's code 7, square-and-multiply; T1: any size, where D8 stopped at int64); inexact through pow otherwise. An exponent outside int64 is refused unless the base is 0, 1 or -1: the answer could not be stored.

defn

r7rs-expt

(r7rs-expt [b e] :any)

T2: an exact base to a negative exact integer power is the exact reciprocal, (expt 2 -10) is 1/1024.

defn

r7rs-cplx-expt?__

(r7rs-cplx-expt?__ [b e] :bool)

T6: a complex base or exponent, or a negative base to a non-integer power, is complex: square-and-multiply for an exact complex base and a fixnum exponent ((expt +i 2) is -1), else exp(e log b). Zero to any power is 0 (1 when the power is zero).

defn

r7rs-expt-mul__

(r7rs-expt-mul__ [b e :int acc] :any)
defn

r7rs-cplx-expt__

(r7rs-cplx-expt__ [b e] :any)
defn

r7rs-exp

(r7rs-exp [x] :any)
defn

r7rs-log1__

(r7rs-log1__ [x] :any)

T6: a negative real's logarithm is complex (log|x| + pi i); the two-argument form is the quotient of two logarithms.

defn

r7rs-log

(r7rs-log [x & xs :any] :any)
defn

r7rs-sin

(r7rs-sin [x] :any)
defn

r7rs-cos

(r7rs-cos [x] :any)
defn

r7rs-tan

(r7rs-tan [x] :any)
defn

r7rs-real-unit?__

(r7rs-real-unit?__ [x] :bool)

asin and acos leave the reals outside [-1, 1] (T6: (asin 2) is complex).

defn

r7rs-asin

(r7rs-asin [x] :any)
defn

r7rs-acos

(r7rs-acos [x] :any)
defn

r7rs-atan

(r7rs-atan [y & xs :any] :any)
defn

r7rs-values-ref

(r7rs-values-ref [v i :int] :any)
defn

r7rs-values-rest

(r7rs-values-rest [v i :int] :any)
defn

r7rs-apply-list__

(r7rs-apply-list__ [f l] :any)

call f with the elements of l as its arguments. Up to eight through the dynamic call (emit_dyn_call's helpers carry eight, and the prelude is compiled on both back ends, so the limit is the compiled one); R6: a variadic f is fine -- the dynamic call packs the surplus arguments into its rest list. Past eight, r7rs-apply-long__.

defn

r7rs-apply-long__

(r7rs-apply-long__ [f l n :int] :any)

internal: apply past eight arguments (r7rs-apply-variadic-over-eight-arguments). The dynamic call's helpers carry eight arguments, but a variadic f needs only its fixed ones spread: the rest of the list becomes its rest argument directly. +, max, append, string-append and a program's own (define (f . xs) ...) are all variadic; a fixed-arity f with more than eight parameters is still refused.

defn

r7rs-variadic-fixed__

(r7rs-variadic-fixed__ [f] :int)

internal: a variadic procedure's count of fixed parameters, or -1 (not a registered variadic: emit_module.c's __tur_dyn_reg_variadic table, which every boxed variadic type joins).

defn

r7rs-call-variadic__

(r7rs-call-variadic__ [f fixed :int n :int l] :any)

internal: call the variadic f (fixed fixed parameters, fixed <= 8) on the n elements of the list l: the first fixed as its arguments, the rest packed by the dynamic call's own __tur_dyn_pack_rest into the rest chain.

defn

r7rs-spread-args-go__

(r7rs-spread-args-go__ [l last] :any)

(a b (c d)) to (a b c d): every argument but the last, then the last as the tail.

defn

r7rs-spread-args__

(r7rs-spread-args__ [l] :any)
defn

r7rs-apply

(r7rs-apply [f & args :any] :any)

(apply f a ... l): R7: the leading arguments are consed onto the final list.

defn

r7rs-call-with-values

(r7rs-call-with-values [producer consumer])
defn

r7rs-exit__

(r7rs-exit__ [code :int] :nil)

internal: flush and leave with a status.

defn

r7rs-void

(r7rs-void)

the unspecified value.

defn

r7rs-dyn-ref__

(r7rs-dyn-ref__ [i :int] :any)

---- control (R6) ------------------------------------------------------

Continuations are Turmeric's call/cc -- one-shot, upward, an escape -- wrapped so Scheme sees a procedure (plan D7). dynamic-wind keeps a wind stack that an escape unwinds; exceptions are a handler stack over the same escapes (D10 named effects, but a handle around a dynamic thunk is not lowered by the compiled back end, and the escape encoding is exactly what R7RS 6.11 describes); parameterize binds a parameter's cell under dynamic-wind; a promise is a shared box. ---- the dynamic environment ----------------------------------------------

The wind stack, the handler stack, parameterize's bindings and the value a re-entered continuation delivers belong to the code that is running, not to the program: they live in tur_r7rs_dyn (emit_dk_runtime.c), one per thread and one per fiber (tur_fiber_block_resume swaps it). As process globals, a raise on one thread called a handler another thread had installed, and a pop on one removed another's (docs/archive/r7rs-dynamic-environment-shared-across-threads.md). A slot that was never written is all zero, which reads as the empty list. r7rs-dyn-ref__ -- internal: slot i of the running code's dynamic environment -- 0 the wind stack, 1 the handler stack, 2 the parameter bindings, 3 a re-entry's delivered value.

defn

r7rs-dyn-set__

(r7rs-dyn-set__ [i :int v] :nil)

internal: set slot i. The slot outlives any region bracket, so the word is noted (the region store-hook rule).

defn

r7rs-dyn-unset?__

(r7rs-dyn-unset?__ [v] :bool)

internal: #t for a slot never written (all zero).

defn

r7rs-dyn-list__

(r7rs-dyn-list__ [i :int] :any)

internal: slot i as a Scheme list.

defstruct

R7rsWind

(defstruct R7rsWind :heap [before :any after :any])

one dynamic-wind frame: its before and after thunks.

defn

r7rs-winders__

(r7rs-winders__ :any)

the wind stack, innermost first, as a Scheme list.

defn

r7rs-winders-set!__

(r7rs-winders-set!__ [v] :nil)
defn

r7rs-wind-after__

(r7rs-wind-after__ [w :R7rsWind] :any)
defn

r7rs-dynamic-wind

(r7rs-dynamic-wind [before thunk after] :any)

run before, thunk, after; the frame is on the wind stack while thunk runs, so an escape out of thunk runs after.

defn

r7rs-rewind-to__

(r7rs-rewind-to__ [saved] :nil)

internal: pop wind frames, running each after, until the stack is the one captured with the continuation. The saved stack is always a tail of the current one for an escape; if it is not reached the continuation is being re-entered, which the underlying escape reports itself.

defn

r7rs-values-of-list__

(r7rs-values-of-list__ [l] :any)

internal: the value a (values ...) denotes: one value is itself, any other count is the R7rsValues carrier.

defn

r7rs-call/ec__

(r7rs-call/ec__ [f] :any)

internal: an ESCAPE-only call/cc (R6, D7). The receiver gets a variadic procedure; invoking it unwinds the wind stack to the capture point and delivers its arguments as the value of the call. Invoking it after the call has returned is the named error "continuation invoked after its call/cc prompt returned". guard and the eval bridge escape through this, which costs nothing per call; the public call/cc below is re-entrant and copies the stack.

defn

r7rs-cont-save-state

(r7rs-cont-save-state [p :ptr<void>] :nil)

---- T5: re-entrant continuations ----------------------------------------

A continuation is a copy of the C stack from the call/cc to the stack's base, taken when call/cc is called, plus the runtime state that tracks the stack (the tail-call trampoline, the CPS driver, the live escapes). Invoking it travels the wind stack to the captured one -- after thunks out, before thunks in -- then copies the stack back and jumps into it, so the call/cc returns again, however many times and whenever. Heap data is shared, as Scheme requires: a continuation restores control, not state. This is the classic copying implementation (SCM, early Guile); it keeps every frame between the call/cc and the base, C frames included, which is what a Scheme continuation is. Where the stack's base cannot be found the public call/cc is the escape above. r7rs-cont-save-state -- internal: record the runtime's per-thread state in a capture: the tail-call trampoline's root and armed callee, the CPS driver's landing and entry depth, and the live escapes.

(No __ suffix: an inline-C __TUR_CNAME_ splice ends at the first __.) This and r7rs-cont-load-state are their own functions, called from the capture through volatile pointers so that no compiler inlines them back: the function that calls setjmp must not touch a thread-local itself. Apple's arm64 clang, after setjmp's second return (a re-entry), stored to a thread-local through a stale address -- a write into the program's text that ended the program -- once the CPS state joined the trampoline's among the thread-locals (docs/archive/dk-reap-list-shared-across-threads.md). Out here each access computes its address afresh.

defn

r7rs-cont-load-state

(r7rs-cont-load-state [p :ptr<void>] :nil)

internal: put a capture's per-thread state back on a re-entry (see r7rs-cont-save-state).

defn

r7rs-cont-capture__

(r7rs-cont-capture__ :ptr<void>)

internal: capture; returns the handle, and returns AGAIN, tagged (low bit set), each time the continuation is re-entered.

defn

r7rs-cont-resumed?__

(r7rs-cont-resumed?__ [c :ptr<void>] :bool)

internal: #t for the tagged handle a re-entry returns.

defn

r7rs-cont-null?__

(r7rs-cont-null?__ [c :ptr<void>] :bool)

internal: #t when no copy could be taken (no stack base on this platform).

defn

r7rs-cont-here?__

(r7rs-cont-here?__ [c :ptr<void>] :bool)

internal: #t when the calling thread is the one that captured the continuation. Its image is a copy of that thread's stack at that thread's addresses, so a jump into it from any other thread would copy one thread's frames over another's.

defn

r7rs-cont-check-here__

(r7rs-cont-check-here__ [c :ptr<void>] :nil)

internal: raise an error object, one a program can guard, when a continuation is invoked on a thread other than the one that captured it. Checked before the wind travel, so no before or after thunk runs for a jump that is refused.

defn

r7rs-cont-resumable?__

(r7rs-cont-resumable?__ [c :ptr<void>] :bool)

internal: #f when the (scheme eval) evaluator cannot resume its side of the continuation: one captured inside a host call made from a text being evaluated ((eval '(f 1)), as against an applied procedure) can be re-entered only while that evaluation is still in progress -- its frames end with the eval, and resumed after it returned they would finish the evaluation a second time.

defn

r7rs-cont-check-resumable__

(r7rs-cont-check-resumable__ [c :ptr<void>] :nil)

internal: the error object a program can guard for that case. Checked before the wind travel, with the thread check.

defn

r7rs-cont-restore__

(r7rs-cont-restore__ [c :ptr<void>] :nil)

internal: copy the captured stack back and jump in.

defn

r7rs-cont-hooks-install__

(r7rs-cont-hooks-install__ [capture :ptr<void> resumable :ptr<void> restore :ptr<void> resumed :ptr<void>] :bool)

internal: point the capture above at the (scheme eval) evaluator's continuation hooks (src/turi/r7rs_embed.h): capture, resumable, restore, resumed. Run once, at startup, by stdlib/r7rs/eval.tur; the interpreter's twin does nothing, since its capture reaches the evaluator directly.

defn

r7rs-cont-delivered__

(r7rs-cont-delivered__ :any)

the value an invoked continuation hands its call/cc; set just before the jump, read just after it, on one thread.

defn

r7rs-cont-deliver!__

(r7rs-cont-deliver!__ [v] :nil)
defn

r7rs-run-toplevel-thunk

(r7rs-run-toplevel-thunk [thunk] :nil)

internal: call a top-level form's thunk. Its own function so the runner below can call it by C name from inline C.

defn

r7rs-run-toplevel-thunk-ptr

(r7rs-run-toplevel-thunk-ptr [p :ptr<void>] :nil)

internal: the trampoline r7k_run_form calls, void (*)(void *), over the thunk's address.

defn

r7rs-toplevel__

(r7rs-toplevel__ [thunk] :nil)

internal: run one top-level form under its own prompt (r7rs-toplevel-reentry-reruns-forms). The Scheme lowering wraps every statement of a program in it. A continuation captured inside the form copies the stack only up to the mark r7k_run_form takes (r7k_measure), so a re-entry from a later form restores this form's frames over that form's -- every statement is called from the same depth, so the mark is the same address for each -- finishes this form, and returns into the runner frame of the INVOKING form, which carries on after it: the way chibi's loader and Racket's per-form prompt behave. The mark lives in r7k_run_form, reached through a volatile function pointer so that no compiler folds that frame into the program's main (see its comment).

defn

r7rs-wind-depth__

(r7rs-wind-depth__ [l] :int)

internal: a wind stack's length.

defn

r7rs-wind-drop__

(r7rs-wind-drop__ [l n :int] :any)
defn

r7rs-wind-common__

(r7rs-wind-common__ [a b] :any)

internal: the longest common tail of two wind stacks.

defn

r7rs-wind-before__

(r7rs-wind-before__ [w :R7rsWind] :any)
defn

r7rs-rewind-into__

(r7rs-rewind-into__ [target common] :nil)

internal: enter the frames of target above common, outermost first: each before runs, then its frame is pushed.

defn

r7rs-travel-to__

(r7rs-travel-to__ [target] :nil)

internal: R7RS 6.10 -- leave the current extent to the common ancestor (each after, innermost first), then enter the target's (each before, outermost first).

defn

r7rs-call/cc

(r7rs-call/cc [f] :any)
defn

r7rs-read-error?

(r7rs-read-error? [x] :bool)

R7: an error object of that kind; (scheme file) raises file errors, the reader's arrive with R8.

defn

r7rs-file-error?

(r7rs-file-error? [x] :bool)
defn

r7rs-handlers__

(r7rs-handlers__ :any)

the exception handler stack, innermost first.

defn

r7rs-handlers-set!__

(r7rs-handlers-set!__ [v] :nil)
defn

r7rs-with-exception-handler

(r7rs-with-exception-handler [handler thunk] :any)

install handler for the extent of thunk. The install and the uninstall are wind frames, so an escape out of thunk leaves the stack as it found it.

defn

r7rs-raise-continuable

(r7rs-raise-continuable [obj] :any)

call the innermost handler with obj, with the outer handlers installed while it runs (R7RS 6.11); its value is the value of the raise.

defn

r7rs-raise

(r7rs-raise [obj] :any)

like raise-continuable, but a handler that returns is an error: a secondary exception is raised to the outer handlers.

defn

r7rs-error

(r7rs-error [msg & irritants :any] :any)

R7RS error: raise a fresh error object.

defn

r7rs-type-error-message__

(r7rs-type-error-message__ [who :cstr what :cstr] :cstr)

internal: a value of the wrong type reached a typed prelude procedure -- (car 5). Raise an error object, "car: not a pair" with the value as its irritant, where the checked cast at the seam used to panic (docs/archive/r7rs-type-errors-are-uncatchable-panics.md). who is the procedure ("" when the cast has none to name), what the expected type in Scheme's words ("" makes who the whole message, with no irritant: the r7rs-fail-* helpers' shape). The compiled back end calls it through the hook below, from the raising cast check; the interpreter calls it by name. It never returns: the raise escapes to a handler, and an unhandled one ends the program.

defn

r7rs-type-error__

(r7rs-type-error__ [who :cstr what :cstr x] :any)
defn

r7rs-type-error-hook-install__

(r7rs-type-error-hook-install__ :bool)

internal: point the raising cast check (__tur_any_cast_check_r7, which the emitter writes into any unit with a Scheme cast) at r7rs-type-error__. Run once, at startup, by the def below. The interpreter's twin does nothing: it finds the procedure by name.

defn

r7rs-raise-type__

(r7rs-raise-type__ [who :cstr what :cstr x] :bool)

internal: r7rs-type-error__, called through the hook from C. For the "it is an error" checks on the hottest paths (arithmetic, comparison, the r7rs-fail-* helpers): a direct raise there makes every procedure that reaches it effectful, which compiles it to CPS and costs the tail-call trampoline (tests/fixtures/r7rs-tail-calls), while a call into C is opaque to that analysis. An empty what makes who the whole message, with no irritant. Returns (false) only when no hook is installed; the caller then panics as it did before.

defn

r7rs-num-error__

(r7rs-num-error__ [who :cstr a b] :any)

internal: an arithmetic operator given a non-number; the irritant is the operand that is not one.

defstruct

R7rsParam

(defstruct R7rsParam :heap [value :any converter :any])

a parameter object's cell: its global value and converter. parameterize does not write the cell: it binds it in the running code's dynamic environment (slot 2), so no other thread or fiber sees the value.

defstruct

R7rsPBind

(defstruct R7rsPBind :heap [cell :any value :any])

one parameterize binding of a cell, in slot 2's list.

defstruct

R7rsParamMarker

(defstruct R7rsParamMarker [tag :int])

the private argument that asks a parameter for its cell.

defn

r7rs-param-get__

(r7rs-param-get__ [c :R7rsParam] :any)
defn

r7rs-param-conv__

(r7rs-param-conv__ [c :R7rsParam] :any)
defn

r7rs-param-set__

(r7rs-param-set__ [c :R7rsParam v] :nil)
defn

r7rs-pbind-cell__

(r7rs-pbind-cell__ [b :R7rsPBind] :any)
defn

r7rs-pbind-value__

(r7rs-pbind-value__ [b :R7rsPBind] :any)
defn

r7rs-pbind-set__

(r7rs-pbind-set__ [b :R7rsPBind v] :nil)
defn

r7rs-param-binding__

(r7rs-param-binding__ [cell l] :any)

internal: the innermost binding of cell in the binding list l, or the empty list when the cell is not bound there.

defn

r7rs-param-value__

(r7rs-param-value__ [cell] :any)

internal: a parameter's value for the running code: its innermost binding, else the cell's global value.

defn

r7rs-param-assign__

(r7rs-param-assign__ [cell v] :nil)

internal: (p v): the innermost binding when there is one, else the global value.

defn

r7rs-identity__

(r7rs-identity__ [x] :any)
defn

r7rs-make-parameter

(r7rs-make-parameter [init & xs :any] :any)

a parameter is a procedure: (p) reads it, and parameterize reaches its cell through the private marker.

defn

r7rs-param-cell__

(r7rs-param-cell__ [p] :any)
defn

r7rs-params-bind__

(r7rs-params-bind__ [cells vals l] :any)

internal: l with a binding of each cell to its value in front, the first pair innermost.

defn

r7rs-parameterize__

(r7rs-parameterize__ [bindings thunk] :any)

(parameterize ((p v) ...) body...): bindings is the list of (p . v); each new value goes through the parameter's converter. The new bindings go in front of the running code's own, and entering and leaving are wind frames.

defstruct

R7rsPBox

(defstruct R7rsPBox :heap [done :bool value :any])

a promise shares its box with the promise a delay-force chain yields, the R7RS 7.3 reference shape.

defstruct

R7rsPromise

(defstruct R7rsPromise :heap [box :any])
defn

r7rs-promise?

(r7rs-promise? [x] :bool)
defn

r7rs-pbox__

(r7rs-pbox__ [p :R7rsPromise] :any)
defn

r7rs-pbox-done__

(r7rs-pbox-done__ [b :R7rsPBox] :bool)
defn

r7rs-pbox-value__

(r7rs-pbox-value__ [b :R7rsPBox] :any)
defn

r7rs-pbox-set__

(r7rs-pbox-set__ [b :R7rsPBox done :bool v] :nil)
defn

r7rs-promise-share__

(r7rs-promise-share__ [p :R7rsPromise b] :nil)
defn

r7rs-delay-force__

(r7rs-delay-force__ [thunk] :any)

(delay-force expr): thunk yields a promise.

defn

r7rs-make-promise

(r7rs-make-promise [v] :any)

a promise already forced to v (a promise is itself).

defn

r7rs-force

(r7rs-force [p] :any)

iterative: each step runs the pending thunk and, unless that forced the promise already, adopts the resulting promise's state and makes the two share one box, so a delay-force loop runs in constant space (the self call is a tail call).

defn

r7rs-boolean=2__

(r7rs-boolean=2__ [a b] :bool)

---- R7: the rest of (scheme base) that is not a port -----------------

defn

r7rs-boolean=?

(r7rs-boolean=? [a b & xs :any] :bool)

#t when every argument is #t, or every one is #f.

defn

r7rs-symbol=2__

(r7rs-symbol=2__ [a b] :bool)
defn

r7rs-symbol=?

(r7rs-symbol=? [a b & xs :any] :bool)

#t when every argument is the same symbol.

defn

r7rs-list-set!

(r7rs-list-set! [l k :int x] :nil)

store x as the k-th element.

defn

r7rs-make-list-go__

(r7rs-make-list-go__ [k :int x acc] :any)
defn

r7rs-make-list

(r7rs-make-list [k :int & fill :any] :any)

k elements, each fill (default #f).

defn

r7rs-make-string-go__

(r7rs-make-string-go__ [v :(Vec int) k :int c :int] :(Vec int))

a new (mutable) string of k copies of char (default #\space).

defn

r7rs-make-string

(r7rs-make-string [k :int & c :any] :any)
defn

r7rs-string

(r7rs-string [& cs :any] :any)

a new (mutable) string of the given chars.

defn

r7rs-string->vector

(r7rs-string->vector [s & r :any] :any)
defn

r7rs-vector->string

(r7rs-vector->string [v :(Vec any) & r :any] :any)
defn

r7rs-seq-lists__

(r7rs-seq-lists__ [conv first rest :(Cons any)] :any)

the list form of each sequence in a chain, through conv (string->list / vector->list): the multi-sequence map/for-each below run over lists.

defn

r7rs-string-list1__

(r7rs-string-list1__ [s] :any)
defn

r7rs-vector-list1__

(r7rs-vector-list1__ [v] :any)
defn

r7rs-string-map

(r7rs-string-map [f s & ss :any] :any)

(string-map f s1 s2 ...): f's results are chars.

defn

r7rs-string-for-each

(r7rs-string-for-each [f s & ss :any] :nil)
defn

r7rs-vector-map

(r7rs-vector-map [f v & vs :any] :any)
defn

r7rs-vector-for-each

(r7rs-vector-for-each [f v & vs :any] :nil)
defn

r7rs-vec-push-range__

(r7rs-vec-push-range__ [out :(Vec any) v :(Vec any) i :int end :int] :nil)
defn

r7rs-vector-append-go__

(r7rs-vector-append-go__ [out :(Vec any) c :(Cons any)] :(Vec any))
defn

r7rs-vector-append

(r7rs-vector-append [& vs :any] :any)

a fresh vector of every argument's elements.

defn

r7rs-vector-copy

(r7rs-vector-copy [v :(Vec any) & r :any] :any)

a fresh vector of [start, end).

defn

r7rs-vec-store-list__

(r7rs-vec-store-list__ [to :(Vec any) at :int l] :nil)
defn

r7rs-vector-copy!

(r7rs-vector-copy! [to :(Vec any) at :int from :(Vec any) & r :any] :nil)

copy [start, end) of from into to at at; the source range is read out first, so overlapping ranges copy correctly.

defn

r7rs-bytes-push-range__

(r7rs-bytes-push-range__ [out :(Vec int) v :(Vec int) i :int end :int] :nil)
defn

r7rs-bytevector-append-go__

(r7rs-bytevector-append-go__ [out :(Vec int) c :(Cons any)] :(Vec int))
defn

r7rs-bytevector-append

(r7rs-bytevector-append [& bs :any] :any)
defn

r7rs-bytevector-copy

(r7rs-bytevector-copy [bv & r :any] :any)
defn

r7rs-bytes-read-acc__

(r7rs-bytes-read-acc__ [v :(Vec int) i :int j :int acc] :any)
defn

r7rs-bytes-read-range__

(r7rs-bytes-read-range__ [v :(Vec int) i :int end :int] :any)
defn

r7rs-bytes-store-list__

(r7rs-bytes-store-list__ [to :(Vec int) at :int l] :nil)
defn

r7rs-bytevector-copy!

(r7rs-bytevector-copy! [to at :int from & r :any] :nil)
defn

r7rs-utf8-bytes-go__

(r7rs-utf8-bytes-go__ [s :cstr i :int end :int out :(Vec int)] :(Vec int))

the UTF-8 bytes of characters [start, end) (T3: start and end count characters, as every string procedure does).

defn

r7rs-string->utf8

(r7rs-string->utf8 [s & r :any] :any)
defn

r7rs-utf8-cont__

(r7rs-utf8-cont__ [v :(Vec int) i :int end :int] :int)
defn

r7rs-utf8-go__

(r7rs-utf8-go__ [v :(Vec int) i :int end :int out :(Vec int)] :(Vec int))

decode the bytes, checking the encoding: a string is built from code points, so an invalid sequence is an error, not garbage. T8: straight into code points; it appended one character at a time, a quadratic that leaked every intermediate string.

defn

r7rs-utf8->string

(r7rs-utf8->string [bv & r :any] :any)
defn

r7rs-features

(r7rs-features :any)

the feature identifiers cond-expand tests (scheme_lower.c R7RS_FEATURES, then srfi-N for every SRFI_LIBS row that is here, in table order). tests/check-r7rs-srfi-sync.sh fails when this list and that one differ, and tests/fixtures/r7rs-features-agree asks cond-expand about each (r7rs-srfi-plan D4). exact-closed: + - * on exact integers are exact (or signal); only / may be inexact. ratios: / of exact integers is exact.

defn

r7rs-simplest-pos__

(r7rs-simplest-pos__ [lo hi] :any)

the simplest rational within y of x (R7RS 6.2.6), by the continued-fraction walk. T2: the walk is written over the generic operators, so exact arguments give the exact answer ((rationalize (exact .3) 1/10) is 1/3) and an inexact one the inexact answer, from one definition.

defn

r7rs-simplest__

(r7rs-simplest__ [lo hi] :any)
defn

r7rs-rationalize

(r7rs-rationalize [x y] :any)
defn

r7rs-char-upper-case?

(r7rs-char-upper-case? [c :R7rsChar] :bool)

case mapping ---------------------------------

Chars are Unicode scalar values. R10: non-ASCII answers come from the Unicode tables (stdlib/r7rs/unicode.tur): a char's simple case mapping, the Uppercase/Lowercase properties, Nd digits, and a string's FULL case mapping ((string-upcase "\xDF;") is "SS"). Strings stay byte strings, so the string procedures map the UTF-8 in place rather than per char.

defn

r7rs-char-lower-case?

(r7rs-char-lower-case? [c :R7rsChar] :bool)
defn

r7rs-char-foldcase

(r7rs-char-foldcase [c :R7rsChar] :R7rsChar)
defn

r7rs-digit-value

(r7rs-digit-value [c :R7rsChar] :any)

the value of a decimal digit (any Nd), #f otherwise.

defn

r7rs-fold-code__

(r7rs-fold-code__ [c] :int)
defn

r7rs-char-ci=2__

(r7rs-char-ci=2__ [a b] :bool)
defn

r7rs-char-ci<2__

(r7rs-char-ci<2__ [a b] :bool)
defn

r7rs-char-ci>2__

(r7rs-char-ci>2__ [a b] :bool)
defn

r7rs-char-ci<=2__

(r7rs-char-ci<=2__ [a b] :bool)
defn

r7rs-char-ci>=2__

(r7rs-char-ci>=2__ [a b] :bool)
defn

r7rs-char-ci=?

(r7rs-char-ci=? [a b & xs :any] :bool)
defn

r7rs-char-ci<?

(r7rs-char-ci<? [a b & xs :any] :bool)
defn

r7rs-char-ci>?

(r7rs-char-ci>? [a b & xs :any] :bool)
defn

r7rs-char-ci<=?

(r7rs-char-ci<=? [a b & xs :any] :bool)
defn

r7rs-char-ci>=?

(r7rs-char-ci>=? [a b & xs :any] :bool)
defn

r7rs-case-map__

(r7rs-case-map__ [who :cstr s r :(Cons any) op :int] :cstr)

string-upcase and string-downcase take SRFI 13's optional [start, end) too, and then map just those characters: a compatible extension, so (srfi 13) re-exports these rather than giving the names a second meaning next to (scheme char) (r7rs-srfi-plan D5).

defn

r7rs-string-upcase

(r7rs-string-upcase [s & r :any] :cstr)
defn

r7rs-string-downcase

(r7rs-string-downcase [s & r :any] :cstr)
defn

r7rs-string-foldcase

(r7rs-string-foldcase [s] :cstr)
defn

r7rs-string-ci=2__

(r7rs-string-ci=2__ [a b] :bool)
defn

r7rs-string-ci<2__

(r7rs-string-ci<2__ [a b] :bool)
defn

r7rs-string-ci>2__

(r7rs-string-ci>2__ [a b] :bool)
defn

r7rs-string-ci<=2__

(r7rs-string-ci<=2__ [a b] :bool)
defn

r7rs-string-ci>=2__

(r7rs-string-ci>=2__ [a b] :bool)
defn

r7rs-string-ci=?

(r7rs-string-ci=? [a b & xs :any] :bool)
defn

r7rs-string-ci<?

(r7rs-string-ci<? [a b & xs :any] :bool)
defn

r7rs-string-ci>?

(r7rs-string-ci>? [a b & xs :any] :bool)
defn

r7rs-string-ci<=?

(r7rs-string-ci<=? [a b & xs :any] :bool)
defn

r7rs-string-ci>=?

(r7rs-string-ci>=? [a b & xs :any] :bool)
defn

r7rs-caaar

(r7rs-caaar [p] :any)

the three- and four-deep compositions ----------

defn

r7rs-caadr

(r7rs-caadr [p] :any)
defn

r7rs-cadar

(r7rs-cadar [p] :any)
defn

r7rs-cdaar

(r7rs-cdaar [p] :any)
defn

r7rs-cdadr

(r7rs-cdadr [p] :any)
defn

r7rs-cddar

(r7rs-cddar [p] :any)
defn

r7rs-cdddr

(r7rs-cdddr [p] :any)
defn

r7rs-caaaar

(r7rs-caaaar [p] :any)
defn

r7rs-caaadr

(r7rs-caaadr [p] :any)
defn

r7rs-caadar

(r7rs-caadar [p] :any)
defn

r7rs-caaddr

(r7rs-caaddr [p] :any)
defn

r7rs-cadaar

(r7rs-cadaar [p] :any)
defn

r7rs-cadadr

(r7rs-cadadr [p] :any)
defn

r7rs-caddar

(r7rs-caddar [p] :any)
defn

r7rs-cadddr

(r7rs-cadddr [p] :any)
defn

r7rs-cdaaar

(r7rs-cdaaar [p] :any)
defn

r7rs-cdaadr

(r7rs-cdaadr [p] :any)
defn

r7rs-cdadar

(r7rs-cdadar [p] :any)
defn

r7rs-cdaddr

(r7rs-cdaddr [p] :any)
defn

r7rs-cddaar

(r7rs-cddaar [p] :any)
defn

r7rs-cddadr

(r7rs-cddadr [p] :any)
defn

r7rs-cdddar

(r7rs-cdddar [p] :any)
defn

r7rs-cddddr

(r7rs-cddddr [p] :any)
defn

r7rs-real-part

(r7rs-real-part [x] :any)

---- (scheme complex) -----------------------------------------------------

T6: over R7rsComplex (above). A real's imaginary part is exact 0.

defn

r7rs-imag-part

(r7rs-imag-part [x] :any)
defn

r7rs-magnitude

(r7rs-magnitude [x] :any)

|z|: exact for an exact complex number whose squared magnitude is a perfect square ((magnitude 3+4i) is 5).

defn

r7rs-angle

(r7rs-angle [x] :any)

arg z; for a real, 0 when non-negative and pi when negative.

defn

r7rs-make-rectangular

(r7rs-make-rectangular [re im] :any)
defn

r7rs-make-polar

(r7rs-make-polar [m a] :any)

m e^(ia); exact m when the angle is exact zero.

defopaque

R7rsIo

(defopaque R7rsIo :ptr<void>)

---- R8: ports ------------------------------------------------------------

A port is an R7rsPort over an R7rsIo: one C byte buffer with a read position and, for a file port, the FILE it reads or writes. A string or bytevector port is the buffer alone; an input file port fills the buffer from its FILE on demand (so peeking a multi-byte character needs no ungetc) and reclaims it once it is drained; an output file port writes straight through. The primitives are inline C with interpreter twins in interpreter_natives.c (keep them equal). Text is UTF-8: a char is read by decoding, written by encoding.

The current ports are parameter objects (R7RS 6.13.1), so parameterize and with-output-to-file rebind them with the R6 machinery. R7rsIo -- the C buffer behind a port.

defopaque

R7rsIdTab

(defopaque R7rsIdTab :ptr<void>)

an identity hash table from a heap value to an int: the printer's datum-label bookkeeping and the reader's patch walk. Keys are compared by address and never dereferenced, and a table lives for one write or read call, so no key outlives the value it names.

defn

r7rs-io-new__

(r7rs-io-new__ :R7rsIo)

an empty in-memory buffer.

defn

r7rs-io-std__

(r7rs-io-std__ [k :int] :R7rsIo)

the buffer over stdin (0), stdout (1) or stderr (2).

defn

r7rs-io-open__

(r7rs-io-open__ [path :cstr mode :cstr] :R7rsIo)

a buffer over fopen(path, mode); r7rs-io-ok?__ says whether the open succeeded.

defn

r7rs-io-ok?__

(r7rs-io-ok?__ [io :R7rsIo] :bool)
defn

r7rs-io-add__

(r7rs-io-add__ [io :R7rsIo s :cstr] :nil)

write a string: through to the FILE, or onto the buffer. stdout is flushed before anything goes to stderr, so the two interleave in program order.

defn

r7rs-io-add-byte__

(r7rs-io-add-byte__ [io :R7rsIo x :int] :nil)

write one byte.

defn

r7rs-io-add-code__

(r7rs-io-add-code__ [io :R7rsIo c :int] :nil)

T8: a code point, UTF-8 encoded, byte by byte (no scratch string per character).

defn

r7rs-cps-encode__

(r7rs-cps-encode__ [v :(Vec int) i :int end :int io :R7rsIo] :nil)

T8: encoded into one buffer. It was a divide-and-conquer of appends, every intermediate string leaked: O(n log n) bytes of garbage per conversion, and every seam crossing of a mutable string converts.

defn

r7rs-cps->cstr__

(r7rs-cps->cstr__ [v :(Vec int) a :int b :int] :cstr)
defn

r7rs-io-peek__

(r7rs-io-peek__ [io :R7rsIo k :int] :int)

the byte k places past the read position, or -1 at end of input. A file buffer is filled from its FILE as far as needed; stdout is flushed before stdin is read, so a prompt shows.

defn

r7rs-io-skip__

(r7rs-io-skip__ [io :R7rsIo k :int] :nil)

advance the read position by k bytes (after a peek).

defn

r7rs-io-str__

(r7rs-io-str__ [io :R7rsIo] :cstr)

the buffer's bytes as a fresh string.

defn

r7rs-io-len__

(r7rs-io-len__ [io :R7rsIo] :int)
defn

r7rs-io-byte-ref__

(r7rs-io-byte-ref__ [io :R7rsIo i :int] :int)
defn

r7rs-io-flush__

(r7rs-io-flush__ [io :R7rsIo] :nil)
defn

r7rs-io-close__

(r7rs-io-close__ [io :R7rsIo] :nil)

close a file buffer's FILE (never a standard stream).

defn

r7rs-io-free__

(r7rs-io-free__ [io :R7rsIo] :nil)

release a scratch buffer (a string builder).

defn

r7rs-io-take-str__

(r7rs-io-take-str__ [io :R7rsIo] :cstr)

a builder's contents, and the builder released.

defn

r7rs-idtab-new__

(r7rs-idtab-new__ :R7rsIdTab)

the identity table (open addressing, key 0 empty). A missing key reads as -2.

defn

r7rs-idtab-get__

(r7rs-idtab-get__ [tab :R7rsIdTab x] :int)
defn

r7rs-idtab-put__

(r7rs-idtab-put__ [tab :R7rsIdTab x v :int] :nil)
defn

r7rs-idtab-count__

(r7rs-idtab-count__ [tab :R7rsIdTab] :int)
defn

r7rs-idtab-free__

(r7rs-idtab-free__ [tab :R7rsIdTab] :nil)
defn

r7rs-uf-add__

(r7rs-uf-add__ [x tab :R7rsIdTab parent :(Vec int)] :int)

structural on pairs, vectors and bytevectors, eqv? on everything else, and it TERMINATES ON CYCLES (R7RS 6.1). T8: the pairs and vectors under comparison are merged into classes (union-find, as in Adams and Dybvig's "Efficient nondestructive equality checking for trees and graphs"): two nodes already in one class are assumed equal, the coinductive reading the standard specifies. Any difference makes the whole answer #f, so an assumption that turns out wrong is never kept. Linear, where the list of pairs under comparison it replaces made two equal lists of 10^5 elements take half a minute; and a cycle through vectors now terminates too.

defn

r7rs-uf-id-of__

(r7rs-uf-id-of__ [x tab :R7rsIdTab parent :(Vec int) i :int] :int)
defn

r7rs-uf-id__

(r7rs-uf-id__ [x tab :R7rsIdTab parent :(Vec int)] :int)
defn

r7rs-uf-find__

(r7rs-uf-find__ [parent :(Vec int) i :int] :int)
defn

r7rs-uf-same?__

(r7rs-uf-same?__ [a b tab :R7rsIdTab parent :(Vec int)] :bool)

#t when a and b are already one class; else joins them.

defn

r7rs-equal-go__

(r7rs-equal-go__ [a b tab :R7rsIdTab parent :(Vec int)] :bool)
defn

r7rs-equal-vec__

(r7rs-equal-vec__ [a :(Vec any) b :(Vec any) i :int tab :R7rsIdTab parent :(Vec int)] :bool)
defn

r7rs-equal-bytes__

(r7rs-equal-bytes__ [a :(Vec int) b :(Vec int) i :int] :bool)
defn

r7rs-equal?

(r7rs-equal? [a b] :bool)
defn

r7rs-fx-and__

(r7rs-fx-and__ [a :int b :int] :int)

---- fixnum bits (r7rs-srfi-plan S7: SRFI 60) -----------------------------

SRFI 60's fast path: two fixnums (Scheme's int-carried exact integers) in two's complement, which is what the SRFI specifies for negatives too. Bignums take the SRFI's arithmetic formulation in stdlib/srfi/60.scm, as they are base-1e9 limbs, not bits. Plain Turmeric, the same on both back ends. r7rs-fx-and__ -- internal: the bitwise AND of two fixnums.

defn

r7rs-fx-ior__

(r7rs-fx-ior__ [a :int b :int] :int)

internal: the bitwise inclusive OR of two fixnums.

defn

r7rs-fx-xor__

(r7rs-fx-xor__ [a :int b :int] :int)

internal: the bitwise exclusive OR of two fixnums.

defn

r7rs-fx-shr__

(r7rs-fx-shr__ [a :int k :int] :int)

internal: fixnum a shifted right k places, 0 <= k < 64, rounding toward negative infinity. bit-shr is a logical shift, so a negative a is shifted as its complement, which is non-negative.

defn

r7rs-identity-word__

(r7rs-identity-word__ [x] :int)

---- hashing (r7rs-srfi-plan S4: SRFI 69) --------------------------------

Each hash is a non-negative int below 2^30, so a table's arithmetic on it stays in fixnums. r7rs-eqv-hash__ agrees with eqv? (and so with eq?, which is eqv? here): it hashes by value what eqv? compares by value, and by address the rest. r7rs-equal-hash__ agrees with equal?. Only the two primitives are C; the rest is this Turmeric, the same on both back ends. r7rs-identity-word__ -- internal: a value's carrier word: a heap value's address (stable, as the collector does not move), an int's value, a float's bits. Inline C on the compiled path, a native under the interpreter (the payload word r7rs-same-ref__ compares).

defn

r7rs-cstr-hash__

(r7rs-cstr-hash__ [s :cstr ci :bool] :int)

internal: FNV-1a over a string's UTF-8 bytes, folded to 30 bits. With ci, an ASCII letter hashes as its lower case, and a byte outside ASCII answers -1 (the caller folds that string itself).

defn

r7rs-hash-fold__

(r7rs-hash-fold__ [w :int] :int)

internal: a 64-bit word folded to 30 bits.

defn

r7rs-hash-mix__

(r7rs-hash-mix__ [h :int x :int] :int)

internal: one more 30-bit hash folded into h.

defn

r7rs-string-hash__

(r7rs-string-hash__ [s] :int)

SRFI 69's string-hash: agrees with string=?, over a literal and a mutable string alike (the same characters, the same bytes).

defn

r7rs-string-ci-hash__

(r7rs-string-ci-hash__ [s] :int)

SRFI 69's string-ci-hash: agrees with string-ci=?. An ASCII string is folded as it is hashed; any other is folded first, which gives an ASCII one's bytes the same way.

defn

r7rs-float-hash__

(r7rs-float-hash__ [x :float] :int)

internal: an integral float hashes as the exact integer would (so a table keyed by = finds 2 from 2.0), which also puts 0.0 and -0.0 together, as eqv? has them; any other float by its bits.

defn

r7rs-eqv-hash__

(r7rs-eqv-hash__ [x] :int)

SRFI 69's hash-by-identity: agrees with eqv? and eq?.

defn

r7rs-equal-hash__

(r7rs-equal-hash__ [x] :int)

SRFI 69's hash: agrees with equal?. It reads at most 16 elements of a list or vector (and 64 bytes of a bytevector), three levels down, so it is quick on a big key and terminates on a cycle, as equal? does. Values equal? compares by eqv? hash as r7rs-eqv-hash__.

defn

r7rs-equal-hash-go__

(r7rs-equal-hash-go__ [x depth :int] :int)
defn

r7rs-equal-hash-sub__

(r7rs-equal-hash-sub__ [x depth :int] :int)
defn

r7rs-equal-hash-list__

(r7rs-equal-hash-list__ [x depth :int n :int h :int] :int)
defn

r7rs-equal-hash-vec__

(r7rs-equal-hash-vec__ [v :(Vec any) depth :int i :int h :int] :int)
defn

r7rs-equal-hash-bytes__

(r7rs-equal-hash-bytes__ [b :(Vec int) i :int h :int] :int)
defstruct

R7rsPort

(defstruct R7rsPort :heap [kind :int input :bool output :bool binary :bool open :bool fold :bool io :R7rsIo])

kind 0 is a file, 1 a string, 2 a bytevector. A port is an input port or an output port, never both, so one open flag serves. fold is the port's #!fold-case state, which read keeps (R7RS 2.1: the directive affects later data read from the same port).

defn

r7rs-port?

(r7rs-port? [x] :bool)
defn

r7rs-port-kind__

(r7rs-port-kind__ [p :R7rsPort] :int)
defn

r7rs-port-in__

(r7rs-port-in__ [p :R7rsPort] :bool)
defn

r7rs-port-out__

(r7rs-port-out__ [p :R7rsPort] :bool)
defn

r7rs-port-bin__

(r7rs-port-bin__ [p :R7rsPort] :bool)
defn

r7rs-port-open__

(r7rs-port-open__ [p :R7rsPort] :bool)
defn

r7rs-port-io__

(r7rs-port-io__ [p :R7rsPort] :R7rsIo)
defn

r7rs-port-mark-closed__

(r7rs-port-mark-closed__ [p :R7rsPort] :nil)
defn

r7rs-port-fold__

(r7rs-port-fold__ [p :R7rsPort] :bool)
defn

r7rs-port-set-fold__

(r7rs-port-set-fold__ [p :R7rsPort v :bool] :nil)
defn

r7rs-make-port__

(r7rs-make-port__ [kind :int input :bool binary :bool io :R7rsIo] :any)
defn

r7rs-input-port?

(r7rs-input-port? [x] :bool)
defn

r7rs-output-port?

(r7rs-output-port? [x] :bool)
defn

r7rs-textual-port?

(r7rs-textual-port? [x] :bool)
defn

r7rs-binary-port?

(r7rs-binary-port? [x] :bool)
defn

r7rs-input-port-open?

(r7rs-input-port-open? [p] :bool)
defn

r7rs-output-port-open?

(r7rs-output-port-open? [p] :bool)
defn

r7rs-port-arg__

(r7rs-port-arg__ [rl param] :any)

the optional port argument: the first of rl, or the current port the parameter holds.

defn

r7rs-port-of-chain__

(r7rs-port-of-chain__ [c :(Cons any) param] :any)

T8: the same, read off the rest-argument chain itself, so an I/O call builds no scratch list to find its port.

defn

r7rs-after-port__

(r7rs-after-port__ [rl] :any)
defn

r7rs-out-io__

(r7rs-out-io__ [port] :R7rsIo)

the buffer of an open port of the right direction; anything else is an error a guard can catch.

defn

r7rs-in-io__

(r7rs-in-io__ [port] :R7rsIo)
defn

r7rs-port-put__

(r7rs-port-put__ [port s :cstr] :nil)

internal: a string onto an output port.

defn

r7rs-newline

(r7rs-newline [& r :any] :nil)

(newline [port]).

defn

r7rs-write-char

(r7rs-write-char [c :R7rsChar & r :any] :nil)

(write-char char [port]).

defn

r7rs-write-string

(r7rs-write-string [s & r :any] :nil)

(write-string string [port [start [end]]]); start and end count characters.

defn

r7rs-write-u8

(r7rs-write-u8 [x :int & r :any] :nil)

(write-u8 byte [port]).

defn

r7rs-write-bytes-go__

(r7rs-write-bytes-go__ [io :R7rsIo v :(Vec int) i :int end :int] :nil)
defn

r7rs-write-bytevector

(r7rs-write-bytevector [bv & r :any] :nil)

(write-bytevector bv [port [start [end]]]).

defn

r7rs-flush-output-port

(r7rs-flush-output-port [& r :any] :nil)

(flush-output-port [port]).

defn

r7rs-utf8-width__

(r7rs-utf8-width__ [b :int] :int)

the byte length of the character a lead byte starts.

defn

r7rs-io-cont__

(r7rs-io-cont__ [io :R7rsIo k :int] :int)
defn

r7rs-io-peek-code__

(r7rs-io-peek-code__ [io :R7rsIo] :int)

the next character's scalar value, -1 at the end.

defn

r7rs-io-read-code__

(r7rs-io-read-code__ [io :R7rsIo] :int)
defn

r7rs-in-port-io__

(r7rs-in-port-io__ [r :(Cons any)] :R7rsIo)
defn

r7rs-code->char-or-eof__

(r7rs-code->char-or-eof__ [c :int] :any)
defn

r7rs-read-char

(r7rs-read-char [& r :any] :any)

the next character, or the eof object.

defn

r7rs-peek-char

(r7rs-peek-char [& r :any] :any)
defn

r7rs-read-u8

(r7rs-read-u8 [& r :any] :any)

the next byte, or the eof object.

defn

r7rs-peek-u8

(r7rs-peek-u8 [& r :any] :any)
defn

r7rs-io-ready?__

(r7rs-io-ready?__ [io :R7rsIo] :bool)

internal: whether a read on the buffer would not block (R7RS 6.13.2): a buffered byte, a string or bytevector buffer (its end of input counts as ready), a FILE at end of file, or a FILE whose descriptor has input now (a zero-timeout poll, so a terminal or an empty pipe answers #f). Windows has no poll over a FILE; it answers #t.

defn

r7rs-repl-value__

(r7rs-repl-value__ [x] :any)

internal: a REPL top-level expression's value as an any. A top-level expression's value is its elaborated type's representation (a let yielding a vector is the bare Vec), which the prompt's write cannot read as a Scheme value; passing it through an any parameter widens it the way a procedure's result is (r7rs-repl-toplevel-expression-value-not-widened).

defn

r7rs-char-ready?

(r7rs-char-ready? [& r :any] :bool)

whether a read would not block now. A string or bytevector port is always ready; a file, pipe or console port is asked (r7rs-io-ready?__).

defn

r7rs-u8-ready?

(r7rs-u8-ready? [& r :any] :bool)
defn

r7rs-read-line-go__

(r7rs-read-line-go__ [io :R7rsIo out :R7rsIo] :nil)

the characters up to a line end (LF, CR or CR LF, which is consumed and not included), or the eof object at the end of input.

defn

r7rs-read-line

(r7rs-read-line [& r :any] :any)
defn

r7rs-read-string-go__

(r7rs-read-string-go__ [io :R7rsIo out :R7rsIo k :int] :nil)

(read-string k [port]): up to k characters, or the eof object when none are left.

defn

r7rs-read-string

(r7rs-read-string [k :int & r :any] :any)
defn

r7rs-read-bytes-go__

(r7rs-read-bytes-go__ [io :R7rsIo v :(Vec int) k :int] :(Vec int))

(read-bytevector k [port]): up to k bytes.

defn

r7rs-read-bytevector

(r7rs-read-bytevector [k :int & r :any] :any)
defn

r7rs-read-into-go__

(r7rs-read-into-go__ [io :R7rsIo v :(Vec int) i :int end :int n :int] :int)

(read-bytevector! bv [port [start [end]]]): the number of bytes stored, or the eof object.

defn

r7rs-read-bytevector!

(r7rs-read-bytevector! [bv & r :any] :any)
defn

r7rs-open-input-string

(r7rs-open-input-string [s] :any)

---- string and bytevector ports, closing ---------------------------------

defn

r7rs-open-output-string

(r7rs-open-output-string :any)
defn

r7rs-get-output-string

(r7rs-get-output-string [p] :cstr)

everything written to a string port so far.

defn

r7rs-open-input-bytevector

(r7rs-open-input-bytevector [bv] :any)
defn

r7rs-open-output-bytevector

(r7rs-open-output-bytevector :any)
defn

r7rs-io-bytes-go__

(r7rs-io-bytes-go__ [io :R7rsIo i :int n :int v :(Vec int)] :(Vec int))
defn

r7rs-get-output-bytevector

(r7rs-get-output-bytevector [p] :any)

everything written to a bytevector port.

defn

r7rs-close-port

(r7rs-close-port [p] :nil)

close either direction (closing twice is harmless).

defn

r7rs-close-input-port

(r7rs-close-input-port [p] :nil)
defn

r7rs-close-output-port

(r7rs-close-output-port [p] :nil)
defn

r7rs-call-with-port

(r7rs-call-with-port [p proc] :any)

(proc port), then close it and return proc's value.

defn

r7rs-node?__

(r7rs-node?__ [x] :bool)

---- the printer: display, write, write-shared, write-simple -------------

R7RS 6.13.3: write and display label only the pairs and vectors that are part of a cycle (#0= defines a label, #0# refers back), so they always terminate; write-shared labels every pair and vector that appears more than once; write-simple labels nothing and loops on a cycle. A pre-pass fills an identity table: 1 while a node is on the current path, 2 when done, 3 / 4 for the same states of a node that needs a label. List spines are walked iteratively (a long list is not a deep recursion); only car nesting recurses.

defn

r7rs-cyc-spine__

(r7rs-cyc-spine__ [p tab :R7rsIdTab n :int] :int)

The cycle pre-pass: a node met again while it is still on the path is a back edge, so it gets a label. A spine marks each new pair as on the path, then finishes exactly the pairs it marked.

defn

r7rs-cyc-finish__

(r7rs-cyc-finish__ [p tab :R7rsIdTab n :int] :nil)
defn

r7rs-cyc-vec-go__

(r7rs-cyc-vec-go__ [v :(Vec any) i :int tab :R7rsIdTab] :nil)
defn

r7rs-mark-cycles__

(r7rs-mark-cycles__ [x tab :R7rsIdTab] :nil)
defn

r7rs-shr-spine__

(r7rs-shr-spine__ [p tab :R7rsIdTab] :nil)

The sharing pre-pass: any pair or vector met twice gets a label.

defn

r7rs-shr-vec-go__

(r7rs-shr-vec-go__ [v :(Vec any) i :int tab :R7rsIdTab] :nil)
defn

r7rs-mark-shared__

(r7rs-mark-shared__ [x tab :R7rsIdTab] :nil)
defn

r7rs-escape-string__

(r7rs-escape-string__ [s :cstr] :cstr)

a string literal: quoted, with \" \\ \a \b \t \n \r and \xHH; for any other control byte.

defn

r7rs-symbol-plain?__

(r7rs-symbol-plain?__ [s :cstr] :bool)

a symbol whose name reads back as itself without bars: not empty, not ., no delimiter, whitespace, control byte or backslash, not starting with #, and not +i/-i or led by a signed inf./nan.. (Names that read as numbers are the caller's.)

defn

r7rs-bar-symbol__

(r7rs-bar-symbol__ [s :cstr] :cstr)

|name|, with | and \ escaped.

defn

r7rs-symbol-spelling__

(r7rs-symbol-spelling__ [s :cstr] :cstr)
defn

r7rs-char-spelling__

(r7rs-char-spelling__ [n :int] :cstr)

#\a, the R7RS names, or #\xHH for the other control characters.

defn

r7rs-atom-spelling__

(r7rs-atom-spelling__ [x quoted :bool] :cstr)

a value that is not a pair, vector or error object.

defn

r7rs-put-fresh__

(r7rs-put-fresh__ [port s :cstr] :nil)

T8: write a spelling made for this write, then free it (port-put copies the bytes).

defn

r7rs-pr-atom__

(r7rs-pr-atom__ [x port quoted :bool] :nil)

an atom's spelling into the port. The spellings made afresh for this write -- a number's, an escaped or re-encoded string -- are freed once written (T8: every printed number leaked its digits); the rest (a literal, a symbol's own name, a cstr string's own bytes) belong to something else and are written as they are.

defn

r7rs-label-put__

(r7rs-label-put__ [port n :int suffix :cstr] :nil)
defn

r7rs-pr__

(r7rs-pr__ [x port quoted :bool tab :R7rsIdTab labels :R7rsIdTab] :nil)

one value. A labelled node prints #n= the first time (numbered in print order) and #n# after.

defn

r7rs-pr-node__

(r7rs-pr-node__ [x port quoted :bool tab :R7rsIdTab labels :R7rsIdTab] :nil)
defn

r7rs-pr-tail__

(r7rs-pr-tail__ [d port quoted :bool tab :R7rsIdTab labels :R7rsIdTab] :nil)

the rest of a list: b c), or . d) for an improper tail or a tail that carries a label.

defn

r7rs-pr-vec__

(r7rs-pr-vec__ [v :(Vec any) i :int port quoted :bool tab :R7rsIdTab labels :R7rsIdTab] :nil)
defn

r7rs-pr-bytes__

(r7rs-pr-bytes__ [v :(Vec int) i :int port] :nil)
defn

r7rs-pr-irritants__

(r7rs-pr-irritants__ [l port tab :R7rsIdTab labels :R7rsIdTab] :nil)
defn

r7rs-print__

(r7rs-print__ [x port quoted :bool mode :int] :nil)

mode 0 labels nothing, 1 labels cycles, 2 labels sharing.

defn

r7rs-out-port-of__

(r7rs-out-port-of__ [r :(Cons any)] :any)
defn

r7rs-display

(r7rs-display [x & r :any] :nil)

(display obj [port]): strings and chars bare, cycles labelled.

defn

r7rs-write

(r7rs-write [x & r :any] :nil)

(write obj [port]): for reading back, cycles labelled.

defn

r7rs-write-shared

(r7rs-write-shared [x & r :any] :nil)

(write-shared obj [port]): every shared node labelled.

defn

r7rs-write-simple

(r7rs-write-simple [x & r :any] :nil)

(write-simple obj [port]): no labels (loops on a cycle).

defn

r7rs-display-irritants__

(r7rs-display-irritants__ [l port] :nil)

internal: irritant for each, written.

defn

r7rs-uncaught__

(r7rs-uncaught__ [obj] :any)

internal: no handler is installed. Report on the current error port the way error objects are conventionally shown and exit 70 (EX_SOFTWARE).