sifflet-2.3.0: lib/Data/Sifflet/Functoid.hs
module Data.Sifflet.Functoid
(Functoid(..)
, functoidName, functoidArgNames, functoidHeader
, FunctoidLayout(..), flayout
, flayoutBBox, flayoutSize, flayoutWidth, flayoutBottom
, flayoutWiden)
where
import Data.Graph.Inductive as G
import Data.Sifflet.Geometry
import Data.Sifflet.TreeLayout
import Language.Sifflet.Expr
import Language.Sifflet.ExprTree
-- | A Functoid is either a FunctoidParts, representing a partially
-- defined function, or a (completely defined) Function.
-- A FunctoidParts represents an incompletely defined function,
-- which has a function name, argument names, and a list of graph nodes
-- representing the function body which might not yet form
-- a complete expression tree, e.g., nodes might
-- be unconnected.
data Functoid = FunctoidParts {fpName :: String,
fpArgs :: [String],
fpNodes :: [G.Node]}
| FunctoidFunc {fpFunc :: Function}
deriving (Show)
functoidName :: Functoid -> String
functoidName (FunctoidParts {fpName = name}) = name
functoidName (FunctoidFunc function) = functionName function
functoidArgNames :: Functoid -> [String]
functoidArgNames (FunctoidParts {fpArgs = args}) = args
functoidArgNames (FunctoidFunc function) = functionArgNames function
functoidHeader :: Functoid -> String
functoidHeader f = unwords (functoidName f : functoidArgNames f)
-- | What is a FunctoidLayout? You can think of it as a
-- tree layout for a Frame,
-- or for a Functoid, or as a Forest of Tree Layouts!
-- For an Edit frame, it must be a forest, since the nodes are not
-- yet necessarily connected into a tree.
-- For a call frame, it will be a single TreeLayout (singleton list).
data FunctoidLayout = FLayoutTree (TreeLayout ExprNode)
| FLayoutForest [TreeLayout ExprNode] BBox
-- | Graphically lay out the Functoid.
-- mvalues: Nothing implies an uncalled frame,
-- Just values implies a called frame, even with 0 arguments.
flayout :: Style -> Functoid -> Env -> Maybe [Value] -> FunctoidLayout
flayout style functoid env mvalues =
case functoid of
FunctoidParts {} ->
-- STUB: [] and bbox ***
-- WELL: is this supposed to CREATE the tlo or RETRIEVE the tlo?
-- Either way, it won't work without access to the WGraph!
FLayoutForest [] (BBox (hpad style) (vpad style) 300 300)
FunctoidFunc function ->
let expr = functionBody function
aspecs = functionArgSpecs function
exprTree = case mvalues of
Nothing -> exprToTree expr
Just _values -> evalTree (exprToTree expr) env
tlo = treeLayout style
(exprNodeIoletCounter env aspecs)
exprTree
in FLayoutTree tlo
flayoutBBox :: FunctoidLayout -> BBox
flayoutBBox aflayout =
case aflayout of
FLayoutTree t -> layoutTreeBB t
FLayoutForest _ bbox -> bbox
flayoutSize :: FunctoidLayout -> Size
flayoutSize = bbSize . flayoutBBox
flayoutWidth :: FunctoidLayout -> Double
flayoutWidth = bbWidth . flayoutBBox
flayoutBottom :: FunctoidLayout -> Double
flayoutBottom = bbBottom . flayoutBBox
flayoutWiden :: FunctoidLayout -> Double -> FunctoidLayout
flayoutWiden aflayout minWidth =
case aflayout of
FLayoutTree t -> FLayoutTree (treeLayoutWiden t minWidth)
FLayoutForest f bbox -> FLayoutForest f bbox -- STUB ***
instance Translate FunctoidLayout where
translate dx dy fl =
case fl of
FLayoutTree t ->
FLayoutTree (translate dx dy t)
FLayoutForest f b ->
FLayoutForest (translate dx dy f) (translate dx dy b)