chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] Implementing a macroexpand-all


From: Patrick Li
Subject: Re: [Chicken-users] Implementing a macroexpand-all
Date: Sat, 12 Feb 2011 15:01:33 -0500

Thank you for everyone's help! 

I scrounged together a half-working implementation of macroexpand-all. It recursively macroexpands all the subforms within a form until there are absolutely no macros left in the _expression_. This is a temporary solution for whoever needs it, as I think Felix probably already has this implemented somewhere in the Chicken scheme system (because the compiler needs it I think) and just haven't exposed it for public use yet. 

Known Limitations:
(1) It does not work if you call it with fundamental macros ALREADY shadowed by existing local bindings.

A contrived example of shooting oneself in the foot:
(let ((let (fn (x) x)))
  (macroexpand-all '(let 10)))
This will STILL try to expand the "let" inside the form, because macroexpand-all does not know about the "let" binding introduced before the call to macroexpand-all.

(2) It does not work if the given form contains local macro definitions, or subforms that expand to local macro definitions. I imagine this will take some work and I just haven't gotten around to doing this yet.

  -Patrick

;;--------------------------------------------------------------------------------
;;----------------------------  MACRO EXPAND  ------------------------------------
;;Helper Function for macroexpanding an _expression_ with a list of known bound symbols.
;;Symbols are assumed to be NOT bound to macros. So this implementation does not work
;;with local macros.
(define (-macroexpand-all bound-symbols _expression_)
  (define (recurse-macroexpand-all bound-symbols _expression_)
    (cons (-macroexpand-all bound-symbols (car _expression_))
          (-macroexpand-all bound-symbols (cdr _expression_))))
  (define (get-symbols binding)
    (cond ((null? binding) '())
          ((pair? binding) (append (get-symbols (car binding)) (get-symbols (cdr binding))))
          (else (list binding))))

  (if (pair? _expression_)
      (let ((head (car _expression_))
            (tail (cdr _expression_)))
        (cond
         ;;((...) ...)
         ((pair? head) (recurse-macroexpand-all bound-symbols _expression_))

         ;;Bound Symbol
         ((memq head bound-symbols) (recurse-macroexpand-all bound-symbols _expression_))

         ;;Quoted _expression_
         ((eq? head '##core#quote)
          _expression_)

         ;;Lambda _expression_
         ((eq? head '##core#lambda)
          (let* ((bindings (cadr _expression_))
                 (body (cddr _expression_))
                 (new-symbols (append (get-symbols bindings) bound-symbols)))
            (cons head
                  (cons bindings
                        (recurse-macroexpand-all new-symbols body)))))

         ;;Let Form
         ((eq? head '##core#let)
          (let* ((bindings (cadr _expression_))
                 (body (cddr _expression_))
                 (new-symbols (append (map car bindings) bound-symbols))
                 (expanded-bindings (map (lambda (b)
                                           (list (car b) (-macroexpand-all bound-symbols (cadr b))))
                                         bindings)))
            (cons head (cons expanded-bindings (recurse-macroexpand-all new-symbols body)))))

         ;;Normal Form just expand it
         (else (recurse-macroexpand-all bound-symbols (expand _expression_)))))
      _expression_))

;;Macroexpand-All
(define (macroexpand-all _expression_)
  (-macroexpand-all '() _expression_))


On Sat, Feb 12, 2011 at 2:08 PM, Patrick Li <address@hidden> wrote:
Thanks for the help! I upgraded to 4.6.0 and everything's fine now.
 -Patrick


On Sat, Feb 12, 2011 at 12:55 PM, Peter Bex <address@hidden> wrote:
On Sat, Feb 12, 2011 at 12:18:30PM -0500, Patrick Li wrote:
> Ah I'm using Chicken 4.4.0.
> I'm a beginner to Chicken and just typed "port install chicken" into my
> MacOSX terminal.
> I'll figure out how to upgrade Chicken.

If you have more questions, it may be more efficient to continue the
conversation on IRC.

Cheers,
Peter
--
http://sjamaan.ath.cx
--
"The process of preparing programs for a digital computer
 is especially attractive, not only because it can be economically
 and scientifically rewarding, but also because it can be an aesthetic
 experience much like composing poetry or music."
                                                       -- Donald Knuth



reply via email to

[Prev in Thread] Current Thread [Next in Thread]