[plt-scheme] unit/sig question
I recently wrote a toy compiler to demonstrate a few things about using
a functional language with pattern matching for traversing grammars to
some colleagues in my department.
I ended up with too much code duplication; so, I read up on units, and
in having a clear (good?) use for them, I finally saw how I might use
them in putting together a program using them. For some reason, I never
quite saw what they could be used for.
I took my grammar and created a unit for each production rule; I then
define a "pass" in the compiler as a compound unit that composes the
production rules. This way, I can reuse most of the production rules
from one pass to another, but can also introduce new production rules
for handling, say, just one part of the grammar (a la [1], but without
all of the fancy grammar macro extension---this is more of a 'micro-'
than 'nano-pass' approach).
For example, the top level of my grammar looks like
(define-signature top^ (<top>))
(define top-lang0@
(unit/sig top^
(import id^ variable^ process^)
(define (<top> exp)
(match exp
[(struct proc (meta id variables process))
(make-proc
meta
(<id> id)
(map <variable> variables)
(<process> process))]
[else
(error '<top-lang0> "Bad proc form.")]))
))
And a pass that validates the input grammar looks like
(define verify-lang0@
(compound-unit/sig
(import)
(link
(TOP : top^ (top-lang0@ ID VARIABLE PROCESS))
(PROCESS : process^ (process-lang0@ ACTION
CONSTRUCTION))
(ACTION : action^ (action-lang0@ ID EXPRESSION))
(CONSTRUCTION : construction^ (construction-lang0@ PROCESS
EXPRESSION VARIABLE GUARD))
(GUARD : guard^ (guard-lang0@ ID))
(EXPRESSION : expression^ (expression-lang0@ OPERAND))
(OPERAND : operand^ (operand-lang0@ ID))
(VARIABLE : variable^ (variable-lang0@ ID TYPE))
(TYPE : type^ (type-lang0@))
(ID : id^ (id-lang0@)))
(export (var (TOP <top>)))
))
What I don't understand is how I can turn this compound unit into
something I can use. For example, I thought that something like
(define pass0 (invoke-unit/sig verify-lang0@))
would bind pass0 to the export of verify-lang0@ (and therefore an
expression that parses the top-level form in the language), but that's
not the case. Or, if it is, I've got the export of top-lang0@ wrong as
well, and somehow I just end up with #void.
I have a small example that seemed to work the way I'm expecting, but it
used 'unit' instead of 'unit/sig', which may account for the difference
in behavior and also my misunderstanding.
What is it that I should do to get the behavior I seem to think I want?
Thanks,
Matt
[1] A nanopass infrastructure for compiler education
Dipanwita Sarkar, Oscar Waddell, R. Kent Dybvig
http://doi.acm.org/10.1145/1016850.1016878