Update stackage. Replace (NodeName, Icon) with NamedIcon.

This commit is contained in:
Robbie Gleichman 2018-10-28 00:25:31 -07:00
parent 8267305950
commit 4b99c862a7
12 changed files with 148 additions and 108 deletions

View File

@ -16,6 +16,7 @@ import Types(SyntaxNode(..), IngSyntaxGraph, Edge(..),
CaseOrGuardTag(..), Port(..), NameAndPort(..), SgNamedNode(..))
import Util(maybeBoolToBool, sgNamedNodeToSyntaxNode)
--import Util(printSelf)
{-# ANN module "HLint: ignore Use record patterns" #-}
-- See graph_algs.txt for pseudocode

View File

@ -28,10 +28,13 @@ import Data.Either(partitionEithers)
import Data.List(find)
import Data.Maybe(catMaybes, listToMaybe, isJust, fromJust)
import Types(Icon(..), SpecialQDiagram, SpecialBackend, SpecialNum, NodeName, Port(..), LikeApplyFlavor(..),
SyntaxNode(..))
import Types(Icon(..), SpecialQDiagram, SpecialBackend, SpecialNum
, NodeName, Port(..), LikeApplyFlavor(..),
SyntaxNode(..), NamedIcon(..))
import DrawingColors(colorScheme, ColorStyle(..))
{-# ANN module "HLint: ignore Use record patterns" #-}
-- TYPES --
-- | A TransformableDia is a function that returns a diagram for an icon when given
-- the icon's name, its nesting depth, whether it will be reflected, and by what
@ -97,21 +100,21 @@ findNestedIcon name icon = case icon of
NestedPApp args -> snd <$> findIcon name (fmap fst args)
_ -> Nothing
findIcon :: NodeName -> [Maybe (NodeName, Icon)] -> Maybe (Int, Icon)
findIcon :: NodeName -> [Maybe NamedIcon] -> Maybe (Int, Icon)
findIcon name args = icon where
numberedArgs = zip ([0,1..] :: [Int]) args
filteredArgs = Arrow.second fromJust <$> filter (isJust . snd) numberedArgs
nameMatches (_, (n, _)) = n == name
nameMatches (_, NamedIcon n _) = n == name
icon = case find nameMatches filteredArgs of
Nothing -> listToMaybe $ catMaybes $ fmap findSubSubIcon filteredArgs
Just (argNum, (_, finalIcon)) -> Just (argNum, finalIcon)
Just (argNum, NamedIcon _ finalIcon) -> Just (argNum, finalIcon)
where
findSubSubIcon (argNum, (_, subIcon)) = case findNestedIcon name subIcon of
findSubSubIcon (argNum, NamedIcon _ subIcon) = case findNestedIcon name subIcon of
Nothing -> Nothing
Just x -> Just (argNum, x)
generalNestedPortAngles :: SpecialNum n =>
(Port -> [Angle n]) -> [Maybe (NodeName, Icon)] -> Port -> Maybe NodeName -> [Angle n]
(Port -> [Angle n]) -> [Maybe NamedIcon] -> Port -> Maybe NodeName -> [Angle n]
generalNestedPortAngles defaultAngles args port maybeNodeName = case maybeNodeName of
Nothing -> defaultAngles port
Just name -> case findIcon name args of
@ -124,7 +127,7 @@ reflectXAngle x = reflectedAngle where
reflectedAngle = (-) <$> halfTurn <*> normalizedAngle
-- TODO reflect the angles for the right side sub-icons
nestedGuardPortAngles :: SpecialNum n => [Maybe (NodeName, Icon)] -> Port -> Maybe NodeName -> [Angle n]
nestedGuardPortAngles :: SpecialNum n => [Maybe NamedIcon] -> Port -> Maybe NodeName -> [Angle n]
nestedGuardPortAngles args port maybeNodeName = case maybeNodeName of
Nothing -> guardPortAngles port
Just name -> case findIcon name args of
@ -290,7 +293,7 @@ generalTextAppDia textCol borderCol numArgs str name _ reflect angle = nameDiagr
-- TODO Refactor with generalNestedDia
nestedPAppDia :: SpecialBackend b n =>
[Colour Double] -> [(Maybe (NodeName, Icon), String)] -> TransformableDia b n
[Colour Double] -> [(Maybe NamedIcon, String)] -> TransformableDia b n
nestedPAppDia borderCols funcNodeNameAndArgs name nestingLevel reflect angle = named name $ case funcNodeNameAndArgs of
[] -> mempty
(maybeFunText:args) -> centerXY $ centerY finalDia ||| transformedText ||| resultCircleAndPort
@ -307,21 +310,21 @@ nestedPAppDia borderCols funcNodeNameAndArgs name nestingLevel reflect angle = n
rotate quarterTurn (apply0Triangle borderCol) :
zipWith (makeInnerIcon False) argPortsConst args
allPorts = makeQualifiedPort name inputPortConst <> alignT triangleAndPorts -- alignL (strutX separation ||| trianglePortsCircle)
topAndBottomLineWidth = width allPorts
-- boxHeight = height
-- boxHeight = height
argBox = alignT $ lwG defaultLineWidth $ lc borderCol $ roundedRect topAndBottomLineWidth (height allPorts + verticalSeparation) (circleRadius * 0.5)
finalDia = argBox <> allPorts
makeInnerIcon _ portNum (Nothing, str) = centerX $ makeLabelledPort name reflect angle str portNum
makeInnerIcon True _ ((Just (_, TextBoxIcon t)), _) = transformCorrectedTextBox t (textBoxTextC colorScheme) borderCol reflect angle
makeInnerIcon func _ ((Just (iconNodeName, icon)), _) = iconToDiagram icon iconNodeName innerLevel reflect angle where
makeInnerIcon True _ (Just (NamedIcon _ (TextBoxIcon t)), _) = transformCorrectedTextBox t (textBoxTextC colorScheme) borderCol reflect angle
makeInnerIcon func _ (Just (NamedIcon iconNodeName icon), _) = iconToDiagram icon iconNodeName innerLevel reflect angle where
innerLevel = if func then nestingLevel else nestingLevel + 1
generalNestedDia :: SpecialBackend b n =>
(Colour Double -> SpecialQDiagram b n) -> [Colour Double] -> [Maybe (NodeName, Icon)] -> TransformableDia b n
(Colour Double -> SpecialQDiagram b n) -> [Colour Double] -> [Maybe NamedIcon] -> TransformableDia b n
generalNestedDia dia borderCols funcNodeNameAndArgs name nestingLevel reflect angle = named name $ case funcNodeNameAndArgs of
[] -> mempty
(maybeFunText:args) -> centerXY $ transformedText ||| centerY finalDia
@ -337,19 +340,19 @@ generalNestedDia dia borderCols funcNodeNameAndArgs name nestingLevel reflect an
reflectX (dia borderCol) :
zipWith (makeInnerIcon False) argPortsConst args ++
[makeQualifiedPort name resultPortConst <> alignR (lc borderCol $ lwG defaultLineWidth $ fc borderCol $ circle circleRadius)]
allPorts = makeQualifiedPort name inputPortConst <> alignL trianglePortsCircle
topAndBottomLineWidth = width allPorts - circleRadius
argBox = alignL $ lwG defaultLineWidth $ lc borderCol $ roundedRect topAndBottomLineWidth (height allPorts + verticalSeperation) (circleRadius * 0.5)
finalDia = argBox <> allPorts
makeInnerIcon _ portNum Nothing = makeQualifiedPort name portNum <> portCircle
makeInnerIcon True _ (Just (_, TextBoxIcon t)) = transformCorrectedTextBox t (textBoxTextC colorScheme) borderCol reflect angle
makeInnerIcon func _ (Just (iconNodeName, icon)) = iconToDiagram icon iconNodeName innerLevel reflect angle where
makeInnerIcon True _ (Just (NamedIcon _ (TextBoxIcon t))) = transformCorrectedTextBox t (textBoxTextC colorScheme) borderCol reflect angle
makeInnerIcon func _ (Just (NamedIcon iconNodeName icon)) = iconToDiagram icon iconNodeName innerLevel reflect angle where
innerLevel = if func then nestingLevel else nestingLevel + 1
nestedApplyDia :: SpecialBackend b n =>
LikeApplyFlavor -> [Maybe (NodeName, Icon)] -> TransformableDia b n
LikeApplyFlavor -> [Maybe NamedIcon] -> TransformableDia b n
nestedApplyDia flavor = case flavor of
ApplyNodeFlavor -> generalNestedDia apply0Triangle (nestingC colorScheme)
ComposeNodeFlavor -> generalNestedDia composeSemiCircle (repeat $ apply1C colorScheme)
@ -452,12 +455,20 @@ guardTriangle portDia =
-- 1 -> bottom
-- odds -> left
-- evens -> right
generalNestedGuard :: SpecialBackend b n =>
Colour Double -> (SpecialQDiagram b n -> SpecialQDiagram b n) -> SpecialQDiagram b n -> [Maybe (NodeName, Icon)] -> TransformableDia b n
generalNestedGuard :: SpecialBackend b n
=> Colour Double
-> (SpecialQDiagram b n -> SpecialQDiagram b n)
-> SpecialQDiagram b n
-> [Maybe NamedIcon]
-> TransformableDia b n
generalNestedGuard triangleColor lBracket bottomDia inputAndArgs name nestingLevel reflect angle = named name $ case inputAndArgs of
[] -> mempty
input : args -> centerXY finalDia where
finalDia = alignT (bottomDia <> makeQualifiedPort name resultPortConst) <> alignB (inputIcon === (bigVerticalLine <> guardDia <> makeQualifiedPort name inputPortConst))
finalDia = alignT (bottomDia <> makeQualifiedPort name resultPortConst)
<> alignB
(inputIcon === (bigVerticalLine
<> guardDia
<> makeQualifiedPort name inputPortConst))
iconMapper (Port portNum) arg
| even portNum = Right $ guardTriangle port ||| makeInnerIcon True arg
@ -475,13 +486,13 @@ generalNestedGuard triangleColor lBracket bottomDia inputAndArgs name nestingLev
verticalLine = strutY 0.4
inputIcon = makeInnerIcon False input
guardDia = vcat (alignT trianglesAndBrackets)
bigVerticalLine = alignT $ lwG defaultLineWidth $ lc triangleColor $ vrule (height guardDia)
makeInnerIcon innerReflected mNameAndIcon = case mNameAndIcon of
Nothing -> mempty
Just (iconNodeName, icon) -> if innerReflected
Just (NamedIcon iconNodeName icon) -> if innerReflected
then reflectX dia
else dia
where
@ -499,7 +510,7 @@ guardLBracket portDia = alignL (alignT ell) <> portDia
-- resultPortConst: Bottom result port
-- Ports 3,5...: The left ports for the booleans
-- Ports 2,4...: The right ports for the values
nestedGuardDia :: SpecialBackend b n => [Maybe (NodeName, Icon)] -> TransformableDia b n
nestedGuardDia :: SpecialBackend b n => [Maybe NamedIcon] -> TransformableDia b n
nestedGuardDia = generalNestedGuard lineCol guardLBracket mempty
-- TODO Improve design to be more than a circle.
@ -518,7 +529,7 @@ caseC portDia = caseResult <> portDia
-- resultPortConst: Bottom result port
-- Ports 3,5...: The left ports for the results
-- Ports 2,4...: The right ports for the patterns
nestedCaseDia :: SpecialBackend b n => [Maybe (NodeName, Icon)] -> TransformableDia b n
nestedCaseDia :: SpecialBackend b n => [Maybe NamedIcon] -> TransformableDia b n
nestedCaseDia = generalNestedGuard (patternC colorScheme) caseC caseResult
-- END Guard and case icons

View File

@ -29,8 +29,8 @@ import Icons(colorScheme, iconToDiagram, defaultLineWidth, ColorStyle(..), getPo
import TranslateCore(nodeToIcon)
import Types(Edge(..), Icon, EdgeOption(..), Drawing(..), EdgeEnd(..),
NameAndPort(..), SpecialQDiagram, SpecialBackend, SpecialNum, NodeName(..), Port(..),
SgNamedNode)
import Util(fromMaybeError, mapNodeInNamedNode)
SgNamedNode, NamedIcon(..))
import Util(fromMaybeError, mapNodeInNamedNode, namedIconToTuple, tupleToNamedIcon)
-- If the inferred types for these functions becomes unweildy,
-- try using PartialTypeSignitures.
@ -55,16 +55,20 @@ drawingToGraphvizScaleFactor = 0.15
-- TODO Refactor with syntaxGraphToFglGraph in TranslateCore
-- TODO Make this work with nested icons now that names are not qualified.
drawingToIconGraph :: Drawing -> Gr (NodeName, Icon) Edge
drawingToIconGraph :: Drawing -> Gr NamedIcon Edge
drawingToIconGraph (Drawing nodes edges) =
mkGraph nodes labeledEdges where
labeledEdges = fmap makeLabeledEdge edges
makeLabeledEdge e@(Edge _ _ (NameAndPort n1 _, NameAndPort n2 _)) =
((n1, lookupInNodes n1), (n2, lookupInNodes n2), e) where
lookupInNodes name = fromMaybeError errorString (lookup name nodes) where
errorString =
"syntaxGraphToFglGraph edge connects to non-existent node. Node NodeName ="
++ show name ++ " Edge=" ++ show e
(NamedIcon n1 (lookupInNodes n1), NamedIcon n2 (lookupInNodes n2), e)
where
lookupInNodes name = fromMaybeError
errorString
(lookup name (fmap namedIconToTuple nodes))
where
errorString =
"syntaxGraphToFglGraph edge connects to non-existent node. Node NodeName ="
++ show name ++ " Edge=" ++ show e
-- | Custom arrow tail for the arg1 result circle.
@ -134,8 +138,8 @@ nameAndPortToName (NameAndPort name mPort) = case mPort of
Nothing -> toName name
Just port -> name .> port
findPortAngles :: SpecialNum n => (NodeName, Icon) -> NameAndPort -> [Angle n]
findPortAngles (nodeName, nodeIcon) (NameAndPort diaName mPort) = case mPort of
findPortAngles :: SpecialNum n => NamedIcon -> NameAndPort -> [Angle n]
findPortAngles (NamedIcon nodeName nodeIcon) (NameAndPort diaName mPort) = case mPort of
Nothing -> []
Just port -> foundAngles where
mName = if nodeName == diaName then Nothing else Just diaName
@ -173,13 +177,13 @@ smallestAngleDiff (nodeFlip, nodeAngle) target angles = case angles of
(+) <$> angle <*> nodeAngle
lookupNodeAngle :: Show n => [((NodeName, Icon), (Bool, Angle n))] -> (NodeName, Icon) -> (Bool, Angle n)
lookupNodeAngle :: Show n => [(NamedIcon, (Bool, Angle n))] -> NamedIcon -> (Bool, Angle n)
lookupNodeAngle rotationMap key =
fromMaybeError ("nodeVector: key not in rotaionMap. key = " ++ show key ++ "\n\n rotationMap = " ++ show rotationMap)
$ lookup key rotationMap
makeEdge :: (SpecialBackend b n, ING.Graph gr) =>
gr (NodeName, Icon) Edge -> SpecialQDiagram b n -> [((NodeName, Icon), (Bool, Angle n))] ->
gr NamedIcon Edge -> SpecialQDiagram b n -> [(NamedIcon, (Bool, Angle n))] ->
ING.LEdge Edge -> SpecialQDiagram b n -> SpecialQDiagram b n
makeEdge graph dia rotationMap (node0, node1, edge@(Edge _ _ (namePort0, namePort1))) =
connectMaybePorts portAngles edge
@ -211,7 +215,7 @@ makeEdge graph dia rotationMap (node0, node1, edge@(Edge _ _ (namePort0, namePor
-- | addEdges draws the edges underneath the nodes.
addEdges :: (SpecialBackend b n, ING.Graph gr) =>
gr (NodeName, Icon) Edge -> (SpecialQDiagram b n, [((NodeName, Icon), (Bool, Angle n))]) -> SpecialQDiagram b n
gr NamedIcon Edge -> (SpecialQDiagram b n, [(NamedIcon, (Bool, Angle n))]) -> SpecialQDiagram b n
addEdges graph (dia, rotationMap) = dia <> applyAll connections dia
where
connections = makeEdge graph dia rotationMap <$> ING.labEdges graph
@ -235,12 +239,12 @@ scoreAngle iconPosition edges reflected angle = sum $ (^(2 :: Int)) <$> fmap edg
angleDiff = smallestAngleDiff (reflected, angle) shaftAngle portAngles
bestAngleForIcon :: (SpecialNum n, ING.Graph gr) =>
Map.Map (NodeName, Icon) (Point V2 n)
-> gr (NodeName, Icon) Edge
-> (NodeName, Icon)
Map.Map NamedIcon (Point V2 n)
-> gr NamedIcon Edge
-> NamedIcon
-> Bool
-> (Angle n, n)
bestAngleForIcon positionMap graph key@(NodeName nodeId, _) reflected =
bestAngleForIcon positionMap graph key@(NamedIcon (NodeName nodeId) _) reflected =
minimumBy (compare `on` snd) $ (\angle -> (angle, scoreAngle iconPosition edges reflected angle)) <$> fmap (@@ turn) possibleAngles
where
possibleAngles = [0,(1/24)..1]
@ -261,10 +265,10 @@ bestAngleForIcon positionMap graph key@(NodeName nodeId, _) reflected =
(_, nameAndPort) = edgeConnection edge
findIconRotation :: (SpecialNum n, ING.Graph gr) =>
Map.Map (NodeName, Icon) (Point V2 n)
-> gr (NodeName, Icon) Edge
-> (NodeName, Icon)
-> ((NodeName, Icon), (Bool, Angle n))
Map.Map NamedIcon (Point V2 n)
-> gr NamedIcon Edge
-> NamedIcon
-> (NamedIcon, (Bool, Angle n))
findIconRotation positionMap graph key = (key, (reflected, angle)) where
-- Smaller scores are better
(reflectedAngle, reflectedScore) = bestAngleForIcon positionMap graph key True
@ -273,19 +277,19 @@ findIconRotation positionMap graph key = (key, (reflected, angle)) where
angle = if reflected then reflectedAngle else nonReflectedAngle
rotateNodes :: (SpecialNum n, ING.Graph gr) =>
Map.Map (NodeName, Icon) (Point V2 n)
-> gr (NodeName, Icon) Edge
-> [((NodeName, Icon), (Bool, Angle n))]
Map.Map NamedIcon (Point V2 n)
-> gr NamedIcon Edge
-> [(NamedIcon, (Bool, Angle n))]
rotateNodes positionMap graph = findIconRotation positionMap graph <$> Map.keys positionMap
-- END rotateNodes --
type LayoutResult a b = Gr (GV.AttributeNode (NodeName, b)) (GV.AttributeNode a)
type LayoutResult a = Gr (GV.AttributeNode NamedIcon) (GV.AttributeNode a)
placeNodes :: forall a b gr. (SpecialBackend b Double, ING.Graph gr) =>
LayoutResult a Icon
-> gr (NodeName, Icon) Edge
-> (SpecialQDiagram b Double, [((NodeName, Icon), (Bool, Angle Double))])
LayoutResult a
-> gr NamedIcon Edge
-> (SpecialQDiagram b Double, [(NamedIcon, (Bool, Angle Double))])
placeNodes layoutResult graph = (mconcat placedNodes, rotationMap)
where
positionMap = fst $ getGraph layoutResult
@ -294,7 +298,7 @@ placeNodes layoutResult graph = (mconcat placedNodes, rotationMap)
placedNodes = fmap placeNode rotationMap
-- todo: Not sure if the diagrams should already be centered at this point.
placeNode (key@(name, icon), (reflected, angle)) = place transformedDia diaPosition where
placeNode (key@(NamedIcon name icon), (reflected, angle)) = place transformedDia diaPosition where
origDia = iconToDiagram icon name 0 reflected angle
transformedDia = centerXY $ rotate angle $ (if reflected then reflectX else id) origDia
diaPosition = graphvizScaleFactor *^ (positionMap Map.! key)
@ -320,20 +324,20 @@ customLayoutParams = GV.defaultParams{
doGraphLayout :: forall b.
SpecialBackend b Double =>
Gr (NodeName, Icon) Edge
Gr NamedIcon Edge
-> IO (SpecialQDiagram b Double)
doGraphLayout graph = do
layoutResult <- layoutGraph' layoutParams GVA.Neato graph
-- layoutResult <- layoutGraph' layoutParams GVA.Fdp graph
pure $ addEdges graph $ placeNodes layoutResult graph
where
layoutParams :: GV.GraphvizParams Int (NodeName,Icon) e () (NodeName,Icon)
layoutParams :: GV.GraphvizParams Int NamedIcon e () NamedIcon
--layoutParams :: GV.GraphvizParams Int l el Int l
layoutParams = customLayoutParams{
GV.fmtNode = nodeAttribute
}
nodeAttribute :: (Int, (NodeName, Icon)) -> [GV.Attribute]
nodeAttribute (_, (_, nodeIcon)) =
nodeAttribute :: (Int, NamedIcon) -> [GV.Attribute]
nodeAttribute (_, NamedIcon _ nodeIcon) =
-- GVA.Width and GVA.Height have a minimum of 0.01
--[GVA.Width diaWidth, GVA.Height diaHeight]
[GVA.Width circleDiameter, GVA.Height circleDiameter]
@ -359,5 +363,5 @@ renderIngSyntaxGraph ::
Gr SgNamedNode Edge -> IO (SpecialQDiagram b Double)
renderIngSyntaxGraph = renderIconGraph . ING.nmap (mapNodeInNamedNode nodeToIcon)
renderIconGraph :: SpecialBackend b Double => Gr (NodeName, Icon) Edge -> IO (SpecialQDiagram b Double)
renderIconGraph :: SpecialBackend b Double => Gr NamedIcon Edge -> IO (SpecialQDiagram b Double)
renderIconGraph = doGraphLayout

View File

@ -35,6 +35,8 @@ import Util(makeSimpleEdge, nameAndPort, justName)
import Icons(inputPort, resultPort, argumentPorts, caseRhsPorts,
casePatternPorts)
{-# ANN module "HLint: ignore Use record patterns" #-}
-- OVERVIEW --
-- The core functions and data types used in this module are in TranslateCore.
-- The TranslateCore also contains most/all of the translation functions that
@ -734,7 +736,7 @@ matchesToCase firstMatch@(Match srcLoc funName pats _ _) restOfMatches = do
allMatches = firstMatch:restOfMatches
alts = fmap matchToAlt allMatches
evalMatch :: Show l => EvalContext -> (Match l) -> State IDState SyntaxGraph
evalMatch :: Show l => EvalContext -> Match l -> State IDState SyntaxGraph
evalMatch c (Match _ name patterns rhs maybeWhereBinds) = do
let
matchFunNameString = nameToString name

View File

@ -40,10 +40,12 @@ import Data.Semigroup(Semigroup, (<>))
import Types(Icon, SyntaxNode(..), Edge(..), EdgeOption(..),
NameAndPort(..), IDState, SgNamedNode(..), NodeName(..), Port,
LikeApplyFlavor(..), CaseOrGuardTag(..), IDState(..))
import Util(noEnds, nameAndPort, makeSimpleEdge, justName, maybeBoolToBool, mapNodeInNamedNode, nodeNameToInt)
LikeApplyFlavor(..), CaseOrGuardTag(..), IDState(..), NamedIcon(..))
import Util(noEnds, nameAndPort, makeSimpleEdge, justName, maybeBoolToBool, mapNodeInNamedNode, nodeNameToInt, tupleToNamedIcon)
import Icons(Icon(..), inputPort, resultPort, argumentPorts, guardRhsPorts, guardBoolPorts)
{-# ANN module "HLint: ignore Use list comprehension" #-}
-- OVERVIEW --
-- This module has the core functions and data types used by Translate.
-- This module also contains most/all of the translation functions that
@ -258,10 +260,10 @@ nodeToIcon (CaseNode n) = CaseIcon n
nodeToIcon CaseResultNode = CaseResultIcon
nodeToIcon (NestedCaseOrGuardNode tag x edges) = nestedCaseOrGuardNodeToIcon tag x edges
makeArg :: [(SgNamedNode, Edge)] -> Port -> Maybe (NodeName, Icon)
makeArg :: [(SgNamedNode, Edge)] -> Port -> Maybe NamedIcon
makeArg args port = case find (findArg port) args of
Nothing -> Nothing
Just (SgNamedNode argName argSyntaxNode, _) -> Just (argName, nodeToIcon argSyntaxNode)
Just (SgNamedNode argName argSyntaxNode, _) -> Just $ NamedIcon argName (nodeToIcon argSyntaxNode)
nestedApplySyntaxNodeToIcon :: LikeApplyFlavor -> Int -> [(SgNamedNode, Edge)] -> Icon
nestedApplySyntaxNodeToIcon flavor numArgs args = NestedApply flavor argList where
@ -281,7 +283,7 @@ nestedCaseOrGuardNodeToIcon tag numArgs args = case tag of
nestedPatternNodeToIcon :: String -> [(Maybe SgNamedNode, String)] -> Icon
nestedPatternNodeToIcon str children = NestedPApp $
(Just (NodeName (-1), TextBoxIcon str), "")
(Just (NamedIcon (NodeName (-1)) (TextBoxIcon str)), "")
:
fmap (Arrow.first $ fmap (mapNodeInNamedNode nodeToIcon)) children

View File

@ -1,6 +1,7 @@
{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts, ConstraintKinds #-}
module Types (
NamedIcon(..),
Icon(..),
SyntaxNode(..),
NodeName(..),
@ -26,6 +27,9 @@ import Diagrams.TwoD.Text(Text)
import Data.Typeable(Typeable)
data NamedIcon = NamedIcon {niName :: NodeName, niIcon :: Icon}
deriving (Show, Eq, Ord)
-- TYPES --
-- | A datatype that represents an icon.
-- The TextBoxIcon's data is the text that appears in the text box.
@ -35,11 +39,13 @@ data Icon = TextBoxIcon String | GuardIcon Int
| FlatLambdaIcon [String] | ApplyAIcon Int | ComposeIcon Int
| PAppIcon Int String | CaseIcon Int | CaseResultIcon
| BindTextBoxIcon String
-- TODO: NestedApply should have the type NestedApply (Maybe (Name, Icon)) [Maybe (Name, Icon)]
| NestedApply LikeApplyFlavor [Maybe (NodeName, Icon)]
| NestedPApp [(Maybe (NodeName, Icon), String)]
| NestedCaseIcon [Maybe (NodeName, Icon)]
| NestedGuardIcon [Maybe (NodeName, Icon)]
-- TODO: NestedApply should have the type NestedApply (Maybe NamedIcon) [Maybe NamedIcon]
| NestedApply
LikeApplyFlavor -- apply or compose
[Maybe NamedIcon] -- list of arguments or functions
| NestedPApp [(Maybe NamedIcon, String)]
| NestedCaseIcon [Maybe NamedIcon]
| NestedGuardIcon [Maybe NamedIcon]
deriving (Show, Eq, Ord)
data LikeApplyFlavor = ApplyNodeFlavor | ComposeNodeFlavor deriving (Show, Eq, Ord)
@ -84,7 +90,7 @@ data EdgeEnd = EndAp1Result | EndAp1Arg | EndNone deriving (Show, Eq, Ord)
-- | A drawing is a map from names to Icons, a list of edges,
-- and a map of names to subDrawings
data Drawing = Drawing [(NodeName, Icon)] [Edge] deriving (Show, Eq)
data Drawing = Drawing [NamedIcon] [Edge] deriving (Show, Eq)
data SgNamedNode = SgNamedNode NodeName SyntaxNode deriving (Ord, Eq, Show)

View File

@ -19,7 +19,9 @@ module Util (
mapNodeInNamedNode,
sgNamedNodeToSyntaxNode,
nodeNameToInt,
customRenderSVG
customRenderSVG,
namedIconToTuple,
tupleToNamedIcon
)where
import Diagrams.Backend.SVG(renderSVG', Options(..), SVG)
@ -34,7 +36,7 @@ import Data.Text(pack)
import Data.Typeable(Typeable)
import Types(EdgeEnd(..), Edge(..), NameAndPort(..), Connection, NodeName(..), Port,
SyntaxNode, SgNamedNode(..))
SyntaxNode, SgNamedNode(..), NamedIcon(..), Icon(..))
mapFst :: Functor f => (a -> b) -> f (a, c) -> f (b, c)
mapFst f = fmap (first f)
@ -89,8 +91,8 @@ eitherToMaybes (Right y) = (Nothing, Just y)
maybeBoolToBool :: Maybe Bool -> Bool
maybeBoolToBool = or
mapNodeInNamedNode :: (SyntaxNode -> a) -> SgNamedNode -> (NodeName, a)
mapNodeInNamedNode f (SgNamedNode name node) = (name, f node)
mapNodeInNamedNode :: (SyntaxNode -> Icon) -> SgNamedNode -> NamedIcon
mapNodeInNamedNode f (SgNamedNode name node) = NamedIcon name (f node)
sgNamedNodeToSyntaxNode :: SgNamedNode -> SyntaxNode
sgNamedNodeToSyntaxNode (SgNamedNode _ n) = n
@ -98,6 +100,11 @@ sgNamedNodeToSyntaxNode (SgNamedNode _ n) = n
nodeNameToInt :: NodeName -> Int
nodeNameToInt (NodeName x) = x
namedIconToTuple :: NamedIcon -> (NodeName, Icon)
namedIconToTuple (NamedIcon x y) = (x, y)
tupleToNamedIcon :: (NodeName, Icon) -> NamedIcon
tupleToNamedIcon (x, y) = NamedIcon x y
customRenderSVG :: (Typeable n, Show n, RealFloat n) =>
FilePath

View File

@ -7,7 +7,7 @@ license: GPL-3
license-file: LICENSE
author: Robbie Gleichman
maintainer: rgleichman@gmail.com
copyright: 2016 Robbie Gleichman
copyright: 2018 Robbie Gleichman
category: Visual Programming
build-type: Simple
-- extra-source-files:

View File

@ -1,7 +1,7 @@
# For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md
# Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2)
resolver: lts-8.23
resolver: lts-12.14
# Local packages, usually specified by relative directory name
packages:
@ -9,7 +9,7 @@ packages:
# Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3)
extra-deps: [
"diagrams-graphviz-1.4"
"diagrams-graphviz-1.4.1"
]
# Override default flag values for local packages and extra-deps

View File

@ -1,4 +1,5 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
module VisualGraphAlgorithmTests (
visualCollapseTests
) where

View File

@ -1,4 +1,5 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
module VisualRenderingTests (
renderTests
) where
@ -7,9 +8,9 @@ import Diagrams.Prelude hiding ((#), (&))
import Rendering (renderDrawing)
import Types (NodeName(..), Drawing(..), Edge, Icon(..), Port(..), EdgeEnd(..),
LikeApplyFlavor(..), SpecialQDiagram, SpecialBackend)
LikeApplyFlavor(..), SpecialQDiagram, SpecialBackend, NamedIcon(..))
import Util(portToPort, iconToPort,
iconToIconEnds, iconTailToPort)
iconToIconEnds, iconTailToPort, tupleToNamedIcon)
iconToIntPort :: NodeName -> NodeName -> Int -> Edge
iconToIntPort x y p = iconToPort x y (Port p)
@ -20,7 +21,7 @@ intPortToPort x1 port1 x2 port2 = portToPort x1 (Port port1) x2 (Port port2)
drawing0 :: Drawing
drawing0 = Drawing d0Icons d0Edges where
[d0A, d0B, d0Res, d0Foo, d0Bar] = fmap NodeName [0..4] --["A", "B", "res", "foo", "bar"]
d0Icons =
d0Icons = fmap tupleToNamedIcon
[(d0A, ApplyAIcon 1),
(d0B, ApplyAIcon 1),
(d0Res, CaseResultIcon),
@ -45,7 +46,7 @@ fG0, fOne, fEq0, fMinus1, fEq0Ap, fMinus1Ap, fTimes, fRecurAp, fTimesAp, fArg, f
fact0Drawing :: Drawing
fact0Drawing = Drawing fact0Icons fact0Edges where
fact0Icons =
fact0Icons = fmap tupleToNamedIcon
[
(fG0, GuardIcon 2),
(fOne, TextBoxIcon "1"),
@ -75,8 +76,8 @@ fact0Drawing = Drawing fact0Icons fact0Edges where
]
fact1Icons :: [(NodeName, Icon)]
fact1Icons =
fact1Icons :: [NamedIcon]
fact1Icons = fmap tupleToNamedIcon
[
(fG0, GuardIcon 2),
(fOne, TextBoxIcon "1"),
@ -108,8 +109,8 @@ fact1Drawing = Drawing fact1Icons fact1Edges
-- fact2 is like fact1, but uses fTimesAp port 2 to distrubute the argument,
-- not fArg
fact2Icons :: [(NodeName, Icon)]
fact2Icons =
fact2Icons :: [NamedIcon]
fact2Icons = fmap tupleToNamedIcon
[
(fG0, GuardIcon 2),
(fOne, TextBoxIcon "1"),
@ -144,7 +145,7 @@ fact2Drawing = Drawing fact2Icons fact2Edges
arrowTestDrawing :: Drawing
arrowTestDrawing = Drawing arrowTestIcons arrowTestEdges where
[arr1, arr2, arr3, arr4] = fmap NodeName [0..3] --["arr1", "arr2", "arr3", "arr4"]
arrowTestIcons = [
arrowTestIcons = fmap tupleToNamedIcon [
(arr1, TextBoxIcon "1"),
(arr2, TextBoxIcon "2"),
(arr3, TextBoxIcon "3"),
@ -160,19 +161,22 @@ arrowTestDrawing = Drawing arrowTestIcons arrowTestEdges where
nestedTextDrawing :: Drawing
nestedTextDrawing = Drawing nestedTestIcons nestedTestEdges where
[n1, t1, t2, inner, t, n2, n3, foo, in1, n4] = fmap NodeName [0..9]
nestedTestIcons = [
nestedTestIcons = fmap tupleToNamedIcon [
(n1, NestedApply ApplyNodeFlavor args),
(t1, TextBoxIcon "T1"),
(t2, TextBoxIcon "t2")
]
where
innerArgs = [
innerArgs = fmap (fmap tupleToNamedIcon) [
Just (inner, TextBoxIcon "inner"),
Just (t, TextBoxIcon "t"),
Nothing,
Just (n2, NestedApply ApplyNodeFlavor [Just (n4, TextBoxIcon "N4"), Nothing])
Just (n2,
NestedApply
ApplyNodeFlavor
(fmap (fmap tupleToNamedIcon) [Just (n4, TextBoxIcon "N4"), Nothing]))
]
args = [
args = fmap (fmap tupleToNamedIcon) [
Just (n3, TextBoxIcon "n3"),
Nothing,
Just (foo, TextBoxIcon "3"),
@ -187,33 +191,34 @@ nestedTextDrawing = Drawing nestedTestIcons nestedTestEdges where
iconToIntPort t2 n2 2
]
-- TODO refactor these Drawings
nestedCaseDrawing :: Drawing
nestedCaseDrawing = Drawing icons [] where
[n0, n1, n2, n3, n4, n5, n6, n7, n8, n9] = fmap NodeName [0..9]
icons = [
icons = fmap tupleToNamedIcon [
(n0, NestedCaseIcon [Nothing, Nothing, Nothing]),
(n1, NestedCaseIcon [Nothing, Just (n2, TextBoxIcon "n2"), Nothing]),
(n3, NestedCaseIcon [Nothing, Nothing, Just (n4, TextBoxIcon "n4")]),
(n1, NestedCaseIcon [Nothing, Just $ NamedIcon n2 (TextBoxIcon "n2"), Nothing]),
(n3, NestedCaseIcon [Nothing, Nothing, Just $ NamedIcon n4 (TextBoxIcon "n4")]),
(n5, NestedCaseIcon [Nothing,
Just (n6, TextBoxIcon "n6"),
Just (n7, TextBoxIcon "n7"),
Just (n8, TextBoxIcon "n8"),
Just (n9, TextBoxIcon "n9")])
Just $ NamedIcon n6 (TextBoxIcon "n6"),
Just $ NamedIcon n7 (TextBoxIcon "n7"),
Just $ NamedIcon n8 (TextBoxIcon "n8"),
Just $ NamedIcon n9 (TextBoxIcon "n9")])
]
nestedGuardDrawing :: Drawing
nestedGuardDrawing = Drawing icons edges where
[n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10] = fmap NodeName [0..10]
icons = [
icons = fmap tupleToNamedIcon [
(n10, TextBoxIcon "n10"),
(n0, NestedGuardIcon [Nothing, Nothing, Nothing]),
(n1, NestedGuardIcon [Nothing, Just (n2, TextBoxIcon "n2"), Nothing]),
(n3, NestedGuardIcon [Nothing, Nothing, Just (n4, TextBoxIcon "n4")]),
(n1, NestedGuardIcon [Nothing, Just $ NamedIcon n2 (TextBoxIcon "n2"), Nothing]),
(n3, NestedGuardIcon [Nothing, Nothing, Just $ NamedIcon n4 (TextBoxIcon "n4")]),
(n5, NestedGuardIcon [Nothing,
Just (n6, TextBoxIcon "n6"),
Just (n7, TextBoxIcon "n7"),
Just (n8, TextBoxIcon "n8"),
Just (n9, TextBoxIcon "n9")])
Just $ NamedIcon n6 (TextBoxIcon "n6"),
Just $ NamedIcon n7 (TextBoxIcon "n7"),
Just $ NamedIcon n8 (TextBoxIcon "n8"),
Just $ NamedIcon n9 (TextBoxIcon "n9")])
]
edges = [
iconToIntPort n10 n5 0
@ -221,7 +226,7 @@ nestedGuardDrawing = Drawing icons edges where
flatCaseDrawing :: Drawing
flatCaseDrawing = Drawing icons edges where
icons = [
icons = fmap tupleToNamedIcon [
(NodeName 0, CaseIcon 0),
(NodeName 1, CaseIcon 1),
(NodeName 2, CaseIcon 2)
@ -230,7 +235,7 @@ flatCaseDrawing = Drawing icons edges where
flatGuardDrawing :: Drawing
flatGuardDrawing = Drawing icons edges where
icons = [
icons = fmap tupleToNamedIcon [
(NodeName 1, GuardIcon 1),
(NodeName 2, GuardIcon 2),
(NodeName 3, GuardIcon 3)

View File

@ -1,4 +1,5 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MonoLocalBinds #-}
module VisualTranslateTests(
visualTranslateTests
) where