Sat Mar 6 08:54:35 CET 2010
Assember refactoring: practical
Get rid of the `source' component in target-value, and use abstract
interpretation instead. Try once to see the dependencies, then
reconsider if it doesn't work.
Reconsider: I do not want to loose names of constants. Currently
these go through:
(define-syntax-rule (constants (name value) ...)
(define name (target-value-delay value 'name)) ...
(compositions (macro) macro: (name ',name) ...)))
Which binds the name both in the Scheme namespace to a target-value
and in the macro/ namespace as a constant function that refers to the
It looks like there is no way around it: current implementation needs
to maintain explicit source rep as we need to export symbols. Maybe
the functional rep can then be discarded?
I forgot: how de labels fit into the picture? The key routine is the
following: target-value objects will trigger their interpreter, while
target-word structs return an address if it is defined, or abort
;; Undefined words will abort. This is internal: used only to
;; recursively evaluate target-value references.
(define (target-value-eval expr)
((target-value? expr) ((target-value-thunk expr)))
((target-word? expr) (or (target-word-address expr)
To make this easier to understand, I want to change names:
target-value -> target-asmexpr
target-word -> target-node
Maybe the latter is not necessary, but the former seems to be: it's
essential to capture the idea that these are expressions - not fully
No - it's too interwoven, also the doc. I don't think it's that
complicated once you look from the perspective of the assembly result,
not the specification:
target-word = a machine address
target-value = a literal operand (can be address or num constant)
Because the target-word objects are not yet instantiated before
assembly relaxation is performed, the target-value objects need to
be thunks, parameterized by the value of the target-word objects.
I think it really needs to stay the same. Maybe the only thing to do
is to abstract the composition mechanism and representation of the
target-value code components. I.e. turn them into s-expressions
instead of concatenative words, as they represent values, not stacks
or stack ops.
So.. is this a detail or not?
PRO: it's instructive to be able to see symbolic asm code in RPN
form like this:
box> (code> 123 TOSL +)
[qw (123 TOSL +)]
CON: - essentially, these chunks represent values, not stacks or stackops
- an extra translation from RPN -> expression form is necessary
What about this: keep the code form to serve as human-readable only,
then modify the function form such that the functions come out of an
asmexpr namespace. This then allows one to encode the assembler
syntax into the operations.
I.e. change 'tv:' to something that is parameterized by the asmexpr
So I'm at this now:
;; The target-value compiler uses scat: to construct assembler
;; expressions. (FIXME: this sould later be full parameterization of
;; which assembler to use).
(define-syntax-rule (tv: . code)
(make-target-value-compiler scat: . code))
Is that enough? No, it needs to be parameterized differently. Is the
whole target-value / target-word business necessary when using an
external asm? In some sense yes as it's necessary to read back the
binary data. (Maybe that alone can be quite a problem?)
I.e. the binary code storage is tightly coupled to the target-word
struct, which matches it up with assembler opcodes. Really, this
can't be handled by external tools.
My conclusion is this:
- Staapl is a macro assembler. The 'assembler' (symbolic -> binary
translation and relaxation) part is a deeply integrated component
of the system. I.e. the Staapl assembler is more powerful than
external monolithic tools.
- To support external tools, use tool behaviour snarfing. Todo:
write an assembler snarfer (in Haskell?).