odds and ends
This commit is contained in:
		
							parent
							
								
									a6505ef990
								
							
						
					
					
						commit
						d6ac20424e
					
				| 
						 | 
					@ -0,0 +1,88 @@
 | 
				
			||||||
 | 
					; Copyright (c) 2003 RT Happe <rthappe at web de>
 | 
				
			||||||
 | 
					; See the file COPYING distributed with the Scheme Untergrund Library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; Odds and Ends
 | 
				
			||||||
 | 
					;   that haven't found a natural place, yet.
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; Synopses
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   (assert [id] exp)                                             ; syntax
 | 
				
			||||||
 | 
					;   If not EXP signal an error with suitable message.  The optional 
 | 
				
			||||||
 | 
					;   ID may be any printable object, e.g. a symbol naming the enclosing
 | 
				
			||||||
 | 
					;   procedure.  [ This could be done with a procedure, but ASSERT being
 | 
				
			||||||
 | 
					;   a macro, we can redefine it as the trivial form that doesn't evaluate
 | 
				
			||||||
 | 
					;   its parameters. ]
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   (receive/name loop formals exp form0 ...)                     ; syntax
 | 
				
			||||||
 | 
					;   Bind LOOP to a macro wrapped around the procedure LUP with parameter
 | 
				
			||||||
 | 
					;   list FORMALS and body FORM0 ... so that
 | 
				
			||||||
 | 
					;   * (LOOP multi-valued-expression) calls LUP with the values of 
 | 
				
			||||||
 | 
					;     multi-valued-expression , and
 | 
				
			||||||
 | 
					;   * (LOOP exp0 ...) becomes (LUP exp0 ...)
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;   (gen-dispatch ((predicate action) ...) e0 e1 ... en)          ; syntax
 | 
				
			||||||
 | 
					;   Dispatch action on type of first argument E0:  feed E0 ... EN to the 
 | 
				
			||||||
 | 
					;   first action such that the PREDICATE holds for E0.  Signal an error 
 | 
				
			||||||
 | 
					;   if nothing goes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define-syntax assert
 | 
				
			||||||
 | 
					      (syntax-rules ()
 | 
				
			||||||
 | 
						((assert ?x)
 | 
				
			||||||
 | 
						 (if (not ?x) (error "Assertion failed" '?x)))
 | 
				
			||||||
 | 
					        ((assert ?tag ?x)
 | 
				
			||||||
 | 
					         (if (not ?x) (error (format #f "~a -- assertion failed" ?tag)
 | 
				
			||||||
 | 
					                             '?x)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; RECEIVE/NAME is a multiple values analogue of named LET. 
 | 
				
			||||||
 | 
					; Syntax:  (receive/name <identifier> <formals> <expression> <body>)
 | 
				
			||||||
 | 
					;   [ non-terminals as in R5RS ]
 | 
				
			||||||
 | 
					; Semantics:  (receive/name loop (x y) exp0     ; yes, it's a special case
 | 
				
			||||||
 | 
					;               ... (loop exp1) ...) 
 | 
				
			||||||
 | 
					; is eqv to
 | 
				
			||||||
 | 
					;             (receive (x y) exp0
 | 
				
			||||||
 | 
					;               (let lup ((x x) (y y))
 | 
				
			||||||
 | 
					;                 ... (receive (x y) exp1
 | 
				
			||||||
 | 
					;                       (lup x y)) ...))
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; And         (receive/name loop (x y) exp0
 | 
				
			||||||
 | 
					;               ... (loop exp1 exp1) ...)
 | 
				
			||||||
 | 
					; is eqv to 
 | 
				
			||||||
 | 
					;             (receive (x y) exp0
 | 
				
			||||||
 | 
					;               (let lup ((x x) (y y))
 | 
				
			||||||
 | 
					;                 ... (lup exp1 exp2) ...))
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; Absurd example:
 | 
				
			||||||
 | 
					; (define (shove n xs) (values (- n 1) (cons n xs)))
 | 
				
			||||||
 | 
					; (receive/name loop (n xs) (values 7 '()) 
 | 
				
			||||||
 | 
					;   (if (= n 0)
 | 
				
			||||||
 | 
					;       (display xs)
 | 
				
			||||||
 | 
					;       (loop (shove n xs))))
 | 
				
			||||||
 | 
					(define-syntax receive/name
 | 
				
			||||||
 | 
					  (syntax-rules ()
 | 
				
			||||||
 | 
					    ((_ ?tag ?tuple ?call ?body0 ?body1 ...)
 | 
				
			||||||
 | 
					     (letrec ((proc
 | 
				
			||||||
 | 
					               (lambda ?tuple
 | 
				
			||||||
 | 
					                 (let-syntax
 | 
				
			||||||
 | 
					                     ((?tag (syntax-rules ()
 | 
				
			||||||
 | 
					                              ((?tag ?e)
 | 
				
			||||||
 | 
					                               (call-with-values (lambda () ?e)
 | 
				
			||||||
 | 
					                                 (lambda ?tuple (proc . ?tuple))))
 | 
				
			||||||
 | 
					                              ((?tag . ?args)
 | 
				
			||||||
 | 
					                               (proc . ?args)))))
 | 
				
			||||||
 | 
					                   ?body0 ?body1 ...))))
 | 
				
			||||||
 | 
					       (call-with-values (lambda () ?call) proc)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; dispatch on type of the first argument
 | 
				
			||||||
 | 
					;; [ should we support a default clause (else ?proc) ? ]
 | 
				
			||||||
 | 
					(define-syntax gen-dispatch
 | 
				
			||||||
 | 
					  (syntax-rules ()
 | 
				
			||||||
 | 
					    ((_ () ?x0 . ?rest)
 | 
				
			||||||
 | 
					     #f)
 | 
				
			||||||
 | 
					    ((_ ((?pred ?proc) ...) ?x0 . ?rest)
 | 
				
			||||||
 | 
					     (cond ((?pred ?x0) (?proc ?x0 . ?rest))
 | 
				
			||||||
 | 
					           ...
 | 
				
			||||||
 | 
					           (else (error "unsupported input type" ?x0))))))
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					; Copyright (c) 2003 RT Happe <rthappe at web de>
 | 
				
			||||||
 | 
					; See the file COPYING distributed with the Scheme Untergrund Library
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; odds and ends
 | 
				
			||||||
 | 
					(define-structure krims
 | 
				
			||||||
 | 
					  (export (assert :syntax)
 | 
				
			||||||
 | 
					          (receive/name :syntax)
 | 
				
			||||||
 | 
					          (gen-dispatch :syntax))
 | 
				
			||||||
 | 
					  (open srfi-28                         ; format
 | 
				
			||||||
 | 
					        srfi-23                         ; error
 | 
				
			||||||
 | 
					        scheme)
 | 
				
			||||||
 | 
					  (files krims))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;; srfi-9 + define-record-discloser
 | 
				
			||||||
 | 
					(define-structure srfi-9+
 | 
				
			||||||
 | 
					  (export (define-record-type :syntax)
 | 
				
			||||||
 | 
					          define-record-discloser)
 | 
				
			||||||
 | 
					  (open scheme-level-2 
 | 
				
			||||||
 | 
						(with-prefix define-record-types sys:))
 | 
				
			||||||
 | 
					  (begin
 | 
				
			||||||
 | 
					    (define-syntax define-record-type
 | 
				
			||||||
 | 
					      (syntax-rules ()
 | 
				
			||||||
 | 
						((define-record-type type-name . stuff)
 | 
				
			||||||
 | 
						 (sys:define-record-type type-name type-name . stuff))))
 | 
				
			||||||
 | 
					    (define define-record-discloser sys:define-record-discloser)))
 | 
				
			||||||
		Loading…
	
		Reference in New Issue