Efficiently Emitting Code
Efficiency Problem
Consider concatenation-based implementation
Consider standard purely functional list implementation
EmptyList ::: ys = ys (x::xs) ::: ys = x::(xs ::: ys)
How many times is traversed in such implementation?
- quadratic behavior
Consider the related StringBuilder
Imperatively Producing Sequences
Mutable variable contains code so far
Instead of appending lists of instructions, append each instruction to code so far
Just like pretty printing using 'println' instead of our Printing Prefix Infix Postfix
Advantage: very efficient
Disadvantage:
- less modular
- translation order is instruction order
- must be careful
- yet works well and is natural
var code : Array[Instruction] var last : Int = 0 def emit(i : Instruction) = { code(last) = i last = last + 1 } def translate(e : Expr) = e match { case Mul(e1,e2) => translate(e1) translate(e2) emit(Imul()) case IntLiteral(c) => emit(Bipush(c)) ... }
Functionally Producing Sequences
Use accumulating parameter
- standard technique in functional programming
Instead of
have
such that
Rules for expressions:
No concatenation anywhere, just adding to front.