diff options
| author | LaMont Jones <lamont@debian.org> | 2003-05-07 08:36:40 -0600 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2017-02-20 00:05:27 -0800 | 
| commit | e21d47d7813159bb71e0671df9b52ec0470c358d (patch) | |
| tree | 3c7770ea846123c291f599044e9f234ac17616bb /Macexp.scm | |
| parent | 8cfce36c6a4fc2e0a0ab6ef2db66a23cbe462693 (diff) | |
| parent | deda2c0fd8689349fea2a900199a76ff7ecb319e (diff) | |
| download | scm-e21d47d7813159bb71e0671df9b52ec0470c358d.tar.gz scm-e21d47d7813159bb71e0671df9b52ec0470c358d.zip | |
Import Debian changes 5d6-3.2debian/5d6-3.2
scm (5d6-3.2) unstable; urgency=low
  * Fix hppa compile.  Closes: #144062
scm (5d6-3.1) unstable; urgency=low
  * NMU with patch from James Troup, to fix FTBFS on sparc. Closes: #191171
scm (5d6-3) unstable; urgency=low
  * Add build depend on xlibs-dev (Closes: #148020)
scm (5d6-2) unstable; urgency=low
  * Remove libregexx-dev from build-depends.
  * Change build to use ./scmlit rather than scmlit (should fix some build
    problems) (looks like alpha is mostly building)
  * New release (Closes: #140175)
  * Built with turtlegraphics last time (Closes: #58515)
scm (5d6-1) unstable; urgency=low
  * New upstream.
  * Add xlib and turtlegr to requested list of features. (closes
    some bug)
  * Make clean actually clean most everything up.
  * Remove hacks renaming build to something else and just set build as a
    .PHONY target in debian/rules.
  * Add the turtlegr code.
scm (5d5-1) unstable; urgency=low
  * New upstream
  * Has fixes for 64 bit archs.  May fix alpha compile problem.  Does fix
    (Closes: #140175)
  * Take out -O2 arg.
scm (5d4-3) unstable; urgency=low
  * Don't link with regexx, but just use libc6's regular expression
    functions.
  * Define (terms) to output /usr/share/common-licenses/GPL (Closes:
    #119321) 
scm (5d4-2) unstable; urgency=low
  * Add texinfo to build depends (Closes: #107011)
scm (5d4-1) unstable; urgency=low
  * New upstream release.
  * Move install-info --remove to prerm.
scm (5d3-5) unstable; urgency=low
  * Move scm info files to section "The Algorithmic Language Scheme" to
    match up with guile.
scm (5d3-4) unstable; urgency=low
  * Fix build depends (Closes: #76691)
scm (5d3-3) unstable; urgency=low
  * Fix path in scm dhelp file.
scm (5d3-2) unstable; urgency=low
  * Actually put the header files in the package.  Oops.
scm (5d3-1) unstable; urgency=low
  * New upstream. (Closes: #74761)
  * Make (terms) use new license location.
  * Make use libregexx rather than librx.
  * Fix build depends for above.
  * Using new regex lib seems to fix crash (Closes: #66787)
  * Consider adding scm-dev package with headers, but instead just add the
    headers to the scm package. (Closes: #70787)
  * Add doc-base support.
Diffstat (limited to 'Macexp.scm')
| -rw-r--r-- | Macexp.scm | 586 | 
1 files changed, 586 insertions, 0 deletions
| diff --git a/Macexp.scm b/Macexp.scm new file mode 100644 index 0000000..6802699 --- /dev/null +++ b/Macexp.scm @@ -0,0 +1,586 @@ +;; Copyright (C) 1999 Free Software Foundation, Inc. +;; +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this software; see the file COPYING.  If not, write to +;; the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111, USA. +;; +;; As a special exception, the Free Software Foundation gives permission +;; for additional uses of the text contained in its release of SCM. +;; +;; The exception is that, if you link the SCM library with other files +;; to produce an executable, this does not by itself cause the +;; resulting executable to be covered by the GNU General Public License. +;; Your use of that executable is in no way restricted on account of +;; linking the SCM library code into it. +;; +;; This exception does not however invalidate any other reasons why +;; the executable file might be covered by the GNU General Public License. +;; +;; This exception applies only to the code released by the +;; Free Software Foundation under the name SCM.  If you copy +;; code from other Free Software Foundation releases into a copy of +;; SCM, as the General Public License permits, the exception does +;; not apply to the code that you add in this way.  To avoid misleading +;; anyone as to the status of such modified files, you must delete +;; this exception notice from them. +;; +;; If you write modifications of your own for SCM, it is your choice +;; whether to permit this exception to apply to your modifications. +;; If you do not wish that, delete this exception notice. + +;;;; "Macexp.scm", macro expansion, respecting hygiene. +;;; Author: Radey Shouman + +;; LLIST is a lambda list, BINDINGS an alist using the same identifiers. +(define extended-environment +  (let ((env:annotation-marker 4)) +    (lambda (llist bindings env) +      (cons llist (cons env:annotation-marker (cons bindings env)))))) + +(define syntax-extended-environment +  (let ((env:syntax-marker 6)) +    ;;BINDINGS is an alist +    (lambda (bindings env) +      (cons (cons env:syntax-marker bindings) env)))) + +(define (environment-ref env id) +  (environment-annotation id env)) + +;;(debind:if_ ?llist ?val ?body ?alt) +;;?alt should evaluate to a procedure taking two arguments, a pattern +;;and an object.  This macro requires the (... ...) ellipsis quote +;;extension. +(define-syntax debind:if +  (syntax-rules () +    ((_ "PARSE LLIST" () ?val ?body ?alt) +     (if (null? ?val) ?body (?alt '() ?val))) + +    ((_ "PARSE LLIST" (?pattern (... ...)) ?val ?body ?alt) +     (let loop ((v ?val)) +       (cond ((null? v) +	      (debind:if "PARSE ..." ?pattern ?val ?body)) +	     ((pair? v) +	      (let ((carv (car v))) +		(debind:if "PARSE LLIST" ?pattern carv +			   (loop (cdr v)) ?alt))) +	     (else +	      (?alt '(?pattern (... ...)) ?val))))) + +    ((_ "PARSE LLIST" (?first . ?rest) ?val ?body ?alt) +     (if (pair? ?val) +	 (let ((carv (car ?val)) +	       (cdrv (cdr ?val))) +	   (debind:if "PARSE LLIST" ?first carv +		      (debind:if "PARSE LLIST" ?rest cdrv ?body ?alt) +		      ?alt)) +	 (?alt '(?first . ?rest) ?val))) + +    ((_ "PARSE LLIST" ?name ?val ?body ?alt) +     (let ((?name ?val)) ?body)) + +    ((_ "PARSE ..." () ?val ?body) +     ?body) + +    ((_ "PARSE ..." (?pattern (... ...)) ?val ?body) +     (debind:if "PARSE ..." ?pattern ?val ?body)) + +    ((_ "PARSE ..." (?first . ?rest) ?val ?body) +     (debind:if "PARSE ..." ?first (map car ?val) +	(debind:if "PARSE ..." ?rest (map cdr ?val) +			    ?body))) + +    ((_ "PARSE ..." ?name ?val ?body) +     (let ((?name ?val)) ?body)) + +    ((_ ?llist ?val ?body) +     (debind:if ?llist ?val ?body +		(lambda (pat val "debind:if" '?llist val +			     "does not match" pat)))) + +    ((_ ?llist ?val ?body ?alt) +     (let ((val ?val) +	   (alt ?alt)) +       (debind:if "PARSE LLIST" ?llist val ?body alt))))) + +;; Uncomment for DESTRUCTURING-BIND enhanced with ellipsis (...) patterns. +;(define-syntax destructuring-bind +;  (syntax-rules () +;    ((_ ?llist ?val ?body1 ?body ...) +;     (debind:if ?llist ?val +;		(let () ?body1 ?body ...) +;		(lambda (pat val) +;		  (slib:error 'destructuring-bind '?llist +;			      val "does not match" pat)))))) + +;; This should really dispatch on the keyword only, then +;; use destructuring-case for each keyword, that way errors +;; may be more accurately reported for primitives. +;; +;;(keyword-case expr env (pattern body ...) ...) +(define-syntax keyword-case +  (syntax-rules (else) +    ((_ "RECURSE" ?expr ?env) +     (error 'keyword-case ?expr "not matched")) +    ((_ "RECURSE" ?expr ?env +	(else ?body1 ?body ...)) +     (let () ?body1 ?body ...)) +    ((_ "RECURSE" ?expr ?env +	((?keyword . ?pattern) ?body1 ?body ...) +	?clause ...) +     (let ((alt (lambda (ignore1 ignore2) +		  (keyword-case "RECURSE" ?expr ?env ?clause ...)))) +       ;;Keywords are renamed in the top-level environment for each +       ;;comparison, this is wasteful and somewhat ugly. +       (if (identifier-equal? (renamed-identifier '?keyword '()) +			      (car ?expr) ?env) +	   (debind:if ?pattern (cdr ?expr) +		      (let () ?body1 ?body ...) +		      alt) +	   (alt #f #f)))) +    ((_ ?expr ?env ?clause1 ?clause ...) +     (let ((expr ?expr)) +       (if (or (not (pair? expr)) +	       (not (identifier? (car expr)))) +	   (error 'keyword-case expr "bad form") +	   (keyword-case "RECURSE" expr ?env ?clause1 ?clause ...)))))) + +;; This is still not safe when ENV has non-macro bindings in it. +;; It could be made safe by rebuilding an equivalent environment, +;; retaining values only for syntactic bindings. +(define (macro:expand-syntax form env pretty? verbose?) +  (define globals '()) +  (define shadowed-globals '()) +  (define top-lambda (renamed-identifier 'LAMBDA #f)) +  (define top-let (renamed-identifier 'LET #f)) +  (define top-let* (renamed-identifier 'LET* #f)) +  (define top-letrec (renamed-identifier 'LETREC #f)) +  (define top-arrow (renamed-identifier '=> #f)) +  (define top-else (renamed-identifier 'ELSE #f)) +  (define top-define (renamed-identifier 'DEFINE #f)) +  (define top-begin (renamed-identifier 'BEGIN #f)) +  (define (arrow? id env) +    (and (identifier? id) +	 (identifier-equal? id top-arrow env))) +  (define (else? id env) +    (and (identifier? id) +	 (identifier-equal? id top-else env))) +  (define (define? form env) +    (and (list? form)			;FORM will have been expanded. +	 (identifier? (car form)) +	 (identifier-equal? top-define (car form) env))) +  (define (begin? form env) +    (and (list? form) +	 (identifier? (car form)) +	 (identifier-equal? (car form) top-begin env))) + +  (define locally-bound? environment-annotation) + +  (define pretty-name +    (if pretty? +	(letrec ((counter 0) +		 (genname +		  (lambda (sym) +		    (set! counter (+ counter 1)) +		    (string->symbol +		     (string-append (symbol->string sym) +				    "|" (number->string counter)))))) +	  (lambda (name env) +	    (if (symbol? name) +		(if (or (memq name +			      '(LAMBDA LET LET* LETREC DO DEFINE SET! +				       BEGIN IF COND CASE AND OR QUOTE +				       QUASIQUOTE UNQUOTE UNQUOTE-SPLICING +				       DEFINE-SYNTAX LET-SYNTAX LETREC-SYNTAX +				       SYNTAX-QUOTE ELSE =>)) +			(locally-bound? name env)) +		    (genname name) +		    name) +		(genname (identifier->symbol name))))) +	identity)) + +  ;; Local bindings -> (identifier pretty-name (usage-context ...)) +  ;; This will change. +  (define (initial-binding name env) +    (or (identifier? name) +	(slib:error 'macro:expand name "not identifier")) +    (list name (pretty-name name env) '())) +  (define binding->name cadr) +  (define binding->contexts caddr) +  (define (binding-add-context! b context) +    (let ((ctx (caddr b))) +      (if (not (list? ctx)) +	  (error 'not-a-list ctx)) +      (or (memq context ctx) +	  (set-car! (cddr b) (cons context ctx))))) + +  ;; Produces an alist +  (define (llist->bindings llist env) +    (let recurse ((ll llist)) +      (cond ((pair? ll) +	     (cons (initial-binding (car ll) env) +		   (recurse (cdr ll)))) +	    ((identifier? ll) +	     (list (initial-binding ll env))) +	    ((null? ll) ll) +	    (else (error 'strange-lambda-list llist))))) + +  (define (expand-begin forms env context) +    (if (null? forms) +	'() +	(let recurse ((forms forms)) +	  (if (null? (cdr forms)) +	      (list (expand (car forms) env context)) +	      (cons (expand (car forms) env 'SIDE-EFFECT) +		    (recurse (cdr forms))))))) + +  (define (expand-body forms env context) +    (define (rewrite forms defs) +      (if (null? defs) +	  (expand-begin forms env context) +	  (list +	   (expand-primitive +	    `(,top-letrec ,(reverse defs) ;reverse just to make it pretty +			  ,@forms) env context)))) +    (let loop ((forms forms) +	       (defs '())) +      (if (null? (cdr forms)) +	  (rewrite forms defs) +	  (let ((form1 (expand (car forms) env 'SIDE-EFFECT))) +	    (cond ((define? form1 env) +		   (loop (cdr forms) +			 (cons (cdr form1) defs))) +		  ((begin? form1 env) +		   (loop (append (cdr form1) (cdr forms)) +			 defs)) +		  (else (rewrite forms defs))))))) + +  (define (lookup id env) +    (or (environment-ref env id) +	(let* ((sym (identifier->symbol id)) +	       (binding (cond ((assq sym globals)) +			      (else +			       (let ((b (initial-binding sym env))) +				 (set! globals (cons b globals)) +				 b))))) +	  (cond ((not pretty?) id) +		((not (locally-bound? sym env))) +		((assq sym shadowed-globals)) +		(else +		 (set! shadowed-globals +		       (cons (cons sym (binding->name binding)) +			     shadowed-globals)))) +	    binding))) + +  (define pretty-varref +    (if pretty? +	(lambda (id env) +	  (if (symbol? id) +	      id +	      (let ((sym (identifier->symbol id))) +		(if (identifier-equal? id sym env) sym id)))) +	(lambda (id env) id))) + +  (define unpaint +    (if pretty? +	(lambda (x) +	  (cond ((symbol? x) x) +		((identifier? x) (identifier->symbol x)) +		((pair? x) (cons (unpaint (car x)) (unpaint (cdr x)))) +		((vector? x) (let* ((n (vector-length x)) +				    (v (make-vector n))) +			       (do ((i 0 (+ i 1))) +				   ((>= i n) v) +				 (vector-set! v i (unpaint (vector-ref x i)))))) +		(else x))) +	identity)) + +  (define (expand* forms env context) +    (map (lambda (form) (expand form env context)) forms)) + +  (define (expand-primitive form env context) +    (define keyword (and (pair? form) +			 (if pretty? +			     (identifier->symbol (car form)) +			     (car form)))) +    (keyword-case +     form env +     ;;Binding forms +     ((LAMBDA llist body1 body ...) +      (let* ((bindings (llist->bindings llist env)) +	     (env (extended-environment llist bindings env)) +	     (body (expand-body (cons body1 body) env context)) +	     (llist (let recurse ((ll llist) +				  (bl bindings)) +		      (cond ((null? ll) '()) +			    ((pair? ll) (cons (binding->name (car bl)) +					      (recurse (cdr ll) (cdr bl)))) +			    (else (binding->name  bl)))))) +	`(,keyword ,llist ,@body))) +     ((LET ((names values) ...) body1 body ...) +      (let* ((values (expand* values env 'VALUE)) +	     (bindings (llist->bindings names env)) +	     (env (extended-environment names bindings env)) +	     (body (expand-body (cons body1 body) env context))) +	`(,keyword ,(map (lambda (b val) (list (binding->name b) val)) +			 bindings values) +		   ,@body))) +     ((LET name1 ((names values) ...) body1 body ...) +      (expand `((,top-letrec +		 ((,name1 (,(pretty-varref top-lambda env) ,names +			   ,@(cons body1 body)))) +		 ,name1) ,@values) +	      env context)) +     ((LETREC ((names values) ...) body1 body ...) +      (let* ((bindings (llist->bindings names env)) +	     (env (extended-environment names bindings env)) +	     (values (expand* values env 'VALUE)) +	     (body (expand-body (cons body1 body) env context))) +	`(,keyword ,(map (lambda (b val) (list (binding->name b) val)) +			 bindings values) +		   ,@body))) +     ((LET* ((names values) ...) body1 body ...) +      (let recurse ((ns names) +		    (vs values) +		    (env env) +		    (bs '())) +	(if (null? ns) +	    (let ((body (expand-body (cons body1 body) env context))) +	      `(,keyword ,(reverse bs) ,@body)) +	    (let ((binding (initial-binding (car ns) env))) +	      (recurse (cdr ns) (cdr vs) +		       (extended-environment (car ns) +					     (list binding) +					     env) +		       (cons (list (binding->name binding) +				   (expand (car vs) env 'VALUE)) +			     bs)))))) +     ((DO ((names inits . steps) ...) +	  (test exit ...) +	  body ...) +      (let* ((steps (map (lambda (name step) +			   (if (null? step) name (car step))) +			 names steps)) +	     (inits (expand* inits env 'VALUE)) +	     (bindings (llist->bindings names env)) +	     (env (extended-environment names bindings env)) +	     (steps (expand* steps env 'VALUE)) +	     (test (expand test env 'BOOLEAN)) +	     (exit (expand-begin exit env context)) +	     (body (expand-begin body env 'SIDE-EFFECT))) +	`(,keyword +	  ,(map (lambda (binding init step) +		  (list (binding->name binding) init step)) +		bindings inits steps) +	  ,(cons test exit) +	  ,@body))) +     ((DEFINE (name . llist) body ...) +      (expand-primitive +       `(,keyword ,name (,top-lambda ,llist ,@body)) env context)) +     ((DEFINE name value) +      (cond ((null? env)		;Top level +	     (binding-add-context! (lookup name env) 'DEFINE) +	     `(,keyword ,(pretty-varref name env) +			,(expand value env 'VALUE))) +	    (else +	     `(,keyword ,name ,value)))) ;Expansion will be done by expand-body. + +     ((SET! var value) +      (let ((b (lookup var env))) +	(binding-add-context! b 'SET!) +	`(,keyword ,(binding->name b) ,(expand value env 'VALUE)))) + +     ;;Non-binding forms +     ((BEGIN body ...) +      (let ((body (expand-begin body env context))) +	(if (null? (cdr body)) +	    (car body) +	    `(,keyword ,@body)))) +     ((IF test conseq . alt) +      `(,keyword ,(expand test env 'BOOLEAN) +		 ,(expand conseq env context) +		 ,@(if (pair? alt) +		       (list (expand (car alt) env context)) +		       '()))) +     ((COND (test exprs ...) ...) +      `(,keyword +	,@(map (lambda (test exprs) +		 (cond ((null? exprs) (list (expand test env context))) +		       ((arrow? (car exprs) env) +			(list (expand test env 'VALUE) +			      (pretty-varref top-arrow env) +			      (expand (cadr exprs) env 'PROCEDURE))) +		       ((else? test env) +			(cons (pretty-varref top-else env) +			      (expand-begin exprs env context))) +		       (else +			(cons (expand test env 'BOOLEAN) +			      (expand-begin exprs env context))))) +	       test exprs))) +     ((CASE obj (datums exprs ...) ...) +      `(,keyword ,(expand obj env 'VALUE) +	,@(map (lambda (datums exprs) +		 (cons (if (else? datums env) +			   (pretty-varref datums env) +			   (unpaint datums)) +		       (expand-begin exprs env context))) +	       datums exprs))) +     ((AND forms ...) +      `(,keyword ,@(expand* forms env context))) +     ((OR forms ...) +      `(,keyword ,@(expand* forms env context))) + +     ;; Should unpaint synthetic identifiers +     ((QUOTE obj) +      `(,keyword ,(unpaint obj))) +     ((QUASIQUOTE obj) +      `(,keyword +	,(let qexp ((obj obj) +		    (depth 0)) +	   (cond ((not (pair? obj)) +		  (unpaint obj)) +		 ((identifier? (car obj)) +		  (let ((keyword (car obj))) +		    (keyword-case +		     obj env +		     ((QUASIQUOTE arg) +		      (list keyword (qexp arg (+ depth 1)))) +		     ((UNQUOTE arg) +		      (list keyword +			    (if (zero? depth) +				(expand arg env context) +				(qexp arg (- depth 1))))) +		     ((UNQUOTE-SPLICING arg) +		      (list keyword +			    (if (zero? depth) +				(expand arg env context) +				(qexp arg (- depth 1))))) +		     (else +		      (cons (unpaint keyword) (qexp (cdr obj) depth)))))) +		 (else +		  (cons (qexp (car obj) depth) +			(qexp (cdr obj) depth))))))) +     ((DEFINE-SYNTAX name def) +      form) +     ((LET-SYNTAX ((names defs) ...) body1 body ...) +      (let* ((env (syntax-extended-environment '() env)) +	     (defs (map (lambda (name def) +			  (cons name (eval-syntax def env))) +			names defs)) +	     (env (syntax-extended-environment defs env)) +	     (body (expand-body (cons body1 body) env context))) +	(if pretty? +	    `(,(pretty-varref top-let env) () ,@body) +	    `(,top-let* (,(list marker #f)) ,@body)))) +     ((LETREC-SYNTAX ((names defs) ...) body1 body ...) +      (let* ((eframe (map (lambda (name) (cons name #f)) names)) +	     (env (syntax-extended-environment eframe env))) +	(do ((ds defs (cdr ds)) +	     (ef eframe (cdr ef))) +	    ((null? ds)) +	  (set-cdr! (car ef) (eval-syntax (car ds) env))) +	(let ((body (expand-body (cons body1 body) env context))) +	  (if pretty? +	      `(,(pretty-varref top-let env) () ,@body) +	      `(,top-let* (,(list marker #f)) ,@body))))) +     ;;SCM extension +     ((SYNTAX-QUOTE obj) +      `(,keyword ,obj)) +     (else +      (warn 'expand-syntax "Unexpected primitive syntax" form) +      form))) + +  (define (handle-shadowed form env) +    (if (define? form env) +	(list (car form) (cadr form) +	      (handle-shadowed (caddr form))) +	`(,(pretty-varref top-let env) +	  ,(map (lambda (s) +		  (list (cdr s) +			(if (environment-ref env (car s)) +			    (renamed-identifier (car s) #f) +			    (car s)))) +		shadowed-globals) +	  ,form))) + +  (define (expand form env context) +    (cond +     ((identifier? form) +      (let ((expanded (@macroexpand1 form env))) +	(cond ((eq? form expanded) form) +	      ((not expanded) +	       (let* ((b (lookup form env)) +		      (name (binding->name b))) +		 (binding-add-context! b context) +		 name)) +	      (else expanded)))) +     ((number? form) form) +     ((char? form) form) +     ((boolean? form) form) +     ((null? form) form) +     ((string? form) form) +     ((list? form) +      (if (identifier? (car form)) +	  (let ((expanded (@macroexpand1 form env))) +	    (cond ((eq? expanded form) +		   (expand-primitive form env context)) +		  ((not expanded) +		   (cons (expand (car form) env 'PROCEDURE) +			 (map (lambda (arg) +				(expand arg env 'VALUE)) +			      (cdr form)))) +		  (else +		   (expand expanded env context)))) +	  (cons (expand (car form) env 'PROCEDURE) +		(expand* (cdr form) env 'VALUE)))) +     (else +      (warn 'expand-syntax "Unexpected type of form" form) +      form))) + +  (let ((res (expand form env 'TOP))) +    (cond (verbose? +	   (display "Globals: ") +	   (pretty-print globals) +	   (display "Shadowed Globals: ") +	   (pretty-print shadowed-globals))) +    (cond ((null? shadowed-globals) res) +	  ((not (begin? res env)) (handle-shadowed res env)) +	  (else (cons (car res) +		      (map (lambda (form) +			     (handle-shadowed form env)) +			   (cdr res))))))) + +(define (macro:expand form . opt) +  (macro:expand-syntax form '() +		       (not (memq 'not-pretty opt)) +		       (memq 'verbose opt))) + +;; Debugging fodder. +(begin +  (define (read* filename) +    (call-with-input-file filename +      (lambda (p) +	(let loop ((forms '())) +	  (let ((form (read p))) +	    (if (eof-object? form) +		(cons 'BEGIN (reverse forms)) +		(loop (cons form forms)))))))) +  (define (expand-file filename . opt) +    (apply macro:expand (read* filename) '() opt)) +  (define s (read*  (or *load-pathname* "Macexp.scm")))) + + +;;; Local Variables: +;;; mode:scheme +;;; eval:(put 'destructuring-bind 'scheme-indent-function 1) +;;; eval:(put 'destructuring-case 'scheme-indent-function 1) +;;; End: | 
