ryansuchocki / microscheme

A Scheme subset for Atmel microcontrollers.

Home Page:http://ryansuchocki.github.io/microscheme/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

macroexpander?

technomancy opened this issue · comments

I have been pondering implementing a macroexpander for microscheme.

Obviously this can't be done like it would in a conventional scheme since runtime and compile time are completely distinct with no overlap. My first instinct would be to implement the macroexpander in a different scheme runtime and have it emit .ms files for Microscheme to compile.

A few questions:

  • Is this a decent idea? Something that might be appropriate for inclusion as an optional part of microscheme?
  • Is there any precedent for this among other schemes? I know ClojureScript does something similar since they lack runtime eval, but there's probably some prior art in the scheme world as well that we should look at.
  • If so, do you have a preference for which scheme to use?

It is a fantastic idea!

I think that a standalone tool that produces expanded scheme files, ready for the (ms) compiler, is certainly the right way to go about this at the moment.

There are many expander implementations around, and I wouldn't say that any of them is canonical. Over the years, there has been lots of room for interpretation re macros in the standards. In addition to the primitive implementation of any scheme compiler with macros, there are promising library implementations:

However, we might be able to get away with something very simple...

It is not unusual for Scheme implementations to expose their macro-expander so that it may be used, at runtime, on data. (Of course, "code is data"!) For example, in Guile, via (macroexpand ...)

The following Guile program continuously reads scheme code from stdin, expands macros and sends the output to stdout:

; macroexpander.scm

(use-modules (language tree-il))

(define (loop expr)
    (if (eof-object? expr)
        expr
        (begin
            (write (tree-il->scheme (macroexpand expr)))
            (newline)
            (loop (read)))))

(loop (read))

You can test it with:

$ cat sourcefile.scm | guile macroexpander.scm 1>outputfile.ms

I haven't tried this with some real microscheme program, but I think it should be a good start...

Cool! I figured you could probably do something simple with just a plain compiler as you've demonstrated, but I think for anything beyond a proof-of-concept we'd need to at least preserve line numbers. I'll play around with this a bit though; thanks.