[gambit-list] Transforming top-level program code
Jason Felice
jason.m.felice at gmail.com
Thu Feb 21 10:50:25 EST 2013
Awesome! Took a while to digest (specially because the docs are offline :(
).
What's the best way of making a check macro do nothing normally, but
redefining it when the code is loaded in a particular environment?
I'm thinking my checker tool will read the code, set a flag at the top,
then eval it (essentially). The problem is that I can't check a name which
might or might not exist. I was looking for whether there was a way to
stick a feature into cond-expand, but that doesn't seem to be the case.
Though I can redefine cond-expand (or something else), that seems a bit
much.
Thoughts?
-Jason
On Wed, Feb 20, 2013 at 1:37 PM, Marc Feeley <feeley at iro.umontreal.ca>wrote:
>
> On 2013-02-20, at 10:58 AM, Jason Felice <jason.m.felice at gmail.com> wrote:
>
> >
> > I've had a couple ideas for modifications to the Scheme reader that I
> imagine would be front-ends to the compiler. Examples:
> >
> > 1. A front end which reads Scheme source but specially handles square
> braces, transforming them into Objective-C method calls via my library, so
> that I can put the following in a program:
> >
> > (let ((s [[NSString alloc] initWithCapacity:42]))
> > ...)
> >
> > And have it dispatch non-dynamically (my current project is completely
> dynamic).
>
> Extending the reader to handle square brackets is easy because the reader
> already has hooks to customize the reading of [...], {...}, <...>, and
> (...). Here's an example:
>
> Gambit v4.6.7
>
> > (include "~~lib/_gambit#.scm")
> > '[NSString alloc]
> (NSString alloc)
> > (macro-readtable-bracket-keyword-set! ##main-readtable 'ObjC-send)
> > '[NSString alloc]
> [NSString alloc]
> > (length '[NSString alloc])
> 3
> > (car '[NSString alloc])
> ObjC-send
> > (cadr '[NSString alloc])
> NSString
> > (caddr '[NSString alloc])
> alloc
> > (list->vector '[NSString alloc])
> #(ObjC-send NSString alloc)
> > (define-macro (ObjC-send receiver . args) `(pp 'objective-c-send...))
> > [NSString alloc]
> objective-c-send...
>
> Another example, which treats [...] as a vector constructor is:
>
> > (include "~~lib/_gambit#.scm")
> > (macro-readtable-bracket-keyword-set! ##main-readtable 'vector)
> > [1 2 3 4]
> #(1 2 3 4)
>
> > 2. A testing library where "check" forms appear under each function in
> the same file as documentation. The check forms normally expand to
> nothing, but a command can be run from the command line scans the current
> directory and sub-directories for .scm files which (check ...) forms in
> them and runs them.
>
> This should be easy to do with macros.
>
> > 3. A complete environment with support for a lot of SRFI's and utility
> functions built in - a new REPL/compiler which is specialized for some
> domain.
> >
> > Black hole appears to do something like this.
> >
> > My question is, how do I hook into Gambit to compile or interpret after
> I've transformed the code, preserving line numbers?
>
> When you transform the code you must preserve the location information
> that was generated by the reader.
>
> The interpreter and compiler invoke the reader in a special mode where
> each datum (and subdatum) that is read is wrapped in a structure which
> gives the location information. These structures are called "source"
> objects, and the ##make-source function is the constructor.
>
> Here is an example. Say you have a file "foo.scm" with the content:
>
> (define n 1)
> (pp n)
>
> The interpreter and compiler will read that source code using the
> ##read-all-as-a-begin-expr-from-path function, which calls Gambit's
> extended read function to read each expression and construct a begin
> expression:
>
> > (vector-ref (##read-all-as-a-begin-expr-from-path
> "foo.scm"
> (##current-readtable)
> (lambda (re x) x)
> (lambda (re x) x))
> 1)
> (##begin (define n 1) (pp n))
>
> The last two parameters of ##read-all-as-a-begin-expr-from-path are the
> wrap and unwrap functions (whose first argument is the read-environment,
> which contains the reader's state including the port being read from and
> the current line/column location). By supplying the predefined
> ##wrap-datum and ##unwrap-datum functions, each datum (and subdatum) will
> be wrapped in a source object:
>
> > (vector-ref (##read-all-as-a-begin-expr-from-path
> "foo.scm"
> (##current-readtable)
> ##wrap-datum
> ##unwrap-datum)
> 1)
> #(#(source1)
> (#(#(source1) ##begin "/Users/feeley/gambit/work/foo.scm" 0)
> #(#(source1)
> (#(#(source1) define "/Users/feeley/gambit/work/foo.scm" 65536)
> #(#(source1) n "/Users/feeley/gambit/work/foo.scm" 524288)
> #(#(source1) 1 "/Users/feeley/gambit/work/foo.scm" 655360))
> "/Users/feeley/gambit/work/foo.scm"
> 0)
> #(#(source1)
> (#(#(source1) pp "/Users/feeley/gambit/work/foo.scm" 65537)
> #(#(source1) n "/Users/feeley/gambit/work/foo.scm" 262145))
> "/Users/feeley/gambit/work/foo.scm"
> 1))
> "/Users/feeley/gambit/work/foo.scm"
> 0)
>
> The source objects are vectors with the special tag #(source1) as their
> first element, i.e. #(#(source1) <datum> <filename> <column*65536+line>) .
> Note that when <datum> is a list or vector, each of the elements is
> wrapped in a source object, and so on recursively. The datum can be
> extracted with ##source-code, and the location information with
> ##source-locat.
>
> The interpreter and compiler can maintain this source location information
> when macros are defined with the ##define-syntax special form. The macro
> transformer function receives a source object with location information,
> and can return a source object with location information (the transformer
> can also return a non source object, which will get automatically wrapped
> with a source location object with the location of the macro call). Here's
> an example:
>
> > (define (where source)
> (##display-locat (##source-locat source) #f (repl-output-port))
> (newline))
> > (##define-syntax foo (lambda (source) (pp source) (where source) #f))
> > (foo 1 2)
> #(#(source1)
> (#(#(source1) foo (console) 65540)
> #(#(source1) 1 (console) 327684)
> #(#(source1) 2 (console) 458756))
> (console)
> 4)
> (console)@5:1
> #f
>
> Marc
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20130221/777717c7/attachment.htm>
More information about the Gambit-list
mailing list