[racket] Ready for the next phase - or how to shift the phase of a namespace
For the archives the functions
eval-for-meta ; evaluate expression in given phase and return result
eval-for-syntax ; evaluate expression in phase 1 and return result
eval-form-for-meta ; evaluate form in given phase
eval-form-for-syntax ; evaluate form in phase 1
syntax-value ; return the value associated with a syntax
binding in a given phase
are available here:
https://github.com/soegaard/meta/blob/master/expander/transformer.rkt
/Jens Axel
2014-07-20 1:39 GMT+02:00 Jens Axel Søgaard <jensaxel at soegaard.net>:
> 2014-07-20 1:19 GMT+02:00 Matthias Felleisen <matthias at ccs.neu.edu>:
>>
>> Can't you just put forms2 into a constructed module that requires the desired module at the phase where you want it? -- Matthias
>
> That would be tricky. I am writing an interpreter that evaluates
> Racket bytecode represented as zo-structures.
>
> The main entry is:
>
> ; eval-zo : compilation-top [namespace] -> values(s)
> (define (eval-zo zo [ns (make-start-namespace)])
> (unless (compilation-top? zo)
> (error 'eval-zo "expected a compilation-top, got ~a" zo))
> ; evaluation always occur within a top-level namespace
> (parameterize ([current-namespace ns])
> (eval-top zo)))
>
> The structure of the interpreter is a straight forward recursive descent.
> The "phase 0" forms and expressions are done and works fine.
> I have also managed to evaluate the stxs part of the prefix.
> The instruction I need shift-phase for is seq-for-syntax.
>
> From the docs on begin-for-syntax:
> Evaluation of an expr within begin-for-syntax is parameterized to
> set current-namespace as in let-syntax.
> From the docs on (let-syntax ([id trans-expr] ...) body ...+)
> The evaluation of each trans-expr is parameterized to
> set current-namespace to a namespace that shares
> bindings and variables with the namespace being used to
> expand the let-syntax form, except that its base phase is one greater.
>
>
> Here is what I'd like to write:
>
> (define (eval-form form globs stack closed stx-ht)
> (match form
> ...
> [(struct seq-for-syntax (forms prefix max-let-depth dummy))
> ; push the prefix
> (define array (eval-prefix prefix stx-ht))
> (define new-stack (mlist array stack))
> ; shift phase and evalate each form
> (parameterize ([current-namespace (shift-phase (current-namespace) +1)])
> (for ([form (in-list forms)])
> (let-syntaxes ([() (begin (eval-form (car forms) globs
> new-stack closed stx-ht)
> (values))])
> (void))))]
>
> /Jens Axel
>
>> On Jul 19, 2014, at 3:52 PM, Jens Axel Søgaard wrote:
>>
>>> I am looking for a way to change the base phase of a namespace.
>>> Or perhaps to make a new namespace with the same mappings except a
>>> shift in phases.
>>> I hope I have missed a trick, but I couldn't find a
>>> namespace-shift-phase in the docs.
>>>
>>> Consider the following program which defines a variable x to 0, 1, 2, and, 3
>>> in phases 0, 1, 2, and, 3 respectively. It does so by evalunting the
>>> forms in forms.
>>>
>>> Then it displays the values of x in phases 1 and 2 with the results 1 and 2.
>>> It does so by evaluating the forms in forms2.
>>>
>>> I'd like to shift the base phase of the namespace (or make a copy with
>>> new base phase),
>>> so evaluating the forms in forms2 again will give results 2 and 3.
>>>
>>> #lang racket
>>> (define (eval* forms [ns (current-namespace)])
>>> (for ([form forms])
>>> (displayln (~a "> " form))
>>> (eval form ns)))
>>>
>>> (define forms '((module m0 racket (provide x) (define x 0))
>>> (module m1 racket (provide x) (define x 1))
>>> (module m2 racket (provide x) (define x 2))
>>> (module m3 racket (provide x) (define x 3))
>>> (require (for-meta 0 'm0))
>>> (require (for-meta 1 'm1))
>>> (require (for-meta 2 'm2))
>>> (require (for-meta 3 'm3))))
>>>
>>> (define forms2 '(; display the value of x in phase 1
>>> (define-syntaxes () (begin (displayln x) (values)))
>>> ; display the value of x in phase 2
>>> (define-syntaxes () (begin (let-syntaxes ([() (begin
>>> (displayln x) (values))])
>>> (void)) (values)))))
>>>
>>> (define ns (make-base-empty-namespace))
>>> (parameterize ([current-namespace ns])
>>> ; setup the namespace
>>> (namespace-require '(for-meta 0 racket/base))
>>> (namespace-require '(for-meta 1 racket/base))
>>> (namespace-require '(for-meta 2 racket/base))
>>> (namespace-require '(for-meta 3 racket/base))
>>> ; declare and require the modules
>>> (eval* forms)
>>> ; display the value of x in phase 1 and 2
>>> (eval* forms2) ; displays 1 and 2
>>> ; (namespace-shift-phase ns +1) ; on the wish list
>>> ; (eval* forms2) ; would display 2 and 3
>>> )
>>>
>>> The output is:
>>>
>>>> (module m0 racket (provide x) (define x 0))
>>>> (module m1 racket (provide x) (define x 1))
>>>> (module m2 racket (provide x) (define x 2))
>>>> (module m3 racket (provide x) (define x 3))
>>>> (require (for-meta 0 (quote m0)))
>>>> (require (for-meta 1 (quote m1)))
>>>> (require (for-meta 2 (quote m2)))
>>>> (require (for-meta 3 (quote m3)))
>>>> (define-syntaxes () (begin (displayln x) (values)))
>>> 1
>>>> (define-syntaxes () (begin (let-syntaxes ((() (begin (displayln x) (values)))) (void)) (values)))
>>> 2
>>>
>>> --
>>> Jens Axel Søgaard
>>>
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/users
>>
>
>
>
> --
> --
> Jens Axel Søgaard
--
--
Jens Axel Søgaard