mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-18 21:29:19 +02:00
38 lines
1.5 KiB
Scheme
38 lines
1.5 KiB
Scheme
(define-library (srfi 229)
|
|
(export procedure/tag? procedure-tag lambda/tag
|
|
case-lambda/tag)
|
|
(import (scheme base)
|
|
(only (chibi) lambda/generative length*)
|
|
(only (chibi ast)
|
|
Procedure type-of
|
|
procedure-tag
|
|
procedure-tag-set!
|
|
procedure-tagged?))
|
|
(begin
|
|
(define-syntax lambda/tag
|
|
(syntax-rules ()
|
|
((lambda/tag tag-expr formals body1 ... body2)
|
|
(let ((proc (lambda/generative formals body1 ... body2)))
|
|
(procedure-tag-set! proc tag-expr)
|
|
proc))))
|
|
(define (procedure/tag? obj)
|
|
(and (eq? (type-of obj) Procedure)
|
|
(procedure-tagged? obj)))
|
|
(define-syntax %case
|
|
(syntax-rules ()
|
|
((%case args len n p ((params ...) . body) . rest)
|
|
(if (= len (length '(params ...)))
|
|
(apply (lambda (params ...) . body) args)
|
|
(%case args len 0 () . rest)))
|
|
((%case args len n (p ...) ((x . y) . body) . rest)
|
|
(%case args len (+ n 1) (p ... x) (y . body) . rest))
|
|
((%case args len n (p ...) (y . body) . rest)
|
|
(if (>= len n)
|
|
(apply (lambda (p ... . y) . body) args)
|
|
(%case args len 0 () . rest)))
|
|
((%case args len n p)
|
|
(error "case-lambda/tag: no cases matched"))))
|
|
(define-syntax case-lambda/tag
|
|
(syntax-rules ()
|
|
((case-lambda tag-expr . clauses)
|
|
(lambda/tag tag-expr args (let ((len (length* args))) (%case args len 0 () . clauses))))))))
|