Roos package

This commit is contained in:
2025-07-03 13:47:10 +02:00
parent 5e13fff797
commit 706614e5cf
8 changed files with 384 additions and 197 deletions

100
roos.rkt Normal file
View File

@@ -0,0 +1,100 @@
#lang racket/base
(require racket/syntax)
(provide roos ->)
(define-syntax roos-def
(syntax-rules ()
((_ h ((a) expr ...))
(begin
(define (a) expr ...)
(hash-set! h 'a a)))
((_ h ((a b) expr ...))
(begin
(define (a b) expr ...)
(hash-set! h 'a a)))
((_ h ((a b ...) expr ...))
(begin
(define (a b ...) expr ...)
(hash-set! h 'a a)))
((_ h ((a . f) expr ...))
(begin
(define (a . f) expr ...)
(hash-set! h 'a a)))
((_ h ((a b . f) expr ...))
(begin
(define (a b . f) expr ...)
(hash-set! h 'a a)))
((_ h ((a b ... . f) expr ...))
(begin
(define (a b ... . f) expr ...)
(hash-set! h 'a a)))
((_ h (a b))
(begin
(define a b)
(hash-set! h 'a (lambda () a))
(hash-set! h (string->symbol (format "~a!" 'a)) (lambda (v) (set! a v)))))
))
(define-syntax roos-supers
(syntax-rules ()
((_ self ())
(hash-set! self 'super (list)))
((_ self (a))
(hash-set! self 'super (list (a))))
((_ self (a b ...))
(hash-set! self 'super (list (a b ...))))
((_ ((x) (y) ...))
(hash-set! self 'super (list (roos-supers x) (roos-supers y) ...)))
))
(define-syntax roos
(syntax-rules ()
((_ (a ...) self supers b ...)
(begin
(define (a ...)
(begin
(define self (make-hash))
(roos-supers self supers)
(roos-def self b)
...
self))))
((_ (a ... . b) self supers c ...)
(begin
(define (a ... . b)
(begin
(define self (make-hash))
(roos-supers self supers)
(roos-def self c)
...
self))))
))
(define (find-super obj method)
(let ((supers (hash-ref obj 'super '())))
(letrec ((f (lambda (supers)
(if (null? supers)
(error (format "Method ~a not found" method))
(let ((s (car supers)))
(let ((m (hash-ref s method '%roos-nil%)))
(if (eq? m '%roos-nil%)
(f (cdr supers))
m)))))))
(f supers))))
(define-syntax ->
(syntax-rules ()
((_ obj method)
(let ((f (hash-ref obj 'method '%roos-nil%)))
(if (eq? f '%roos-nil%)
(let ((f* (find-super obj 'method)))
(f*))
(f))))
((_ obj method arg ...)
(let ((f (hash-ref obj 'method '%roos-nil%)))
(if (eq? f '%roos-nil%)
(let ((f* (find-super obj 'method)))
(f* arg ...))
(f arg ...))))))
)