Sat Jul 3 16:05:51 CEST 2010

Practically: an application + Current code structure reminders

So, it gets more clear every time I pick this up again: it needs to be
more application driven; otherwise I'm starting to float.  The
"subsampling IIR" approach should work to build simple block-based
Pd/LADSPA/Jack plugins.  Atm the glue logic is more important than the
code transformation & parameterizable compiler stuff: fix the BORING

  - fix prettyprinter for the new Eq based flattener (non-memoized: fix that later)
  - obtain a Bindings struct with Z operators + write pre/post state fetch and update

As a reminder:
  Term      : Syntax for nested algebraic terms
  Ai        : Abstract interpretation (algebraic manip + simplifcation) of Term
  Flatten   : name intermediate nodes to convert Graph -> Bindings
  Procedure : Representation of SSA procedures (most concrete output of code generation: includes variable names)
  DFL       : Combine Term, Procedure and Flatten 

The toplevel module seems to be DFL.hs which allows the expression of
parameterized node networks.

While DFL just combines the different components, some functions are
curried in a way to keep the parameter names abstract, giving a syntax
representation that avoids the use of concrete names, allowing for
some composition mechanism on _syntax_ only, i.e. how to implement
loops (completely separate from any _meaning_ i.e. interpretation of
operations -- this distinction is important!! [1]).

-- List based functions need to accept an infinite list.    
f0 :: (RealFloat t) => [Term t] -> [Term t]       
f0 (ar:ai:br:bi:_) = [realPart c, imagPart c] where
    c = a * b
    a = ar :+ ai
    b = br :+ bi

*DFL> :t compile
compile :: (Show a) => ([Term a] -> [Term a]) -> Procedure

*DFL> compile f0
in:   in0, in2, in1, in3
out:  out0, out1
temp: r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10
[r0] <- [in0]
[r1] <- [in2]
[r2] <- mul[in0, in2]
[r3] <- [in1]
[r4] <- [in3]
[r5] <- mul[in1, in3]
[r6] <- negate[r5]
[r7] <- add[r2, r6]
[out0] <- [r7]
[r8] <- mul[in0, in3]
[r9] <- mul[in1, in2]
[r10] <- add[r8, r9]
[out1] <- [r10]

So, I think I understand again.  Derived from source, not the
documentation in [2] (couldn't find it / didn't know it was there /

In [2] I don't understand the temp node allocation problem..  From
what I gather I've side-stepped the problem by using a hardcoded
temp-node sequence.  Later when allocation becomes more clear, this
could be solved using some state monad.

So, DFL solves 2 problems:

   - Abstract interpretation / algebraic simplification
   - Serialization (graph -> SSA) + Eq-based CSE

This bridges
  * DSL semantics: generic Haskell arithmetic expressions
  * DSL syntax: implementation details for bindings, loops, temp vars, ...

[1] entry://20100509-111252
[2] entry://20100509-110352