We said that stackerizer would convert an “appropriate” Racket S-expression into a stacker program. To keep things simple, we’ll support only a limited vocabulary of S-expressions:
The + and * operators. Of course.
Any numbers as arguments to these operators, in any quantity. Let’s remember that stacker can only perform operations on two arguments at a time, so we’ll need to make some kind of translation there.
Any degree of nesting. stacker only handles a flat list of arguments, so we’ll have to flatten the nesting somehow.
A stacker program represents a single expression. Therefore, the stackerizer language only needs to handle a single expression as input.
Open DrRacket. Start a new file called "stackerizer.rkt" and save it in a convenient location. All we need for now is the #lang line:
In the same directory, create a second file called "stackerizer-test.rkt", also blank except for the #lang line:
#lang s-exp "stackerizer.rkt"
Instead of #lang reader path, we’re using the new #lang s-exp path notation. Recall that #lang reader path was convenient for a prototype language, because it allows us to bootstrap into a certain (which in turn points to an ).
By contrast, #lang s-exp path does two things.
We cannot, however, skip making an expander. So the other job of #lang s-exp is to identify the expander we want to use, in this case "stackerizer.rkt".
Everything else works the same way. Just like the read-syntax function we made before, the s-exp reader returns the code for a module, packaged as a . And as before, our expander will need to start with a #%module-begin macro.
In Racket lingo, a language that uses the standard S-expression reader is known as a . Like vs. , this terminology is counterintuitive. All Racket code lives in some . Therefore, a language that uses a custom reader can only get it from a module. Anyhow. If we see “module language” in the Racket docs, we’ll know that it refers more precisely to a language that has no custom reader.