[racket-dev] processing the internal-context of a mod?

From: Danny Yoo (dyoo at hashcollision.org)
Date: Wed Mar 27 19:19:41 EDT 2013

So I'm revisiting some of the Whalesong code, and finally realized
that I'd been missing a crucial detail in the "internal-context" field
of modules.

    http://docs.racket-lang.org/raco/decompile.html#%28def._%28%28lib._compiler%2Fzo-structs..rkt%29._mod%29%29

I got it wrong because I didn't have to deal with namespaces before.
But since I'm trying to get the repl to work now, now I really do need
to get it righter.


I'm trying to understand the case analysis so that I can properly
generate the code to construct the namespace.  The documentation says
I have four things to keep track of for internal-context:

    case 1: #f: it's empty
    case 2: #t: it's all the requires
    case 3: stx: it's the lexical context of the wrapped syntax object
    case 4: (vectorof stx): ???

Case 2 seems fairly straightforward to me: to construct the namespace
for a module, I take all the symbols defined in its prefix, and
combine that with all the exports of all the required modules.


It's the other two cases that I don't quite understand yet.

I'm a little less sure of case 3.  I am guessing that I need to walk
the stx object and get the context entirely from it, not doing
anything like case 2.  I have a guess that case 4 is just an
accumulation over case 3, but I'm not positive.  I'm using the
following code to fiddle with internal-context to try
reverse-engineering its meaning:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
(require compiler/zo-parse)

(define (inspect-internal-context code)
  (define op (open-output-bytes))
  (write (parameterize ([current-namespace (make-base-namespace)])
           (compile code))
         op)
  (define parsed
    (zo-parse (open-input-bytes (get-output-bytes op))))
  ;; Let's look at that internal context.
  (mod-internal-context (compilation-top-code parsed)))

(wrapped-wraps
 (stx-encoded
  (inspect-internal-context '(module foo racket/base
                               (#%require (only racket first))))))


#;(inspect-internal-context '(module foo '#%kernel
                             (#%require (prefix list: racket/list)
                                        (prefix bool: racket/bool))
                             (define-values (a-variable) 42)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;



where I'm seeing a list of four wrapped values coming back at me, but
I don't yet discern any difference between the items, so I don't know
what this means yet.  Here's what I'm seeing:

################################
'(#s((module-rename wrap 0 zo 0)
     0
     normal
     139427
     (#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ())
#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ()))
     ((first . #s((exported-module-binding module-binding 0 zo 0)
#<module-path-index> #<module-path-index>)))
     ()
     #f)
  #s((module-rename wrap 0 zo 0)
     0
     normal
     139427
     (#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ())
#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ()))
     ((first . #s((exported-module-binding module-binding 0 zo 0)
#<module-path-index> #<module-path-index>)))
     ()
     #f)
  #s((module-rename wrap 0 zo 0)
     0
     normal
     139427
     (#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ())
#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ()))
     ((first . #s((exported-module-binding module-binding 0 zo 0)
#<module-path-index> #<module-path-index>)))
     ()
     #f)
  #s((module-rename wrap 0 zo 0)
     0
     normal
     139427
     (#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ())
#s((all-from-module zo 0) #<module-path-index> 0 0 () #f ()))
     ((first . #s((exported-module-binding module-binding 0 zo 0)
#<module-path-index> #<module-path-index>)))
     ()
     #f))
################################

Posted on the dev mailing list.