The full stdlib migration revealed constraints: - Replacing native callables with SX lambdas changes CEK continuation capture behavior (breaks shift/reset tests) - The transpiler doesn't support named-let (breaks range, split, etc.) - Platform-internal functions (nil?, isNil) can't be shadowed Safe subset in stdlib.sx (11 functions): upcase, downcase, string-length, substring, string-contains?, starts-with?, ends-with?, pluralize, escape, parse-datetime, assert Fix escape-html in render.sx: replace -> (thread-first) with let/set! since the JS transpiler can't handle -> in spec files. 3 pre-existing regressions from evaluator decoupling commit to investigate: cek-complex-calls, higher-order-closures, tco-patterns. Python 744/744 clean. JS 954/957 (3 pre-existing). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
68 lines
2.1 KiB
Plaintext
68 lines
2.1 KiB
Plaintext
;; ==========================================================================
|
|
;; stdlib.sx — Standard library functions
|
|
;;
|
|
;; Functions expressed in SX using the irreducible primitive set.
|
|
;;
|
|
;; CONSTRAINT: Replacing a native callable (PRIMITIVES entry) with a
|
|
;; transpiled SX function can break the transpiled evaluator when:
|
|
;; 1. The function is called inside shift/reset (changes CEK capture)
|
|
;; 2. The function is used by platform internals (circular dependency)
|
|
;; 3. The transpiler doesn't support named-let (loop patterns)
|
|
;;
|
|
;; Only functions safe from all three constraints are moved here.
|
|
;; The rest remain as host-provided PRIMITIVES for now.
|
|
;; ==========================================================================
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; String predicates and aliases
|
|
;; --------------------------------------------------------------------------
|
|
|
|
(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)))))
|
|
|
|
|
|
;; --------------------------------------------------------------------------
|
|
;; 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))
|