From 2222f55c422fc72f392b1f40ce1dee97b30c17d9 Mon Sep 17 00:00:00 2001 From: mehbark <terezi@pyrope.net> Date: Sun, 23 Feb 2025 18:35:50 -0500 Subject: [PATCH] feat: `define-record-{equality,matcher}!` these are great --- record.sls | 42 ++++++++++++++++++++++++++++++++++++++++++ std.sls | 3 ++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 record.sls diff --git a/record.sls b/record.sls new file mode 100644 index 0000000..015a863 --- /dev/null +++ b/record.sls @@ -0,0 +1,42 @@ +(library (meh record) + (export define-record-equality! define-record-matcher!) + (import (chezscheme) + (meh match)) + +(define-syntax define-record-equality! + (syntax-rules () + [(_ record-type-name) + (let () + (define rtd (record-type-descriptor record-type-name)) + (define field-count (vector-length (record-type-field-names rtd))) + (define accessors + (do ([i 0 (add1 i)] + [as '() (cons (record-accessor rtd i) as)]) + [(= i field-count) (reverse! as)])) + (record-type-equal-procedure rtd + (lambda (r1 r2 =) + (for-all + (lambda (accessor) (= (accessor r1) (accessor r2))) + accessors))))] + [(_ name name* ...) + (begin (define-record-equality! name) + (define-record-equality! name*) ...)])) + +(define-syntax define-record-matcher! + (syntax-rules () + [(_ record-type-name) + (define-pattern record-type-name + (lambda (e) + (syntax-case e () + [(_ pat* (... ...)) + (with-syntax ([rtd #'(record-type-descriptor record-type-name)] + [(idx* (... ...)) + (datum->syntax + #'* (iota (length (syntax->list #'(pat* (... ...))))))]) + #'(and (guard x (record? x rtd)) + (access (record-accessor rtd idx*) pat*) + (... ...)))])))] + [(_ name name* ...) + (begin (define-record-matcher! name) + (define-record-matcher! name*) ...)])) +) diff --git a/std.sls b/std.sls index bca7e57..b2580bc 100644 --- a/std.sls +++ b/std.sls @@ -16,7 +16,8 @@ (import (chezscheme)) - (export (import (meh match))) + (export (import (meh match)) + (import (meh record))) ;;; SYNTAX