Re: again: syntax-case and the module system
Johannes Bruegmann <[email protected]> Sat, 13 Sep 2008 09:12:09 +0200
| Newsgroups | gmane.comp.java.sisc.user |
|---|---|
| Message-ID | <[email protected]> |
Hello, >>>>> "me" =3D=3D Johannes Bruegmann <[email protected]> writes: me> Hello, can anybody help me with that? me> What is wrong with the following module definition? I found the time to work on that problem again and i was able to solve it the following way: - i rewrote both macros [2] - using mtrace [1] i was able to trace the macro expansion and locate the bugs in my code - the error message "Caused by Error: attempt to apply non-procedure '#!void'" appeared because of the letrec-behaviour of define-syntax and disappeared when importing each of the previous definitions into the lambda body of the define-syntax, like for example in the definition of an enumerated type color: ;;; the definition of enumerated-type :color (define-enumerated-type color :color color? colors color-name color-index (black white purple maroon)) =3D=3D=3D=3D> (output of macro mtrace'd in the last step): ;;; an unnamed module that expands in place = (module = (color colors |%%_rxomFnHre| color? color-name color-index) ; use records of SRFI-9 (import srfi-9) ; define a named module that exports all the symbols generated by ; macro define-enumerated-type (module |%%_rxKiDQHre| (colors |%%_rxomFnHre| color? color-name color-index) (import srfi-9) (define colors #f) (define-record-type :color (|%%_rxomFnHre| name index) color? (name color-name) (index color-index)) (set! colors (vector (|%%_rxomFnHre| 'black 0) (|%%_rxomFnHre| 'white (+ 0 1)) (|%%_rxomFnHre| 'purple (+ (+ 0 1) 1)) (|%%_rxomFnHre| 'maroon (+ (+ (+ 0 1) 1) 1))))) ; make the symbols of the module previously defined available in the ; current module definition (import |%%_rxKiDQHre|) ; import all symbols into the lambda body of define-syntax (define-syntax color (lambda (t) (import |%%_rxKiDQHre|) (syntax-case t (black white purple maroon) ((%_ black) (syntax (vector-ref colors 0))) ((%_ white) (syntax (vector-ref colors (+ 0 1)))) ((%_ purple) (syntax (vector-ref colors (+ (+ 0 1) 1)))) ((%_ maroon) (syntax (vector-ref colors (+ (+ (+ 0 1) 1) 1)))))))) Maybe somebody has a similiar problem in the future and will find this helpful. Regards, Johannes Br=FCgmann [1]: http://okmij.org/ftp/Scheme/macro-trace.txt: ;;; mtrace.scm - provide syntax for macro tracing ;;; source from: http://okmij.org/ftp/Scheme/macro-trace.txt (define-syntax mtrace (syntax-rules () ((mtrace x) (begin = (display "Trace: ") (pretty-print 'x) (newline) x)))) (define-syntax rletrec1 (syntax-rules () ((_ ((var1 init1) ...) body ...) (rletrec "generate temp names" (var1 ...) () ((var1 init1) ...) body ...)) ((_ "generate temp names" () (temp1 ...) ((var1 init1) ...) body ...) (let ((var1 #f) ...) (let ((temp1 init1) ...) (set! var1 temp1) ... body ...))) ((_ "generate temp names" (x y ...) (temp ...) ((var1 init1) ...) body ...) (rletrec "generate temp names" (y ...) (newtemp temp ...) ((var1 init1) ...) body ...)))) (define-syntax rletrec (syntax-rules () ((rletrec . args) (mtrace (rletrec1 . args))))) [2]: finite-types.scm: ;;; finite-types.scm - provide syntax for finite types and enumerated types ;;; Copyright (c) 2008 University Duisburg-Essen, Physics of Transport ;;; and Traffic, <http://www.ptt.uni-due.de> ;;; ;;; Author: Johannes Br=FCgmann, 05/2008, <[email protected]> ;;; = ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions ;;; are met: ;;; 1. Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; 2. Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; = ;;; THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND ;;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURP= OSE ;;; ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE ;;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENT= IAL ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ;;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ;;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STR= ICT ;;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY W= AY ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ;;; SUCH DAMAGE. ;;; finite-types as in Scheme48 = ;;;@ ;;;define a finite-type record: ;;;@lisp ;;; (define-finite-type tag type-name ;;; (field-tag ...) ;;; predicate-name ;;; vector-of-instances-name ;;; name-accessor ;;; index-accessor ;;; (field-tag accessor-name [modifier-name]) ;;; ...((instance-name field-value ...) ;;; ...)) ;;;@end lisp ;;;Example from Scheme48 Manual: ;;;@lisp ;;; (define-finite-type color :color ;;; (red green blue) ;;; color? ;;; colors ;;; color-name ;;; color-index ;;; (red color-red) ;;; (green color-green) ;;; (blue color-blue) ;;; ((black 0 0 0) ;;; (white 255 255 255) ;;; (purple 160 32 240) ;;; (maroon 176 48 96))) ;;; = ;;; (color-name (color black)) =3D> black ;;; (color-name (vector-ref colors 1)) =3D> white ;;; (color-index (color purple)) =3D> 2 ;;; (color-red (color maroon)) =3D> 176 ;;;@end lisp (define-syntax define-finite-type (lambda (f) (syntax-case f () ((_ tag tnm (col0 col1 ...) pred instvec nm-acc ix-acc (cn0 cnaccs0 .= ..) (cn1 cnaccs1 ...) ... (inst0 inst1 ...)) (with-syntax (((make-finite-type-record) (generate-temporaries '(1))= )) (syntax (_ (inst0 inst1 ...) = (make-finite-type-record 0) = tag instvec () pred = ((nm-acc ix-acc cnaccs0 ... cnaccs1 ... ...) (define-record-type tnm (make-finite-type-record name index col0 col1 ...) pred (name nm-acc) (index ix-acc) (cn0 cnaccs0 ...) (cn1 cnaccs1 ...) ...)))))) ((_ ((i0-name i0-val0 i0-val1 ...) inst1 ...) = (make-finite-type-record i rec0 ...) = tag instvec ((nm0 ix0) ...) pred = (exp0 exp1 ...)) (syntax (_ (inst1 ...) = (make-finite-type-record (+ i 1) rec0 ... (make-finite-type-record 'i0-= name i i0-val0 i0-val1 ...)) tag instvec ((nm0 ix0) ... (i0-name i)) pred = (exp0 exp1 ...)))) ((_ () = (make-finite-type-record i rec0 rec1 ...) = tag instvec ((nm0 ix0) (nm1 ix1) ...) pred = (exp0 exp1 ...)) (syntax (_ () () = (make-finite-type-record i rec0 rec1 ...) = tag instvec ((nm0 ix0) (nm1 ix1) ...) pred = (exp0 (define instvec #f) exp1 ... (set! instvec (vector rec0 rec1 ...)= ))))) ((_ () () (make-finite-type-record i rec0 rec1 ...) tag instvec ((nm0= ix0) (nm1 ix1) ...) pred ((acc0 acc1 ...) exp1 ...)) (with-syntax (((finite-types-helper) (generate-temporaries '(1)))) (syntax (begin (module (tag instvec make-finite-type-record pred acc0 acc1 ...) (import srfi-9) (module finite-types-helper (instvec make-finite-type-record pred acc0 acc1 ...) (import srfi-9) exp1 ...) (import finite-types-helper) (define-syntax tag (lambda (t) (import finite-types-helper) (syntax-case t (nm0 nm1 ...) ((%_ nm0) (syntax (vector-ref instvec ix0))) ((%_ nm1) (syntax (vector-ref instvec ix1))) ...)))))))) ))) ;;;@lisp ;;; (define-enumerated-type tag type-name ;;; predicate-name ;;; vector-of-instances-name ;;; name-accessor ;;; index-accessor ;;; (instance-name ...)) ;;;@end lisp ;;;Example from Scheme48 Manual: ;;;@lisp ;;; (define-enumerated-type color :color ;;; color? ;;; colors ;;; color-name ;;; color-index ;;; (black white purple maroon)) ;;; = ;;; (color-name (vector-ref colors 0)) =3D> black ;;; (color-name (color white)) =3D> white ;;; (color-index (color purple)) =3D> 2 ;;;@end lisp (define-syntax define-enumerated-type (lambda (f) (syntax-case f () = ((_ tag tnm pred instvec nm-acc ix-acc (inst0 inst1 ...)) (syntax (and (identifier? tag) (identifier? tnm) (identifier? pred) = (identifier? nm-acc) (identifier? ix-acc))) (with-syntax (((make-enumerated-type-record) (generate-temporaries '= (1)))) (syntax (_ (inst0 inst1 ...) = (make-enumerated-type-record 0) = tag instvec () pred () ((nm-acc ix-acc) (define-record-type tnm (make-enumerated-type-record name index) pred (name nm-acc) (index ix-acc))))))) ((_ (inst0-name inst1-name ...) (make-enumerated-type-record i rec0 .= ..) tag instvec ((nm0 ix0) ...) pred () (exp0 exp1 ...)) (syntax (_ (inst1-name ...) = (make-enumerated-type-record (+ i 1) rec0 ... (make-enumerated-type-rec= ord 'inst0-name i)) tag instvec ((nm0 ix0) ... (inst0-name i)) pred () (exp0 exp1 ...)))) ((_ () (make-enumerated-type-record i rec0 rec1 ...) tag instvec ((nm= 0 ix0) (nm1 ix1) ...) pred () (exp0 exp1 ...)) (syntax (_ () () = (make-enumerated-type-record i rec0 rec1 ...) = tag instvec ((nm0 ix0) (nm1 ix1) ...) pred () = (exp0 (define instvec #f) exp1 ... (set! instvec (vector rec0 rec1 ...)= ))))) ((_ () () (make-enumerated-type-record i rec0 rec1 ...) tag instvec (= (nm0 ix0) (nm1 ix1) ...) pred () ((nm-acc ix-acc) exp1 ...)) (with-syntax (((enumerated-types-helper) (generate-temporaries '(1))= )) (syntax (begin (module (tag instvec make-enumerated-type-record pred nm-acc ix-acc) (import srfi-9) (module enumerated-types-helper (instvec make-enumerated-type-record pred nm-acc ix-acc) (import srfi-9) exp1 ...) (import enumerated-types-helper) (define-syntax tag (lambda (t) (import enumerated-types-helper) (syntax-case t (nm0 nm1 ...) ((%_ nm0) (syntax (vector-ref instvec ix0))) ((%_ nm1) (syntax (vector-ref instvec ix1))) ...)))))))) ))) -- W=FCrdig bist du, o Herr, zu empfangen den Ruhm und die Ehre un= d die Macht; denn du hast alle Dinge geschaffen, und durch deinen Willen s= ind sie und wurden sie geschaffen! Offenbarung 4, 11 ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great priz= es Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=3D100&url=3D/