R7RS compat library + 45-test suite (27 passing, 17 need lib load fix)

lib/r7rs.sx: guard/with-exception-handler macros, error objects
(make-error-object, error-object?, error-message, error-object-irritants),
R7RS aliases (car/cdr/cadr/null?/pair?/procedure?/boolean=?/symbol->string/
number->string/string->number), string->symbol.

spec/tests/test-r7rs.sx: 9 suites covering call/cc (7), raise (4),
guard (5), with-exception-handler (1), error-objects (4), multi-map (6),
cond=> (4), do-iteration (4), r7rs-aliases (10). 27/44 pass — the 17
failures need r7rs.sx auto-load in the test runner (currently commented
out pending transpiled evaluator hang investigation).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 08:29:57 +00:00
parent 67c4a6a14d
commit d4244b47bf
3 changed files with 263 additions and 0 deletions

63
lib/r7rs.sx Normal file
View File

@@ -0,0 +1,63 @@
(define make-error-object (fn (message irritants) {:irritants irritants :type "error-object" :message message}))
(define
error-object?
(fn (x) (and (dict? x) (= (get x "type") "error-object"))))
(define
error-message
(fn (x) (if (error-object? x) (get x "message") (str x))))
(define
error-object-irritants
(fn (x) (if (error-object? x) (get x "irritants") (list))))
(defmacro
with-exception-handler
(handler thunk)
(quasiquote
(handler-bind (((fn (c) true) (unquote handler))) ((unquote thunk)))))
(defmacro
guard
(var-and-clauses &rest body)
(let
((var (first var-and-clauses)) (clauses (rest var-and-clauses)))
(quasiquote
(handler-bind
(((fn (c) true) (fn ((unquote var)) (cond (splice-unquote clauses) (else (raise (unquote var)))))))
(splice-unquote body)))))
(define car first)
(define cdr rest)
(define cadr (fn (x) (first (rest x))))
(define cddr (fn (x) (rest (rest x))))
(define caar (fn (x) (first (first x))))
(define cdar (fn (x) (rest (first x))))
(define caddr (fn (x) (first (rest (rest x)))))
(define cadddr (fn (x) (first (rest (rest (rest x))))))
(define null? nil?)
(define pair? (fn (x) (and (list? x) (not (empty? x)))))
(define procedure? (fn (x) (or (lambda? x) (callable? x))))
(define boolean=? (fn (a b) (eq? a b)))
(define symbol->string symbol-name)
(define string->symbol make-symbol)
(define number->string (fn (n) (str n)))
(define
string->number
(fn (s) (if (string-contains? s ".") (parse-float s) (parse-int s))))