Sun Mar 20 10:25:09 EDT 2011

Syntax certificates

In Staapl, I keep running into errors like these:

compile: access from an uncertified context to unexported syntax from module: "/home/tom/pub/darcs/brood-5/staapl/pic18.ss" at: label:org-begin in: label:org-begin.261

I've read a bit on the manual[1] and I think I sort of understand the
idea, but I can't figure out what is causing this.  So, that's today's
task: understand syntax certs.

There are 3 candidates:

- The name prefixing which is used in ns.tx uses `datum->syntax'.
  According to the manual this does not transfer certificates.

- The `ns' macro itself.  However, that really just re-arranges its

- The `rpn-parse' macro which takes apart syntax and puts it back
  together again.

Another experiment.  What I noticed is that if I put the reference to
`label:org-begin' in a `macro:' form by itself, i.e.

   (macro: .. ,label:org-begin ..)

there is no problem.  So I changed the defining form to:

   (define-syntax-rule (word-defs wrap name raw-macro)
       (define-values (label wrapper codegen)
         (wrap 'name
               #f                      ;; source location
       (word-define (target) name label)
       (word-define (macro)  name wrapper)
       (label:append! codegen)))

and then used the following:

  (define-syntax-rule (words-org-flat (address rpn-code ...) ...)
       (define org-begin label:org-begin)
       (define org-end   label:org-end)
         (let ((raw-macro
                (macro: 'address ,label:org-begin
                        rpn-code ...

           (word-defs label:wrap-word #f raw-macro))

which works.  However, when the `raw-macro' is substituded in the code
it doesn't work.

Ok, so I've re-arranged the code such that the code generator is bound
to a variable.  That seems to work and has the added benefit of being
a bit more readable.

   (define-syntax-rule (words-flat (name . rpn-code) ...)
         (define codegen (macro: . rpn-code))
         (word-defs label:wrap-word name codegen))
   (define-syntax-rule (words (name rpn-code ...) ...)
         (define codegen (macro: rpn-code ... ,label:exit))
         (word-defs label:wrap-word name codegen))
   (define-syntax-rule (words-org-flat (address rpn-code ...) ...)
         (define codegen
           (macro: 'address ,label:org-begin  ;; Switch to a new chain
                   rpn-code ...               ;; append the code there,
                   ,label:org-end))           ;; and switch back.
         (word-defs label:wrap-word #f codegen))
   (define-syntax-rule (variable-entry name size)
       (define codegen (macro: size ,label:allot))
       (word-defs label:wrap-variable #f codegen)))

The pattern that shows up is that deconstructing a form like (a . b)
causes problems.  But that doesn't seem to be right.  My guess is that
this is really an artifact of the unit stuff.  Maybe it's time to
start to blame racket?

So, I don't understand why it's a problem here..  Let's try to redo
the other point where it showed up.

Ok, it seems the trouble is with the prefix parsers defined in the sig:
    ((forth) (:forth #f))
    ((macro) (:macro #f))

    ((variable n)   (:variable n 1 mf:allot))  ;; FIXME: needs parameterization
    ((2variable n)  (:variable n 2 mf:allot))  ;; FIXME: needs parameterization

The rest seems to work ok.