I have a bug I'm trying to fix in #lang magic(
https://github.com/jjsimpso/magic). I'm pretty sure I know what the cause
is and I know what I want to do, but I don't know how to do it. The
situation is this:
In the following magic code, a new function(called a named query in magic)
tga-image is defined and later used inside the definition of the function
test-scope. The issue is that tga-image is an unbound identifier in
test-scope. If tga-image is used outside of a function there isn't a
problem because the syntax object passed to use has the binding. What I
would like to do is define tga-image at the top level. When test-scope is
being expanded it doesn't find the binding for tga-image and tags it with
#%top, so I think putting tga-image at the top level will solve my problem.
I also think that this is not a bad solution for my use case.
#lang magic
# display tga bitmap image information
0 name tga-image
>2 byte <34 Targa image data
0 name test-scope
>2 byte <34 Test Scope
>0 use tga-image
After parsing, this code becomes:
(module magic-mod magic/expander
(magic
#f
#f
(named-query
(name-line (offset 0) (name-type "name") "tga-image")
(level)
(line (offset 2) (type (numeric "byte")) (test (numtest "<" 34)) (message
"Targa image data")))
(named-query
(name-line (offset 0) (name-type "name") "test-scope")
(level)
(line (offset 2) (type (numeric "byte")) (test (numtest "<" 34)) (message
"Test Scope"))
(level)
(line (offset 0) (type (use "use")) (test (use-name "tga-image"))))))
This is the most relevant code in my expander (I highlighted creation of
name's binding in red):
(define-syntax (named-query stx)
(syntax-case stx (name-line)
[(_ (name-line (_ 0) (_ "name") magic-name))
(with-syntax ([name (datum->syntax stx (string->symbol (syntax->datum
#'magic-name)))])
#'(define name
(lambda (new-offset) (void))))]
[(_ (name-line (_ 0) (_ "name") magic-name) . rst)
(with-syntax ([name (datum->syntax stx (string->symbol (syntax->datum
#'magic-name)))]
[modified-rst (cons (datum->syntax #'rst
always-true-line) #'rst)])
#'(define name
(lambda (new-offset)
(syntax-parameterize ([name-offset (make-rename-transformer
#'new-offset)])
;(printf "name: offset = ~a~n" name-offset)
(query . modified-rst)))))]))
(define-syntax (magic-module-begin stx)
(define (query? expr)
(if (and (pair? expr)
(equal? (car expr) 'query))
#t
#f))
(define (named-query? expr)
(if (and (pair? expr)
(equal? (car expr) 'named-query))
#t
#f))
(define (wrap-with-delimiter-print expr)
(list 'when* expr '(printf "*** ")))
(let ([exprs (cdadr (syntax->datum stx))])
;(display queries)
(let ([queries (filter query? exprs)]
[named-queries (filter named-query? exprs)])
#`(#%module-begin
#,@named-queries
(define (magic-query)
(or #,@queries))
(define (magic-query-run-all)
; any-true? creates a binding for last-level-offset which we
probably don't want here. investigate.
(any-true? #,@(map wrap-with-delimiter-print queries)))
(provide magic-query magic-query-run-all)))))
The full code is at
https://github.com/jjsimpso/magic/blob/master/expander.rkt.
If there isn't an easy way to pass the top level syntax object into
named-query, then I may have to do something with syntax parameters. I
think that would be more complicated since I'm potentially defining lots of
functions.
Any help is appreciated! I thought this would be an easy one, but I've
spent a while on it already. Hopefully there is a simple solution.
-- Jonathan
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/racket-users/ee664882-1dec-4bb8-b66b-bd6ee80316dc%40googlegroups.com.