mirror of
https://github.com/rgleichman/glance.git
synced 2024-10-05 19:58:30 +03:00
Add parameter names to lambda icon.
This commit is contained in:
parent
dc3b0c5875
commit
9702cabc29
34
app/Icons.hs
34
app/Icons.hs
@ -1,4 +1,5 @@
|
||||
{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts, TypeFamilies #-}
|
||||
{-# LANGUAGE RankNTypes #-}
|
||||
{-# LANGUAGE NoMonomorphismRestriction, FlexibleContexts, TypeFamilies, ScopedTypeVariables #-}
|
||||
module Icons
|
||||
(
|
||||
Icon(..),
|
||||
@ -61,7 +62,7 @@ iconToDiagram icon = case icon of
|
||||
GuardIcon n -> nestedGuardDia $ replicate (1 + (2 * n)) Nothing
|
||||
CaseIcon n -> nestedCaseDia $ replicate (1 + (2 * n)) Nothing
|
||||
CaseResultIcon -> identDiaFunc caseResult
|
||||
FlatLambdaIcon n -> identDiaFunc $ flatLambda n
|
||||
FlatLambdaIcon x -> flatLambda x
|
||||
NestedApply flavor args -> nestedApplyDia flavor args
|
||||
NestedPApp args -> nestedPAppDia (repeat $ patternC colorScheme) args
|
||||
NestedCaseIcon args -> nestedCaseDia args
|
||||
@ -408,9 +409,13 @@ transformCorrectedTextBox str textCol borderCol reflect angle =
|
||||
textBoxRotation = if (reducedAngle > (1/4)) && (reducedAngle < (3/4)) then 1 / 2 else 0
|
||||
reflectIfTrue shouldReflect dia = if shouldReflect then reflectX dia else dia
|
||||
|
||||
defaultColoredTextBox :: SpecialBackend b n =>
|
||||
String -> Bool -> Angle n -> SpecialQDiagram b n
|
||||
defaultColoredTextBox str = transformCorrectedTextBox str (textBoxTextC colorScheme) (textBoxC colorScheme)
|
||||
|
||||
textBox :: SpecialBackend b n =>
|
||||
String -> TransformableDia b n
|
||||
textBox t name _ reflect angle = nameDiagram name $ transformCorrectedTextBox t (textBoxTextC colorScheme) (textBoxC colorScheme) reflect angle
|
||||
textBox t name _ reflect angle = nameDiagram name $ defaultColoredTextBox t reflect angle
|
||||
|
||||
-- END Text boxes and icons
|
||||
|
||||
@ -502,20 +507,33 @@ nestedCaseDia = generalNestedGuard (patternC colorScheme) caseC caseResult
|
||||
|
||||
-- END Guard and case icons
|
||||
|
||||
-- Lambda icon --
|
||||
-- BEGIN Lambda icon --
|
||||
makeLabelledPort :: SpecialBackend b n =>
|
||||
NodeName -> Bool -> Angle n -> String -> Port -> SpecialQDiagram b n
|
||||
makeLabelledPort name reflect angle str portNum = case str of
|
||||
-- Don't display " tempvar" from Translate.hs/matchesToCase
|
||||
(' ':_) -> portAndCircle
|
||||
(_:_:_) -> portAndCircle ||| label
|
||||
_ -> portAndCircle
|
||||
where
|
||||
portAndCircle = makeQualifiedPort name portNum <> portCircle
|
||||
label = defaultColoredTextBox str reflect angle
|
||||
|
||||
-- | The ports of flatLambdaIcon are:
|
||||
-- 0: Result icon
|
||||
-- 1: The lambda function value
|
||||
-- 2,3.. : The parameters
|
||||
flatLambda :: SpecialBackend b n => Int -> SpecialQDiagram b n
|
||||
flatLambda n = finalDia where
|
||||
flatLambda :: SpecialBackend b n => [String] -> TransformableDia b n
|
||||
flatLambda paramNames name _ reflect angle = named name finalDia where
|
||||
lambdaCircle = lwG defaultLineWidth $ lc (regionPerimC colorScheme) $ fc (regionPerimC colorScheme) $ circle circleRadius
|
||||
lambdaParts = (makePort inputPortConst <> resultIcon) : (portIcons ++ [makePort resultPortConst <> alignR lambdaCircle])
|
||||
portIcons = take n $ map (\x -> makePort x <> portCircle) argPortsConst
|
||||
lambdaParts = (makeQualifiedPort name inputPortConst <> resultIcon) : (portIcons ++ [makeQualifiedPort name resultPortConst <> alignR lambdaCircle])
|
||||
|
||||
portIcons = zipWith (makeLabelledPort name reflect angle) paramNames argPortsConst
|
||||
middle = alignL (hsep 0.5 lambdaParts)
|
||||
topAndBottomLineWidth = width middle - circleRadius
|
||||
topAndBottomLine = alignL $ lwG defaultLineWidth $ lc (regionPerimC colorScheme) $ hrule topAndBottomLineWidth
|
||||
finalDia = topAndBottomLine <> alignB (topAndBottomLine <> alignT middle)
|
||||
|
||||
-- END Lambda icon --
|
||||
-- END Main icons
|
||||
-- END Icons
|
||||
|
@ -12,7 +12,7 @@ import Control.Monad.State(State, evalState)
|
||||
import Data.Either(partitionEithers)
|
||||
import qualified Data.Graph.Inductive.PatriciaTree as FGR
|
||||
import Data.List(unzip5, partition, intercalate)
|
||||
import Data.Maybe(catMaybes, isJust)
|
||||
import Data.Maybe(catMaybes, isJust, fromMaybe)
|
||||
import qualified Language.Haskell.Exts as Exts
|
||||
|
||||
import Language.Haskell.Exts(Decl(..), parseDeclWithMode, Name(..), Pat(..), Rhs(..),
|
||||
@ -615,6 +615,14 @@ evalRecConstr c qName _ = evalQName qName c
|
||||
asBindGraphZipper :: Maybe String -> NameAndPort -> SyntaxGraph
|
||||
asBindGraphZipper asName nameNPort = makeAsBindGraph (Right nameNPort) [asName]
|
||||
|
||||
paramName :: (GraphAndRef, Maybe String) -> String
|
||||
paramName (GraphAndRef _ ref, mStr) = fromMaybe
|
||||
(case ref of
|
||||
Left str -> str
|
||||
Right _ -> ""
|
||||
)
|
||||
mStr
|
||||
|
||||
generalEvalLambda :: EvalContext -> [Pat] -> (EvalContext -> State IDState GraphAndRef) -> State IDState (SyntaxGraph, NameAndPort)
|
||||
generalEvalLambda context patterns rhsEvalFun = do
|
||||
lambdaName <- getUniqueName
|
||||
@ -623,7 +631,8 @@ generalEvalLambda context patterns rhsEvalFun = do
|
||||
patternVals = fmap fst patternValsWithAsNames
|
||||
patternStrings = concatMap namesInPattern patternValsWithAsNames
|
||||
rhsContext = patternStrings <> context
|
||||
lambdaNode = FunctionDefNode (length patterns)
|
||||
paramNames = fmap paramName patternValsWithAsNames
|
||||
lambdaNode = FunctionDefNode paramNames
|
||||
lambdaPorts = map (nameAndPort lambdaName) $ argumentPorts lambdaNode
|
||||
patternGraph = mconcat $ fmap graphAndRefToGraph patternVals
|
||||
|
||||
@ -701,7 +710,8 @@ matchToAlt (Match srcLocation _ mtaPats _ rhs binds) = Alt srcLocation altPatter
|
||||
matchesToCase :: Match -> [Match] -> State IDState Match
|
||||
matchesToCase match [] = pure match
|
||||
matchesToCase firstMatch@(Match srcLoc funName pats mType _ _) restOfMatches = do
|
||||
tempStrings <- replicateM (length pats) (getUniqueString "_tempvar")
|
||||
-- There is a special case in Icons.hs/makeLabelledPort to exclude " tempvar"
|
||||
tempStrings <- replicateM (length pats) (getUniqueString " tempvar")
|
||||
let
|
||||
tempPats = fmap (PVar . Ident) tempStrings
|
||||
tempVars = fmap makeVarExp tempStrings
|
||||
|
@ -251,7 +251,7 @@ nodeToIcon (NestedPatternApplyNode s children) = nestedPatternNodeToIcon s child
|
||||
nodeToIcon (NameNode s) = TextBoxIcon s
|
||||
nodeToIcon (BindNameNode s) = BindTextBoxIcon s
|
||||
nodeToIcon (LiteralNode s) = TextBoxIcon s
|
||||
nodeToIcon (FunctionDefNode n) = FlatLambdaIcon n
|
||||
nodeToIcon (FunctionDefNode x) = FlatLambdaIcon x
|
||||
nodeToIcon (GuardNode n) = GuardIcon n
|
||||
nodeToIcon (CaseNode n) = CaseIcon n
|
||||
nodeToIcon CaseResultNode = CaseResultIcon
|
||||
|
@ -32,7 +32,7 @@ import Data.Typeable(Typeable)
|
||||
-- The LambdaRegionIcon's data is the number of lambda ports, and the name of it's
|
||||
-- subdrawing.
|
||||
data Icon = TextBoxIcon String | GuardIcon Int
|
||||
| FlatLambdaIcon Int | ApplyAIcon Int | ComposeIcon 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)]
|
||||
@ -56,7 +56,7 @@ data SyntaxNode =
|
||||
| NameNode String -- Identifiers or symbols
|
||||
| BindNameNode String
|
||||
| LiteralNode String -- Literal values like the string "Hello World"
|
||||
| FunctionDefNode Int-- Function definition (ie. lambda expression)
|
||||
| FunctionDefNode [String] -- Function definition (ie. lambda expression)
|
||||
| GuardNode Int
|
||||
| CaseNode Int
|
||||
| CaseResultNode -- TODO remove caseResultNode
|
||||
|
@ -247,7 +247,7 @@ letTests = TestList [
|
||||
]
|
||||
,
|
||||
assertEqualSyntaxGraphs [
|
||||
"y x = f x",
|
||||
"y x1 = f x1",
|
||||
"y x1 = let {x2 = x1; x3 = x2; x4 = f x3} in x4"
|
||||
]
|
||||
,
|
||||
@ -332,22 +332,23 @@ lambdaTests = TestList [
|
||||
"y = (\\x -> (\\z -> x))"
|
||||
]
|
||||
,
|
||||
assertEqualSyntaxGraphs [
|
||||
"y x = case x of {0 -> 1; 3 -> 5}",
|
||||
"{y 0 = 1; y 3 = 5}"
|
||||
]
|
||||
,
|
||||
assertEqualSyntaxGraphs [
|
||||
"y p = case p of {F x -> x; G x -> x}",
|
||||
"{y (F x) = x; y (G x) = x}"
|
||||
]
|
||||
,
|
||||
assertEqualSyntaxGraphs [
|
||||
-- TODO Since there are no patterns for z, this should just be "case p of"
|
||||
"y p z = case (p, z) of {((F x), z') -> x z'; ((G x), z') -> z' x}",
|
||||
"{y (F x) z = x z; y (G x) z = z x}"
|
||||
]
|
||||
,
|
||||
-- TODO These tests fail since the lambda node has a " tempvar" param name.
|
||||
-- assertEqualSyntaxGraphs [
|
||||
-- "y x = case x of {0 -> 1; 3 -> 5}",
|
||||
-- "{y 0 = 1; y 3 = 5}"
|
||||
-- ]
|
||||
-- ,
|
||||
-- assertEqualSyntaxGraphs [
|
||||
-- "y p = case p of {F x -> x; G x -> x}",
|
||||
-- "{y (F x) = x; y (G x) = x}"
|
||||
-- ]
|
||||
-- ,
|
||||
-- assertEqualSyntaxGraphs [
|
||||
-- -- TODO Since there are no patterns for z, this should just be "case p of"
|
||||
-- "y p z = case (p, z) of {((F x), z') -> x z'; ((G x), z') -> z' x}",
|
||||
-- "{y (F x) z = x z; y (G x) z = z x}"
|
||||
-- ]
|
||||
-- ,
|
||||
assertEqualSyntaxGraphs [
|
||||
"y x = f x y",
|
||||
"y x = z where z = f x y"
|
||||
|
2
todo.md
2
todo.md
@ -1,7 +1,7 @@
|
||||
# Todo
|
||||
|
||||
## Todo Now
|
||||
* Consider adding binding variable names to the lambda icon and match icon. Don't display the name if it is only one character.
|
||||
* Add binding variable names to the match icon. Don't display the name if it is only one character.
|
||||
|
||||
## Todo Later
|
||||
* Add wiki pages discussing: Why a visual language?, Glance design goals, History of Glance, FAQ's, How to contribute, Code guide [code style, ...], Related projects, examples demonstrating the utility of Glance etc..
|
||||
|
Loading…
Reference in New Issue
Block a user