Migrate 175 .sls -> .ss across lib/{std,jerboa}
ober
e0d98b5ebee7f652889d4ad5550f24dc7f844b15
deleted file mode 100644 --- a/lib/jerboa/cache.sls +++ /dev/null @@ -1,146 +0,0 @@ -#!chezscheme -;;; (jerboa cache) — Content-addressed compilation cache -;;; -;;; Hashes source + dependencies + Chez version to produce cache keys. -;;; Avoids recompilation when inputs haven't changed. -;;; -;;; Cache layout: -;;; ~/.jerboa/cache/<sha256>.so -;;; -;;; Cache key = SHA-256(source-content || dep-hash-1 || ... || chez-version || opt-level) - -(library (jerboa cache) - (export - cache-directory - cache-lookup - cache-store! - cache-key - with-compilation-cache - cache-stats - cache-clear!) - (import (chezscheme)) - - ;; ========== Configuration ========== - - (define cache-directory - (make-parameter - (let ([home (getenv "HOME")]) - (if home - (string-append home "/.jerboa/cache") - "/tmp/jerboa-cache")))) - - ;; ========== Hashing ========== - - ;; Simple string hash using Chez's built-in (not cryptographic, but fast) - ;; For production, this should use SHA-256 from chez-crypto - ;; FNV-1a hash producing a 128-bit hex string for cache keys - (define (string-hash-256 str) - (let ([len (string-length str)]) - (let loop ([i 0] [h1 14695981039346656037] [h2 6364136223846793005]) - (if (= i len) - (string-append - (number->string (mod (abs h1) (expt 2 64)) 16) - (number->string (mod (abs h2) (expt 2 64)) 16)) - (let ([byte (char->integer (string-ref str i))]) - (loop (+ i 1) - (mod (* (bitwise-xor h1 byte) 1099511628211) (expt 2 64)) - (mod (* (bitwise-xor h2 (+ byte 37)) 6364136223846793005) (expt 2 64)))))))) - - ;; Compute cache key from source file and its dependencies - (define (cache-key source-path dep-hashes opt-level) - (let* ([source-content (call-with-port (open-input-file source-path) - (lambda (p) - (get-string-all p)))] - [chez-ver (scheme-version)] - [key-material (apply string-append - source-content - (number->string opt-level) - chez-ver - (map (lambda (h) (or h "")) dep-hashes))]) - (string-hash-256 key-material))) - - ;; ========== Cache Operations ========== - - (define (ensure-cache-dir!) - (let ([dir (cache-directory)]) - (unless (file-exists? dir) - (mkdir-p dir)))) - - (define (cache-path key) - (string-append (cache-directory) "/" key ".so")) - - ;; Look up a cached .so by its key - ;; Returns the path if found, #f if not - (define (cache-lookup key) - (let ([path (cache-path key)]) - (if (file-exists? path) path #f))) - - ;; Store a compiled .so file in the cache - (define (cache-store! key so-path) - (ensure-cache-dir!) - (let ([dest (cache-path key)]) - (unless (file-exists? dest) - ;; Copy the file - (let ([data (call-with-port (open-file-input-port so-path) - (lambda (p) (get-bytevector-all p)))]) - (call-with-port (open-file-output-port dest) - (lambda (p) (put-bytevector p data))))))) - - ;; ========== High-Level API ========== - - ;; Compile a file with caching - ;; Returns the .so path (from cache or freshly compiled) - (define (with-compilation-cache source-path output-path dep-hashes opt-level compile-thunk) - (let* ([key (cache-key source-path dep-hashes opt-level)] - [cached (cache-lookup key)]) - (if cached - ;; Cache hit — copy to output - (begin - (let ([data (call-with-port (open-file-input-port cached) - (lambda (p) (get-bytevector-all p)))]) - (call-with-port (open-file-output-port output-path - (file-options no-fail)) - (lambda (p) (put-bytevector p data)))) - output-path) - ;; Cache miss — compile and store - (begin - (compile-thunk) - (when (file-exists? output-path) - (cache-store! key output-path)) - output-path)))) - - ;; ========== Maintenance ========== - - (define (cache-stats) - (let ([dir (cache-directory)]) - (if (file-exists? dir) - (let ([files (directory-list dir)]) - (let ([count (length files)] - [size (fold-left - (lambda (acc f) - (let* ([path (string-append dir "/" f)] - [fsize (call-with-port (open-file-input-port path) - (lambda (p) - (set-port-position! p (+ (port-position p) 0)) - (let ([data (get-bytevector-all p)]) - (if (eof-object? data) 0 - (bytevector-length data)))))]) - (+ acc fsize))) - 0 files)]) - (values count size))) - (values 0 0)))) - - (define (cache-clear!) - (let ([dir (cache-directory)]) - (when (file-exists? dir) - (for-each - (lambda (f) - (delete-file (string-append dir "/" f))) - (directory-list dir))))) - - ;; Create ~/.jerboa/cache directory tree - (define (mkdir-p path) - ;; Use system mkdir -p since Chez doesn't have recursive mkdir - (system (format "mkdir -p '~a'" path))) - - ) ;; end library new file mode 100644 --- /dev/null +++ b/lib/jerboa/cache.ss @@ -0,0 +1,147 @@ +#!chezscheme +;;; (jerboa cache) — Content-addressed compilation cache +;;; +;;; Hashes source + dependencies + Chez version to produce cache keys. +;;; Avoids recompilation when inputs haven't changed. +;;; +;;; Cache layout: +;;; ~/.jerboa/cache/<sha256>.so +;;; +;;; Cache key = SHA-256(source-content || dep-hash-1 || ... || chez-version || opt-level) + +(library (jerboa cache) + (export + cache-directory + cache-lookup + cache-store! + cache-key + with-compilation-cache + cache-stats + cache-clear!) + (import (chezscheme) + (only (jerboa core) def)) + + ;; ========== Configuration ========== + + (def cache-directory + (make-parameter + (let ([home (getenv "HOME")]) + (if home + (string-append home "/.jerboa/cache") + "/tmp/jerboa-cache")))) + + ;; ========== Hashing ========== + + ;; Simple string hash using Chez's built-in (not cryptographic, but fast) + ;; For production, this should use SHA-256 from chez-crypto + ;; FNV-1a hash producing a 128-bit hex string for cache keys + (def (string-hash-256 str) + (let ([len (string-length str)]) + (let loop ([i 0] [h1 14695981039346656037] [h2 6364136223846793005]) + (if (= i len) + (string-append + (number->string (mod (abs h1) (expt 2 64)) 16) + (number->string (mod (abs h2) (expt 2 64)) 16)) + (let ([byte (char->integer (string-ref str i))]) + (loop (+ i 1) + (mod (* (bitwise-xor h1 byte) 1099511628211) (expt 2 64)) + (mod (* (bitwise-xor h2 (+ byte 37)) 6364136223846793005) (expt 2 64)))))))) + + ;; Compute cache key from source file and its dependencies + (def (cache-key source-path dep-hashes opt-level) + (let* ([source-content (call-with-port (open-input-file source-path) + (lambda (p) + (get-string-all p)))] + [chez-ver (scheme-version)] + [key-material (apply string-append + source-content + (number->string opt-level) + chez-ver + (map (lambda (h) (or h "")) dep-hashes))]) + (string-hash-256 key-material))) + + ;; ========== Cache Operations ========== + + (def (ensure-cache-dir!) + (let ([dir (cache-directory)]) + (unless (file-exists? dir) + (mkdir-p dir)))) + + (def (cache-path key) + (string-append (cache-directory) "/" key ".so")) + + ;; Look up a cached .so by its key + ;; Returns the path if found, #f if not + (def (cache-lookup key) + (let ([path (cache-path key)]) + (if (file-exists? path) path #f))) + + ;; Store a compiled .so file in the cache + (def (cache-store! key so-path) + (ensure-cache-dir!) + (let ([dest (cache-path key)]) + (unless (file-exists? dest) + ;; Copy the file + (let ([data (call-with-port (open-file-input-port so-path) + (lambda (p) (get-bytevector-all p)))]) + (call-with-port (open-file-output-port dest) + (lambda (p) (put-bytevector p data))))))) + + ;; ========== High-Level API ========== + + ;; Compile a file with caching + ;; Returns the .so path (from cache or freshly compiled) + (def (with-compilation-cache source-path output-path dep-hashes opt-level compile-thunk) + (let* ([key (cache-key source-path dep-hashes opt-level)] + [cached (cache-lookup key)]) + (if cached + ;; Cache hit — copy to output + (begin + (let ([data (call-with-port (open-file-input-port cached) + (lambda (p) (get-bytevector-all p)))]) + (call-with-port (open-file-output-port output-path + (file-options no-fail)) + (lambda (p) (put-bytevector p data)))) + output-path) + ;; Cache miss — compile and store + (begin + (compile-thunk) + (when (file-exists? output-path) + (cache-store! key output-path)) + output-path)))) + + ;; ========== Maintenance ========== + + (def (cache-stats) + (let ([dir (cache-directory)]) + (if (file-exists? dir) + (let ([files (directory-list dir)]) + (let ([count (length files)] + [size (fold-left + (lambda (acc f) + (let* ([path (string-append dir "/" f)] + [fsize (call-with-port (open-file-input-port path) + (lambda (p) + (set-port-position! p (+ (port-position p) 0)) + (let ([data (get-bytevector-all p)]) + (if (eof-object? data) 0 + (bytevector-length data)))))]) + (+ acc fsize))) + 0 files)]) + (values count size))) + (values 0 0)))) + + (def (cache-clear!) + (let ([dir (cache-directory)]) + (when (file-exists? dir) + (for-each + (lambda (f) + (delete-file (string-append dir "/" f))) + (directory-list dir))))) + + ;; Create ~/.jerboa/cache directory tree + (def (mkdir-p path) + ;; Use system mkdir -p since Chez doesn't have recursive mkdir + (system (format "mkdir -p '~a'" path))) + + ) ;; end library deleted file mode 100644 --- a/lib/jerboa/cloj.sls +++ /dev/null @@ -1,97 +0,0 @@ -#!chezscheme -;;; jerboa/cloj.sls — Clojure reader mode support -;;; -;;; Provides: -;;; reader-cloj-mode — parameter: activates Clojure syntax in the Jerboa reader -;;; fn-literal — macro: expands #(...) anonymous function reader literals -;;; -;;; The Jerboa reader expands #(+ % 1) to (fn-literal + % 1) when cloj mode -;;; is active. fn-literal walks the body, detects % / %1 / %2 / %& references, -;;; and emits the appropriate (lambda ...) form. -;;; -;;; Activation: add #!cloj at the top of any Jerboa source file, or call -;;; (reader-cloj-mode #t) programmatically. - -(library (jerboa cloj) - (export reader-cloj-mode fn-literal activate-cloj-reader!) - - (import (chezscheme) - (only (jerboa reader) reader-cloj-mode)) - - ;;; activate-cloj-reader! — call from library bodies to enable cloj mode - ;; Wraps (reader-cloj-mode #t) so that libraries with restricted import - ;; environments can activate cloj mode with a single function call. - (define (activate-cloj-reader!) (reader-cloj-mode #t)) - - ;;; fn-literal — expands #(...) anonymous function literals - ;; - ;; #(+ % 1) → (lambda (%1) (+ %1 1)) - ;; #(str %1 " " %2) → (lambda (%1 %2) (str %1 " " %2)) - ;; #(apply + %&) → (lambda %& (apply + %&)) - ;; #(begin (f %) %) → (lambda (%1) (begin (f %1) %1)) - ;; - ;; % is an alias for %1. %2, %3, etc. for more positional args. - ;; %& collects all extra args as a rest list. - - (define-syntax fn-literal - (lambda (stx) - - ;; Replace bare % with %1 throughout a datum tree - (define (normalize d) - (cond - ((eq? d '%) '%1) - ((pair? d) (cons (normalize (car d)) (normalize (cdr d)))) - (else d))) - - ;; Walk datum, return (max-positional-n . has-rest?) - ;; Recognises: %1 %2 %3 ... (and %) %& - (define (find-info d) - (let loop ((d d) (n 0) (r? #f)) - (cond - ((null? d) (cons n r?)) - ((eq? d '%&) (cons n #t)) - ((symbol? d) - (let* ((s (symbol->string d)) - (len (string-length s))) - (if (and (> len 1) (char=? (string-ref s 0) #\%)) - (let ((num (string->number (substring s 1 len)))) - (if num (cons (max n num) r?) (cons n r?))) - (cons n r?)))) - ((pair? d) - (let ((r1 (loop (car d) n r?))) - (loop (cdr d) (car r1) (cdr r1)))) - (else (cons n r?))))) - - ;; Build list (1 2 ... n) - (define (range-1-to n) - (let lp ((i n) (acc '())) - (if (= i 0) acc (lp (- i 1) (cons i acc))))) - - (syntax-case stx () - ((kw body-form ...) - (let* ((raw (syntax->datum #'(body-form ...))) - (nb (normalize raw)) - ;; If there's exactly one form, use it directly; else wrap in begin - (body (if (and (pair? nb) (null? (cdr nb))) - (car nb) - (cons 'begin nb))) - (info (find-info body)) - (max-n (car info)) - (rest? (cdr info)) - (positional (map (lambda (i) - (string->symbol - (string-append "%" (number->string i)))) - (range-1-to max-n))) - ;; arg-list: - ;; no args + rest → %& (variadic bare symbol) - ;; no args, no rest → () (nullary) - ;; args + rest → (%1 %2 . %&) (dotted list via append) - ;; args, no rest → (%1 %2 ...) - (arg-list (cond - ((and (null? positional) rest?) '%&) - ((null? positional) '()) - (rest? (append positional '%&)) ;; (append list sym) = dotted - (else positional)))) - (datum->syntax #'kw `(lambda ,arg-list ,body))))))) - - ) ;; end library new file mode 100644 --- /dev/null +++ b/lib/jerboa/cloj.ss @@ -0,0 +1,98 @@ +#!chezscheme +;;; jerboa/cloj.sls — Clojure reader mode support +;;; +;;; Provides: +;;; reader-cloj-mode — parameter: activates Clojure syntax in the Jerboa reader +;;; fn-literal — macro: expands #(...) anonymous function reader literals +;;; +;;; The Jerboa reader expands #(+ % 1) to (fn-literal + % 1) when cloj mode +;;; is active. fn-literal walks the body, detects % / %1 / %2 / %& references, +;;; and emits the appropriate (lambda ...) form. +;;; +;;; Activation: add #!cloj at the top of any Jerboa source file, or call +;;; (reader-cloj-mode #t) programmatically. + +(library (jerboa cloj) + (export reader-cloj-mode fn-literal activate-cloj-reader!) + + (import (chezscheme) + (only (jerboa reader) reader-cloj-mode) + (only (jerboa core) def)) + + ;;; activate-cloj-reader! — call from library bodies to enable cloj mode + ;; Wraps (reader-cloj-mode #t) so that libraries with restricted import + ;; environments can activate cloj mode with a single function call. + (def (activate-cloj-reader!) (reader-cloj-mode #t)) + + ;;; fn-literal — expands #(...) anonymous function literals + ;; + ;; #(+ % 1) → (lambda (%1) (+ %1 1)) + ;; #(str %1 " " %2) → (lambda (%1 %2) (str %1 " " %2)) + ;; #(apply + %&) → (lambda %& (apply + %&)) + ;; #(begin (f %) %) → (lambda (%1) (begin (f %1) %1)) + ;; + ;; % is an alias for %1. %2, %3, etc. for more positional args. + ;; %& collects all extra args as a rest list. + + (define-syntax fn-literal + (lambda (stx) + + ;; Replace bare % with %1 throughout a datum tree + (define (normalize d) + (cond + ((eq? d '%) '%1) + ((pair? d) (cons (normalize (car d)) (normalize (cdr d)))) + (else d))) + + ;; Walk datum, return (max-positional-n . has-rest?) + ;; Recognises: %1 %2 %3 ... (and %) %& + (define (find-info d) + (let loop ((d d) (n 0) (r? #f)) + (cond + ((null? d) (cons n r?)) + ((eq? d '%&) (cons n #t)) + ((symbol? d) + (let* ((s (symbol->string d)) + (len (string-length s))) + (if (and (> len 1) (char=? (string-ref s 0) #\%)) + (let ((num (string->number (substring s 1 len)))) + (if num (cons (max n num) r?) (cons n r?))) + (cons n r?)))) + ((pair? d) + (let ((r1 (loop (car d) n r?))) + (loop (cdr d) (car r1) (cdr r1)))) + (else (cons n r?))))) + + ;; Build list (1 2 ... n) + (define (range-1-to n) + (let lp ((i n) (acc '())) + (if (= i 0) acc (lp (- i 1) (cons i acc))))) + + (syntax-case stx () + ((kw body-form ...) + (let* ((raw (syntax->datum #'(body-form ...))) + (nb (normalize raw)) + ;; If there's exactly one form, use it directly; else wrap in begin + (body (if (and (pair? nb) (null? (cdr nb))) + (car nb) + (cons 'begin nb))) + (info (find-info body)) + (max-n (car info)) + (rest? (cdr info)) + (positional (map (lambda (i) + (string->symbol + (string-append "%" (number->string i)))) + (range-1-to max-n))) + ;; arg-list: + ;; no args + rest → %& (variadic bare symbol) + ;; no args, no rest → () (nullary) + ;; args + rest → (%1 %2 . %&) (dotted list via append) + ;; args, no rest → (%1 %2 ...) + (arg-list (cond + ((and (null? positional) rest?) '%&) + ((null? positional) '()) + (rest? (append positional '%&)) ;; (append list sym) = dotted + (else positional)))) + (datum->syntax #'kw `(lambda ,arg-list ,body))))))) + + ) ;; end library deleted file mode 100644 --- a/lib/jerboa/prelude.sls +++ /dev/null @@ -1,350 +0,0 @@ -#!chezscheme -;;; jerboa/prelude -- One-import-to-rule-them-all -;;; -;;; (import (jerboa prelude)) gives you the full Jerboa API: -;;; - Core macros: def, defstruct, defmethod, match, try/catch, etc. -;;; - Runtime: hash tables, method dispatch, keywords -;;; - Standard library: sort, format, JSON, paths, strings, lists, etc. -;;; - Advanced: result types, datetime, iterators, CSV, pretty-printer -;;; - Ergonomic typing: using, :, maybe -;;; - FFI: c-lambda, define-c-lambda - -(library (jerboa prelude) - (export - ;; ---- Core macros ---- - def def* defrule defrules - defstruct defclass defmethod - match match/strict - define-match-type define-sealed-hierarchy define-active-pattern - try catch finally - while until - - ;; hash constructors - hash-literal hash-eq-literal - let-hash - - ;; ---- Runtime ---- - ~ bind-method! call-method - make-hash-table make-hash-table-eq - hash-ref hash-get hash-put! hash-update! hash-remove! - hash-key? hash->list hash->plist hash-for-each hash-map hash-fold - hash-find hash-keys hash-values hash-copy hash-clear! - hash-merge hash-merge! hash-length hash-table? - list->hash-table plist->hash-table - hash-set - keyword? keyword->string string->keyword make-keyword - error-message error-irritants error-trace - displayln 1+ 1- - iota last-pair - *method-tables* - register-struct-type! *struct-types* - struct-predicate struct-field-ref struct-field-set! - struct-type-info - - ;; ---- std/sort ---- - sort sort! stable-sort stable-sort! - - ;; ---- std/format ---- - format printf fprintf eprintf - - ;; ---- std/error ---- - Error ContractViolation - - ;; ---- std/sugar ---- - chain chain-and assert! - unwind-protect with-id with-lock with-catch - cut cute <> <...> - awhen aif when-let if-let - -> ->> as-> some-> some->> cond-> cond->> - ->? ->>? - with-resource str alist defn defrecord - let-alist define-enum capture dotimes define-values - - ;; ---- std/text/json ---- - read-json write-json json-object->string string->json-object - - ;; ---- std/os/platform ---- - cpu-count - - ;; ---- std/os/path ---- - path-expand path-normalize path-directory path-strip-directory - path-extension path-strip-extension - path-join path-absolute? - - ;; ---- std/regex ---- - re re? - re-match? re-search - re-find-all re-groups - re-replace re-replace-all - re-split re-fold - re-match-full re-match-group re-match-groups - re-match-start re-match-end re-match-named - - ;; ---- std/rx ---- - rx define-rx - - ;; ---- std/misc/string ---- - string-split string-join string-trim - string-prefix? string-suffix? - string-contains string-index - string-empty? - string-match? string-find string-find-all - - ;; ---- std/misc/list ---- - flatten unique snoc - take drop - every any - filter-map - group-by - zip - frequencies - partition partition-all partition-by - interleave interpose - mapcat - distinct - keep - some - iterate-n - reductions - take-last drop-last - split-at split-with - ;; Gerbil v0.19 compat - append-map append1 flatten1 - push! pop! - for-each! - take-while take-until drop-while drop-until - butlast slice split - length=? length<? length<=? length>? length>=? - length=n? length<n? length<=n? length>n? length>=n? - group-consecutive group-n-consecutive group-same - rassoc every-consecutive? - map/car first-and-only when/list - with-list-builder call-with-list-builder - duplicates delete-duplicates/hash - - ;; ---- std/misc/alist ---- - agetq agetv aget - asetq! asetv! aset! - pgetq pgetv pget - alist->hash-table - ;; Gerbil v0.19 compat - alist? acons - asetq asetv aset - aremq aremv arem - aremq! aremv! arem! - psetq psetv pset - psetq! psetv! pset! - premq premv prem - premq! premv! prem! - plist->alist* alist->plist* - - ;; ---- std/misc/ports ---- - read-all-as-string read-all-as-lines - read-file-string read-file-lines - write-file-string - with-input-from-string with-output-to-string - - ;; ---- std/misc/func ---- - compose compose1 identity constantly flip - curry curryn negate conjoin disjoin - memo-proc juxt - partial complement comp - fnil every-pred some-fn - - ;; ---- std/iter ---- - for for/collect for/fold for/or for/and - in-list in-vector in-range in-string - in-hash-keys in-hash-values in-hash-pairs - in-naturals in-indexed - in-port in-lines in-chars in-bytes in-producer - - ;; ---- std/result ---- - ok err - ok? err? result? - unwrap unwrap-err unwrap-or unwrap-or-else - map-ok map-err - and-then or-else - flatten-result - result->values - try-result try-result* - result->option - results-partition - map-results - filter-ok filter-err - sequence-results - ok->list err->list - - ;; ---- std/datetime ---- - make-datetime datetime? - make-date make-time - datetime-now datetime-utc-now - datetime-year datetime-month datetime-day - datetime-hour datetime-minute datetime-second - datetime-nanosecond datetime-offset - parse-datetime parse-date parse-time - datetime->string date->string time->string - datetime->iso8601 - datetime->epoch epoch->datetime - datetime->julian julian->datetime - datetime-add datetime-subtract - datetime-diff - duration duration? duration-seconds duration-nanoseconds - make-duration - datetime<? datetime>? datetime=? datetime<=? datetime>=? - datetime-min datetime-max datetime-clamp - day-of-week day-of-year days-in-month leap-year? - datetime->alist - datetime-truncate - datetime-floor-hour datetime-floor-day datetime-floor-month - - ;; ---- std/debug/pp ---- - pp pp-to-string pprint - ppd ppd-to-string - - ;; ---- std/csv ---- - read-csv read-csv-file csv-port->rows - write-csv write-csv-file rows->csv-string - csv->alists alists->csv - - ;; ---- FFI ---- - c-lambda define-c-lambda - begin-ffi c-declare - - ;; ---- std/ergo ---- - using : maybe list-of? - - ;; ---- std/misc/atom (Gerbil atom + Clojure aliases) ---- - ;; Gerbil-style: - atom atom? atom-deref atom-reset! atom-swap! atom-update! - ;; Clojure-style aliases (familiar to clojure users) - deref reset! swap! compare-and-set! - ;; Watches (fires on every successful swap/reset/update/CAS) - add-watch! remove-watch! - ;; Volatiles (single-threaded transient cells for transducers) - volatile! volatile? vreset! vswap! vderef - - ;; ---- std/misc/meta (Clojure-style metadata wrappers) ---- - with-meta meta vary-meta meta-wrapped? strip-meta - - ;; ---- std/misc/shared (atomic cell with CAS) ---- - make-shared shared? shared-ref shared-set! - shared-update! shared-cas! shared-swap! - - ;; ---- std/misc/nested (Clojure-style nested access) ---- - ;; get-in is polymorphic (imap/chash/hash/vector/alist); - ;; assoc-in / update-in are pure (imap only) and return new containers; - ;; assoc-in! / update-in! mutate chash/hash/vector in place. - get-in assoc-in update-in assoc-in! update-in! - nested-get nested-empty-like - - ;; ---- Timing helpers ---- - sleep-ms - - ;; ---- AI compatibility aliases ---- - ;; Common names LLMs hallucinate from Racket/Gerbil/Gambit/CL training data. - ;; These are thin aliases so AI-generated code works on the first try. - hash-has-key? hash-table-set! ;; Racket - directory-exists? ;; Gambit - eql? ;; Common Lisp - random-integer ;; Gambit - read-line ;; Gambit - force-output ;; Gambit - string-map ;; Racket/R7RS - processor-count ;; Racket - ;; Regex aliases (common generic names from Python, Ruby, JS training data) - regex-match regex-search regex-replace regex-replace-all) - - (import - (except (chezscheme) - make-hash-table hash-table? - sort sort! - printf fprintf - path-extension path-absolute? - with-input-from-string with-output-to-string - iota 1+ 1- - partition - make-date make-time - atom? - meta) - (only (jerboa core) - def def* defrule defrules - defstruct defclass defmethod - try catch finally - while until - hash-literal hash-eq-literal - let-hash) - (only (std match2) - match match/strict - define-match-type define-sealed-hierarchy define-active-pattern) - (jerboa runtime) - (jerboa ffi) - (std sort) - (std format) - (except (std error) error-message error-irritants error-trace error? - with-exception-handler) - (except (std sugar) try catch finally) - (std text json) - (only (std os platform) platform-cpu-count) - (std os path) - (std regex) - (std rx) - (std misc string) - (std misc list) - (std misc alist) - (std misc ports) - (std misc func) - (std iter) - (std result) - (std datetime) - (std debug pp) - (std csv) - (std ergo) - (std misc atom) - (std misc meta) - (std misc shared) - (std misc nested) - ;; Private access to Chez's make-time (shadowed above) so we can - ;; build a time-duration record for the sleep-ms wrapper. - (rename (only (chezscheme) make-time) - (make-time %chez-make-time))) - - ;; ---- System ---- - (define cpu-count platform-cpu-count) - (define processor-count platform-cpu-count) ;; Racket name - - ;; ---- AI compatibility aliases ---- - (define hash-has-key? hash-key?) - (define hash-table-set! hash-put!) - (define directory-exists? file-directory?) - (define eql? eqv?) - (define random-integer random) - (define (read-line . args) - (if (null? args) - (get-line (current-input-port)) - (get-line (car args)))) - (define (force-output . args) - (flush-output-port - (if (null? args) (current-output-port) (car args)))) - (define (string-map f s) - (list->string (map f (string->list s)))) - - ;; ---- Regex AI compatibility aliases ---- - ;; LLMs trained on Python/Ruby/JavaScript commonly use these generic names. - (define (regex-match pat str) (re-search pat str)) - (define (regex-search pat str) (re-search pat str)) - (define (regex-replace pat str rep) (re-replace pat str rep)) - (define (regex-replace-all pat str rep) (re-replace-all pat str rep)) - - ;; ---- Timing helpers ---- - ;; (sleep-ms ms) sleeps for MS milliseconds. Wraps Chez's - ;; `(sleep (make-time 'time-duration ns sec))` so users never have - ;; to reach for `make-time` (which the prelude shadows with a - ;; date-style constructor). MS must be a non-negative integer. - (define (sleep-ms ms) - (unless (and (integer? ms) (>= ms 0)) - (error 'sleep-ms "ms must be a non-negative integer" ms)) - (let ([sec (quotient ms 1000)] - [ns (* (remainder ms 1000) 1000000)]) - (sleep (%chez-make-time 'time-duration ns sec)))) - - ) ;; end library new file mode 100644 --- /dev/null +++ b/lib/jerboa/prelude.ss @@ -0,0 +1,351 @@ +#!chezscheme +;;; jerboa/prelude -- One-import-to-rule-them-all +;;; +;;; (import (jerboa prelude) +;;; (only (jerboa core) def)) gives you the full Jerboa API: +;;; - Core macros: def, defstruct, defmethod, match, try/catch, etc. +;;; - Runtime: hash tables, method dispatch, keywords +;;; - Standard library: sort, format, JSON, paths, strings, lists, etc. +;;; - Advanced: result types, datetime, iterators, CSV, pretty-printer +;;; - Ergonomic typing: using, :, maybe +;;; - FFI: c-lambda, define-c-lambda + +(library (jerboa prelude) + (export + ;; ---- Core macros ---- + def def* defrule defrules + defstruct defclass defmethod + match match/strict + define-match-type define-sealed-hierarchy define-active-pattern + try catch finally + while until + + ;; hash constructors + hash-literal hash-eq-literal + let-hash + + ;; ---- Runtime ---- + ~ bind-method! call-method + make-hash-table make-hash-table-eq + hash-ref hash-get hash-put! hash-update! hash-remove! + hash-key? hash->list hash->plist hash-for-each hash-map hash-fold + hash-find hash-keys hash-values hash-copy hash-clear! + hash-merge hash-merge! hash-length hash-table? + list->hash-table plist->hash-table + hash-set + keyword? keyword->string string->keyword make-keyword + error-message error-irritants error-trace + displayln 1+ 1- + iota last-pair + *method-tables* + register-struct-type! *struct-types* + struct-predicate struct-field-ref struct-field-set! + struct-type-info + + ;; ---- std/sort ---- + sort sort! stable-sort stable-sort! + + ;; ---- std/format ---- + format printf fprintf eprintf + + ;; ---- std/error ---- + Error ContractViolation + + ;; ---- std/sugar ---- + chain chain-and assert! + unwind-protect with-id with-lock with-catch + cut cute <> <...> + awhen aif when-let if-let + -> ->> as-> some-> some->> cond-> cond->> + ->? ->>? + with-resource str alist defn defrecord + let-alist define-enum capture dotimes define-values + + ;; ---- std/text/json ---- + read-json write-json json-object->string string->json-object + + ;; ---- std/os/platform ---- + cpu-count + + ;; ---- std/os/path ---- + path-expand path-normalize path-directory path-strip-directory + path-extension path-strip-extension + path-join path-absolute? + + ;; ---- std/regex ---- + re re? + re-match? re-search + re-find-all re-groups + re-replace re-replace-all + re-split re-fold + re-match-full re-match-group re-match-groups + re-match-start re-match-end re-match-named + + ;; ---- std/rx ---- + rx define-rx + + ;; ---- std/misc/string ---- + string-split string-join string-trim + string-prefix? string-suffix? + string-contains string-index + string-empty? + string-match? string-find string-find-all + + ;; ---- std/misc/list ---- + flatten unique snoc + take drop + every any + filter-map + group-by + zip + frequencies + partition partition-all partition-by + interleave interpose + mapcat + distinct + keep + some + iterate-n + reductions + take-last drop-last + split-at split-with + ;; Gerbil v0.19 compat + append-map append1 flatten1 + push! pop! + for-each! + take-while take-until drop-while drop-until + butlast slice split + length=? length<? length<=? length>? length>=? + length=n? length<n? length<=n? length>n? length>=n? + group-consecutive group-n-consecutive group-same + rassoc every-consecutive? + map/car first-and-only when/list + with-list-builder call-with-list-builder + duplicates delete-duplicates/hash + + ;; ---- std/misc/alist ---- + agetq agetv aget + asetq! asetv! aset! + pgetq pgetv pget + alist->hash-table + ;; Gerbil v0.19 compat + alist? acons + asetq asetv aset + aremq aremv arem + aremq! aremv! arem! + psetq psetv pset + psetq! psetv! pset! + premq premv prem + premq! premv! prem! + plist->alist* alist->plist* + + ;; ---- std/misc/ports ---- + read-all-as-string read-all-as-lines + read-file-string read-file-lines + write-file-string + with-input-from-string with-output-to-string + + ;; ---- std/misc/func ---- + compose compose1 identity constantly flip