[racket] need feedback on syntax-expanding/rewriting image-snips
I'm trying to support image snips in Whalesong. I think I have
something working, but wanted to run it by folks on the list to make
sure I haven't done something incredibly silly.
One of the problems that comes up is due to architecture: Whalesong
uses compiler/zo-parse, and compiler/zo-parse only takes in input
ports. I have to dance through a few hoops to get an appropriate
input port.
1. Given a path, I try calling get-module-code from the
syntax/modcode collection.
2. I then take that compiled-code value and write it into one end
of an output-string-port, and then create a fresh string input port
for use with zo-parse, since zo-parse needs a pipe that supports
file-position.
The code ends up looking like this:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
(require syntax/modcode
compiler/zo-parse)
;; path_>bytecode-port: path->port
;; Consumes the path to a Racket module, and produces a bytecode-port that's
;; suitable for use with compiler/zo-parse.
(define (path->bytecode-port a-path)
(parameterize ([current-namespace (make-base-namespace)])
(define code (get-module-code a-path))
(define outp (open-output-bytes))
(write code outp)
(open-input-bytes (get-output-bytes outp))))
(define some-toplevel-structure
(zo-parse
(path->bytecode-port
(build-path "/home/dyoo/work/whalesong/examples/hello.rkt"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
This works. Sorta. The difficulty lies when I deal with files that
have embedded snips in them, because the inner call to write fails:
snips don't serialize.
I end up having to do something a bit more elaborate: I don't use
get-module-code directly, but instead do the following:
1. read-syntax and expand to get a fully expanded syntax.
2. inject a helper module of my own that can create images out of
url strings.
3. walk the expanded syntax tree and replace the image snips with
calls to that image-url helper function.
4. finally, compile to bytecode and write it to my port, which
works because the image snips are replaced with vanilla function
calls.
The whole thing is in:
https://github.com/dyoo/whalesong/blob/master/get-module-bytecode.rkt
https://github.com/dyoo/whalesong/blob/master/expand-out-images.rkt
It's a bit more elaborate. I'm nervous particularly about
expand-out-images.rkt. I have no idea if I'm doing it right. In
fact, in some sense, I'm sure I'm doing something wrong: I don't quite
know what to do if the original program defines its own bindings that
clash with the image library. At the moment, if you look at how I'm
defining my-image-url in expand-out-images.rkt, I'm parameterizing it
with the value I get out of generate-temporaries, just to try to avoid
the name clash. Suggestions would be greatly appreciated here.