Wraps all core .sx files in R7RS define-library with explicit export lists, plus (import ...) at end for backward-compatible global re-export. Libraries registered: (sx bytecode) — 83 opcode constants (sx render) — 15 tag registries + render helpers (sx signals) — 23 reactive signal primitives (sx r7rs) — 21 R7RS aliases (sx compiler) — 42 compiler functions (sx vm) — 32 VM functions (sx freeze) — 9 freeze/thaw functions (sx content) — 6 content store functions (sx callcc) — 1 call/cc wrapper (sx highlight) — 13 syntax highlighting functions (sx stdlib) — 47 stdlib functions (sx swap) — 13 swap algebra functions (sx render-trace) — 8 render trace functions (sx harness) — 21 test harness functions (sx canonical) — 12 canonical serialization functions (web adapter-html) — 13 HTML renderer functions (web adapter-sx) — 13 SX wire format functions (web engine) — 33 hypermedia engine functions (web request-handler) — 4 request handling functions (web page-helpers) — 12 page helper functions (web router) — 36 routing functions (web deps) — 19 dependency analysis functions (web orchestration) — 59 page orchestration functions Key changes: - define-library now inherits parent env (env-extend env instead of env-extend make-env) so library bodies can access platform primitives - sx_server.ml: added resolve_library_path + load_library_file for import resolution (maps library specs to file paths) - cek_run_with_io: handles "import" locally instead of sending to Python bridge 2608/2608 tests passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
334 lines
7.5 KiB
Plaintext
334 lines
7.5 KiB
Plaintext
;; ==========================================================================
|
|
;; stdlib.sx — Standard library functions
|
|
;;
|
|
;; Every function here is expressed in SX using the irreducible primitive
|
|
;; set. They are library functions — in band, auditable, portable.
|
|
;;
|
|
;; Depends on: evaluator.sx (special forms)
|
|
;; Must load before: render.sx, freeze.sx, types.sx, user code
|
|
;; ==========================================================================
|
|
|
|
|
|
;; Logic + comparison: not, !=, <=, >= stay as primitives.
|
|
;; Replacing them with SX lambdas changes behavior inside shift/reset
|
|
;; because the transpiled evaluator code uses them directly.
|
|
|
|
|
|
(define-library (sx stdlib)
|
|
(export
|
|
eq?
|
|
eqv?
|
|
equal?
|
|
boolean?
|
|
number?
|
|
string?
|
|
list?
|
|
dict?
|
|
continuation?
|
|
zero?
|
|
odd?
|
|
even?
|
|
empty?
|
|
abs
|
|
ceil
|
|
round
|
|
min
|
|
max
|
|
clamp
|
|
first
|
|
last
|
|
rest
|
|
nth
|
|
cons
|
|
append
|
|
reverse
|
|
flatten
|
|
range
|
|
chunk-every
|
|
zip-pairs
|
|
vals
|
|
has-key?
|
|
assoc
|
|
dissoc
|
|
into
|
|
upcase
|
|
downcase
|
|
string-length
|
|
substring
|
|
string-contains?
|
|
starts-with?
|
|
ends-with?
|
|
contains?
|
|
pluralize
|
|
escape
|
|
parse-datetime
|
|
assert)
|
|
(begin
|
|
|
|
(define eq? (fn (a b) (= a b)))
|
|
(define eqv? (fn (a b) (= a b)))
|
|
(define equal? (fn (a b) (= a b)))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Type predicates
|
|
;; --------------------------------------------------------------------------
|
|
|
|
;; nil? stays as primitive — host's type-of uses it internally.
|
|
|
|
(define boolean?
|
|
(fn (x) (= (type-of x) "boolean")))
|
|
|
|
(define number?
|
|
(fn (x) (= (type-of x) "number")))
|
|
|
|
(define string?
|
|
(fn (x) (= (type-of x) "string")))
|
|
|
|
(define list?
|
|
(fn (x) (= (type-of x) "list")))
|
|
|
|
(define dict?
|
|
(fn (x) (= (type-of x) "dict")))
|
|
|
|
(define continuation?
|
|
(fn (x) (= (type-of x) "continuation")))
|
|
|
|
(define zero?
|
|
(fn (n) (= n 0)))
|
|
|
|
(define odd?
|
|
(fn (n) (= (mod n 2) 1)))
|
|
|
|
(define even?
|
|
(fn (n) (= (mod n 2) 0)))
|
|
|
|
(define empty?
|
|
(fn (coll) (or (nil? coll) (= (len coll) 0))))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Arithmetic
|
|
;; --------------------------------------------------------------------------
|
|
|
|
;; inc and dec stay as primitives — used inside continuation contexts.
|
|
|
|
(define abs
|
|
(fn (x) (if (< x 0) (- x) x)))
|
|
|
|
(define ceil
|
|
(fn (x)
|
|
(let ((f (floor x)))
|
|
(if (= x f) f (+ f 1)))))
|
|
|
|
(define round
|
|
(fn (x ndigits)
|
|
(if (nil? ndigits)
|
|
(floor (+ x 0.5))
|
|
(let ((f (pow 10 ndigits)))
|
|
(/ (floor (+ (* x f) 0.5)) f)))))
|
|
|
|
(define min
|
|
(fn (a b) (if (< a b) a b)))
|
|
|
|
(define max
|
|
(fn (a b) (if (> a b) a b)))
|
|
|
|
(define clamp
|
|
(fn (x lo hi) (max lo (min hi x))))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Collection accessors
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define first
|
|
(fn (coll)
|
|
(if (and coll (> (len coll) 0)) (get coll 0) nil)))
|
|
|
|
(define last
|
|
(fn (coll)
|
|
(if (and coll (> (len coll) 0))
|
|
(get coll (- (len coll) 1))
|
|
nil)))
|
|
|
|
(define rest
|
|
(fn (coll) (if coll (slice coll 1) (list))))
|
|
|
|
(define nth
|
|
(fn (coll n)
|
|
(if (and coll (>= n 0) (< n (len coll)))
|
|
(get coll n)
|
|
nil)))
|
|
|
|
(define cons
|
|
(fn (x coll) (concat (list x) (or coll (list)))))
|
|
|
|
(define append
|
|
(fn (coll x)
|
|
(if (list? x) (concat coll x) (concat coll (list x)))))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Collection transforms
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define reverse
|
|
(fn (coll)
|
|
(reduce (fn (acc x) (cons x acc)) (list) coll)))
|
|
|
|
(define flatten
|
|
(fn (coll)
|
|
(reduce
|
|
(fn (acc x)
|
|
(if (list? x) (concat acc x) (concat acc (list x))))
|
|
(list) coll)))
|
|
|
|
(define range
|
|
(fn (start end step)
|
|
(let ((s (if (nil? step) 1 step))
|
|
(result (list)))
|
|
(let loop ((i start))
|
|
(when (< i end)
|
|
(append! result i)
|
|
(loop (+ i s))))
|
|
result)))
|
|
|
|
(define chunk-every
|
|
(fn (coll n)
|
|
(let ((result (list))
|
|
(clen (len coll)))
|
|
(let loop ((i 0))
|
|
(when (< i clen)
|
|
(append! result (slice coll i (min (+ i n) clen)))
|
|
(loop (+ i n))))
|
|
result)))
|
|
|
|
(define zip-pairs
|
|
(fn (coll)
|
|
(let ((result (list))
|
|
(clen (len coll)))
|
|
(let loop ((i 0))
|
|
(when (< i (- clen 1))
|
|
(append! result (list (get coll i) (get coll (+ i 1))))
|
|
(loop (+ i 1))))
|
|
result)))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Dict operations
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define vals
|
|
(fn (d)
|
|
(map (fn (k) (get d k)) (keys d))))
|
|
|
|
(define has-key?
|
|
(fn (d key)
|
|
(some (fn (k) (= k key)) (keys d))))
|
|
|
|
(define assoc
|
|
(fn (d key val)
|
|
(let ((result (merge d (dict))))
|
|
(dict-set! result key val)
|
|
result)))
|
|
|
|
(define dissoc
|
|
(fn (d key)
|
|
(let ((result (dict)))
|
|
(for-each
|
|
(fn (k)
|
|
(when (!= k key)
|
|
(dict-set! result k (get d k))))
|
|
(keys d))
|
|
result)))
|
|
|
|
(define into
|
|
(fn (target coll)
|
|
(cond
|
|
(list? target)
|
|
(if (list? coll)
|
|
(concat coll (list))
|
|
(let ((result (list)))
|
|
(for-each (fn (k) (append! result (list k (get coll k)))) (keys coll))
|
|
result))
|
|
(dict? target)
|
|
(let ((result (dict)))
|
|
(for-each
|
|
(fn (pair)
|
|
(when (and (list? pair) (>= (len pair) 2))
|
|
(dict-set! result (get pair 0) (get pair 1))))
|
|
coll)
|
|
result)
|
|
:else target)))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; String operations
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define upcase (fn (s) (upper s)))
|
|
(define downcase (fn (s) (lower s)))
|
|
(define string-length (fn (s) (len s)))
|
|
(define substring (fn (s start end) (slice s start end)))
|
|
|
|
(define string-contains?
|
|
(fn (s needle) (!= (index-of s needle) -1)))
|
|
|
|
(define starts-with?
|
|
(fn (s prefix) (= (index-of s prefix) 0)))
|
|
|
|
(define ends-with?
|
|
(fn (s suffix)
|
|
(let ((slen (len s))
|
|
(plen (len suffix)))
|
|
(if (< slen plen) false
|
|
(= (slice s (- slen plen)) suffix)))))
|
|
|
|
;; split, join, replace stay as primitives — the stdlib versions cause
|
|
;; stack overflows due to PRIMITIVES entry shadowing in the transpiled output.
|
|
|
|
(define contains?
|
|
(fn (coll key)
|
|
(cond
|
|
(string? coll) (!= (index-of coll (str key)) -1)
|
|
(dict? coll) (has-key? coll key)
|
|
(list? coll) (some (fn (x) (= x key)) coll)
|
|
:else false)))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; Text utilities
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(define pluralize
|
|
(fn (count singular plural)
|
|
(if (= count 1)
|
|
(or singular "")
|
|
(or plural "s"))))
|
|
|
|
(define escape
|
|
(fn (s)
|
|
(let ((r (str s)))
|
|
(set! r (replace r "&" "&"))
|
|
(set! r (replace r "<" "<"))
|
|
(set! r (replace r ">" ">"))
|
|
(set! r (replace r "\"" """))
|
|
(set! r (replace r "'" "'"))
|
|
r)))
|
|
|
|
(define parse-datetime
|
|
(fn (s) (if s (str s) nil)))
|
|
|
|
(define assert
|
|
(fn (condition message)
|
|
(when (not condition)
|
|
(error (or message "Assertion failed")))
|
|
true))
|
|
|
|
|
|
)) ;; end define-library
|
|
|
|
;; Re-export to global namespace for backward compatibility
|
|
(import (sx stdlib))
|