ryansuchocki / microscheme

A Scheme subset for Atmel microcontrollers.
http://ryansuchocki.github.io/microscheme/
MIT License
300 stars 20 forks source link

macroexpander? #8

Closed technomancy closed 9 years ago

technomancy commented 9 years ago

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:

ryansuchocki commented 9 years ago

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...

technomancy commented 9 years ago

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.