module GraphToCode where
import qualified Graph as G
import qualified Code as C
import Control.Monad.State
import Data.List

graphToCode graph =
    C.Unit { C.inlets=G.inlets graph
           , C.outlets=G.outlets graph
           , C.statements=statements
           , C.statevars=statevars
           }
    where
      statements = schedule (G.inlets graph)
                            (G.outlets graph)
                            []
                            (G.nodes graph)
      statevars = (nub.concat.map mentionedStatevars.G.nodes) graph

mentionedStatevars statement =
    case C.op statement of
      (C.Store var) -> [var]
      (C.Load var) -> [var]
      _ -> []

type Trigger = ([String],[C.Statement])

schedule::[String]->[String]->[Trigger]->[G.Node]->[C.Statement]
schedule ready [] triggers nodes = []
schedule ready ((needed,forwhat):restNeeded) triggers nodes =
    let Just defn = G.findDefn needed nodes
        restNodes = delete defn nodes
        (newReady,newNeeded,newTriggers,statements) = performNode defn
    in statements ++ forwhat ++
       schedule (newReady++ready) (newNeeded++restNeeded) restNodes

performNode::G.Node->([String],[String],[Trigger],[C.Statement])
performNode node =
    case G.op Node of
      (G.Old initVal) -> (outputs node,inputs node,
    (outputs node