Mon May 6 11:06:23 EDT 2013
What is Staapl?
- "assisted" macro assembler
- low-level code modeling tool
- experiment: does it make sense to write "abstract low-level code".
Some basic ideas.
uC code is often code-size constrained.
A stack language (Forth) or stack machine model can help here.
Why? Replacing global registers (RISC machine) with a 2nd stack
can decouple code, introducing more opportunity for code reuse.
uC code is often very specialized and "hand optimized".
This means there is _implicit_ structure in the code that is no
longer visible in the low-level assembly (or C) code.
It makes sense to generate it from a higher level description, to
make this otherwise hidden structure explicit. I.e. represent a
model and a specializer as opposed to just the specialized code.
At the meta level, a stack language is easily represented as a
pure functional language.
syntactic concatenation -> composition of code generators
How does it work? Take the Forth snippet
1 2 +
which loads two numbers on the parameter stack and performs the "+"
operation. The result of this is a parameter stack loaded with the
When compiling this to machine code, one would typically see the
Note there is a direct correspondence between a forth code sequence
and a machine code sequence. The trick is then to interpret the
recently generated machine code as a _data stack_
I.e. after compiling "1 2", the compiler sees the following generated
When it encounters "+", instead of compiling the call to "+", it would
remove the two _instructions_ from the compilation buffer, perform the
computation at compile time, and produce the result.
In general, this is called _partial evaluation_. This particular
structure is also called a _peephole optimizer_ in that it only looks
at the most recent code.
Once this mechanism is in place, it is possible to generalize it to
"virtual instructions", meaning to compile code that cannot be
compiled directly to machine code, but will act as parameters passed
to other code generators. This introduces _composition_ of code
And that's it. Everything else fits in this picture. It allows the
same syntactic representation for compile time and run time code.
It's not that different from the macros vs. functions idea in Scheme,
only that this works on stacks of code and not data flow graphs (=
So what's the point? It allows to mix machine mapping (i.e. PIC18
macros) and highlevel code generators, all in one representation,
giving access to the _real_ machine.
( As opposed to performing the partial evaluation directly on the
input syntax. This is related to joy's syntactic vs. semantic
Example in staapl:
- conditionals use uC flags instead of the data stack.