(define-library (srfi 229) (import (scheme base) (scheme case-lambda) (chibi ast) (only (chibi) opcode?)) (export case-lambda/tag lambda/tag procedure/tag? procedure-tag) (begin (define procedure-tag-object (list 'procedure-tag)) (define (procedure->tagged f tag) (make-procedure (procedure-flags f) (procedure-arity f) (procedure-code f) (vector-append (or (procedure-vars f) '#()) (vector tag procedure-tag-object)))) (define-syntax lambda/tag (syntax-rules () ((lambda/tag tag-expr formals . body) (procedure->tagged (lambda formals . body) tag-expr)))) (define-syntax case-lambda/tag (syntax-rules () ((case-lambda/tag tag-expr . clauses) (procedure->tagged (case-lambda . clauses) tag-expr)))) (define (procedure/tag? f) (and (procedure? f) (not (opcode? f)) (let ((vars (procedure-vars f))) (and (vector? vars) (> (vector-length vars) 1) (eq? procedure-tag-object (vector-ref vars (- (vector-length vars) 1))))))) (define (procedure-tag f) (let ((vars (procedure-vars f))) (vector-ref vars (- (vector-length vars) 2))))))