2017-07-19 05:11:57 +03:00
|
|
|
{-# LANGUAGE NoMonomorphismRestriction, TupleSections #-}
|
2016-02-04 11:19:08 +03:00
|
|
|
module Translate(
|
2016-12-16 09:58:19 +03:00
|
|
|
translateStringToSyntaxGraph,
|
|
|
|
translateStringToCollapsedGraphAndDecl,
|
|
|
|
translateModuleToCollapsedGraphs
|
2016-02-04 11:19:08 +03:00
|
|
|
) where
|
|
|
|
|
2016-02-05 08:53:21 +03:00
|
|
|
import Diagrams.Prelude((<>))
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2016-11-28 04:25:30 +03:00
|
|
|
import Control.Monad(replicateM)
|
2016-02-06 08:07:06 +03:00
|
|
|
import Control.Monad.State(State, evalState)
|
2016-02-27 09:58:49 +03:00
|
|
|
import Data.Either(partitionEithers)
|
2016-12-26 12:25:14 +03:00
|
|
|
import qualified Data.Graph.Inductive.PatriciaTree as FGR
|
2016-12-26 08:45:58 +03:00
|
|
|
import Data.List(unzip5, partition, intercalate)
|
2017-01-02 04:43:00 +03:00
|
|
|
import Data.Maybe(catMaybes, isJust, fromMaybe)
|
2017-01-02 11:37:27 +03:00
|
|
|
|
2016-11-28 04:25:30 +03:00
|
|
|
import qualified Language.Haskell.Exts as Exts
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
import Language.Haskell.Exts(
|
|
|
|
Decl(..), parseDeclWithMode, Name(..), Pat(..), Rhs(..),
|
2016-11-28 04:25:30 +03:00
|
|
|
Exp(..), QName(..), fromParseResult, Match(..), QOp(..), GuardedRhs(..),
|
2016-12-16 11:47:48 +03:00
|
|
|
Stmt(..), Binds(..), Alt(..), Module(..), SpecialCon(..), prettyPrint)
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2016-11-28 04:25:30 +03:00
|
|
|
import GraphAlgorithms(collapseNodes)
|
2018-11-12 10:13:19 +03:00
|
|
|
import TranslateCore(
|
|
|
|
Reference, SyntaxGraph(..), EvalContext, GraphAndRef(..), SgSink(..),
|
|
|
|
syntaxGraphFromNodes, syntaxGraphFromNodesEdges, getUniqueName,
|
|
|
|
edgesForRefPortList, makeApplyGraph, makeGuardGraph, combineExpressions,
|
2016-03-28 02:49:58 +03:00
|
|
|
namesInPattern, lookupReference, deleteBindings, makeEdges,
|
2017-01-01 06:11:51 +03:00
|
|
|
makeBox, nTupleString, nTupleSectionString, nListString,
|
2018-11-12 10:13:19 +03:00
|
|
|
syntaxGraphToFglGraph, getUniqueString, bindsToSyntaxGraph,
|
|
|
|
SgBind(..), graphAndRefToGraph,
|
2016-12-28 02:14:01 +03:00
|
|
|
initialIdState)
|
2018-11-06 12:52:39 +03:00
|
|
|
import Types(Labeled(..), NameAndPort(..), IDState,
|
2016-12-29 11:15:17 +03:00
|
|
|
Edge, SyntaxNode(..), IngSyntaxGraph, NodeName, SgNamedNode(..),
|
2016-12-09 06:19:47 +03:00
|
|
|
LikeApplyFlavor(..))
|
2016-12-18 04:13:36 +03:00
|
|
|
import Util(makeSimpleEdge, nameAndPort, justName)
|
2016-12-29 11:15:17 +03:00
|
|
|
import Icons(inputPort, resultPort, argumentPorts, caseRhsPorts,
|
2016-12-30 10:40:10 +03:00
|
|
|
casePatternPorts)
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2018-10-28 10:25:31 +03:00
|
|
|
{-# ANN module "HLint: ignore Use record patterns" #-}
|
|
|
|
|
2016-02-27 09:58:49 +03:00
|
|
|
-- 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
|
|
|
|
-- do not use Language.Haskell.Exts.
|
2016-02-18 10:14:14 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN Helper Functions --
|
2016-12-12 12:06:21 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
makeVarExp :: l -> String -> Exp l
|
|
|
|
makeVarExp l = Var l . UnQual l . Ident l
|
2016-12-12 12:06:21 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
makeQVarOp :: l -> String -> QOp l
|
|
|
|
makeQVarOp l = QVarOp l . UnQual l . Ident l
|
2016-12-12 12:06:21 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
qOpToExp :: QOp l -> Exp l
|
|
|
|
qOpToExp (QVarOp l n) = Var l n
|
|
|
|
qOpToExp (QConOp l n) = Con l n
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
-- | Make a syntax graph that has the bindings for a list of "as pattern" (@)
|
|
|
|
-- names.
|
2016-12-26 08:45:58 +03:00
|
|
|
makeAsBindGraph :: Reference -> [Maybe String] -> SyntaxGraph
|
2018-11-12 10:13:19 +03:00
|
|
|
makeAsBindGraph ref asNames
|
|
|
|
= bindsToSyntaxGraph $ catMaybes $ fmap makeBind asNames
|
|
|
|
where
|
|
|
|
makeBind mName = case mName of
|
|
|
|
Nothing -> Nothing
|
|
|
|
Just asName -> Just $ SgBind asName ref
|
2016-12-26 08:45:58 +03:00
|
|
|
|
2016-12-27 11:37:59 +03:00
|
|
|
grNamePortToGrRef :: (SyntaxGraph, NameAndPort) -> GraphAndRef
|
|
|
|
grNamePortToGrRef (graph, np) = GraphAndRef graph (Right np)
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
bindOrAltHelper :: Show l =>
|
|
|
|
EvalContext
|
|
|
|
-> Pat l
|
|
|
|
-> Rhs l
|
|
|
|
-> Maybe (Binds l)
|
|
|
|
-> State IDState ((GraphAndRef, Maybe String), GraphAndRef)
|
2016-12-30 13:15:43 +03:00
|
|
|
bindOrAltHelper c pat rhs maybeWhereBinds = do
|
|
|
|
patGraphAndRef <- evalPattern pat
|
|
|
|
let
|
|
|
|
rhsContext = namesInPattern patGraphAndRef <> c
|
|
|
|
rhsGraphAndRef <- rhsWithBinds maybeWhereBinds rhs rhsContext
|
|
|
|
pure (patGraphAndRef, rhsGraphAndRef)
|
|
|
|
|
2017-01-02 11:37:27 +03:00
|
|
|
patternName :: (GraphAndRef, Maybe String) -> String
|
|
|
|
patternName (GraphAndRef _ ref, mStr) = fromMaybe
|
|
|
|
(case ref of
|
|
|
|
Left str -> str
|
|
|
|
Right _ -> ""
|
|
|
|
)
|
|
|
|
mStr
|
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END Helper Functions --
|
|
|
|
|
|
|
|
-- BEGIN Names helper functions --
|
2016-12-12 12:06:21 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
nameToString :: Exts.Name l -> String
|
|
|
|
nameToString (Ident _ s) = s
|
|
|
|
nameToString (Symbol _ s) = s
|
|
|
|
|
2018-11-05 09:54:17 +03:00
|
|
|
qNameToString :: Show l => QName l -> String
|
2018-11-12 10:13:19 +03:00
|
|
|
qNameToString (Qual _ (Exts.ModuleName _ modName) name)
|
|
|
|
= modName ++ "." ++ nameToString name
|
2017-07-19 09:47:28 +03:00
|
|
|
qNameToString (UnQual _ name) = nameToString name
|
|
|
|
qNameToString (Special _ (UnitCon _)) = "()"
|
|
|
|
qNameToString (Special _ (ListCon _)) = "[]"
|
|
|
|
qNameToString (Special _ (FunCon _)) = "(->)"
|
|
|
|
qNameToString (Special _ (TupleCon _ _ n)) = nTupleString n
|
|
|
|
qNameToString (Special _ (Cons _)) = "(:)"
|
2016-03-05 11:12:55 +03:00
|
|
|
-- unboxed singleton tuple constructor
|
2017-07-19 09:47:28 +03:00
|
|
|
qNameToString (Special _ (UnboxedSingleCon _)) = "(# #)"
|
2018-11-05 09:54:17 +03:00
|
|
|
qNameToString q = error $ "Unsupported syntax in qNameToSrting: " <> show q
|
2016-02-25 02:10:06 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END Names helper functions
|
|
|
|
|
|
|
|
-- BEGIN evalLit
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
-- This is in Translate and not Translate core since currently it is only used
|
|
|
|
-- by evalLit.
|
2016-12-26 12:25:14 +03:00
|
|
|
makeLiteral :: (Show x) => x -> State IDState (SyntaxGraph, NameAndPort)
|
|
|
|
makeLiteral = makeBox . show
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalLit :: Exts.Literal l -> State IDState (SyntaxGraph, NameAndPort)
|
|
|
|
evalLit (Exts.Int _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.Char _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.String _ x _) = makeLiteral x
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Print the Rational as a floating point.
|
2017-07-19 09:47:28 +03:00
|
|
|
evalLit (Exts.Frac _ x _) = makeLiteral x
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Test the unboxed literals
|
2017-07-19 09:47:28 +03:00
|
|
|
evalLit (Exts.PrimInt _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.PrimWord _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.PrimFloat _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.PrimDouble _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.PrimChar _ x _) = makeLiteral x
|
|
|
|
evalLit (Exts.PrimString _ x _) = makeLiteral x
|
2016-12-26 12:25:14 +03:00
|
|
|
|
|
|
|
-- END evalLit
|
|
|
|
|
|
|
|
-- BEGIN evalPattern
|
|
|
|
|
|
|
|
-- BEGIN evalPApp
|
2016-12-27 03:37:10 +03:00
|
|
|
asNameBind :: (GraphAndRef, Maybe String) -> Maybe SgBind
|
2016-12-27 12:32:51 +03:00
|
|
|
asNameBind (GraphAndRef _ ref, mAsName) = case mAsName of
|
2016-12-26 12:25:14 +03:00
|
|
|
Nothing -> Nothing
|
2016-12-27 03:37:10 +03:00
|
|
|
Just asName -> Just $ SgBind asName ref
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
patternArgumentMapper ::
|
|
|
|
((GraphAndRef, Maybe String), t)
|
|
|
|
-> (String, Either (GraphAndRef, t) (SgNamedNode, SyntaxGraph))
|
|
|
|
patternArgumentMapper (asGraphAndRef@(graphAndRef, _), port)
|
|
|
|
= (patName, eitherVal)
|
2017-01-02 11:37:27 +03:00
|
|
|
where
|
|
|
|
graph = graphAndRefToGraph graphAndRef
|
|
|
|
patName = patternName asGraphAndRef
|
|
|
|
|
|
|
|
eitherVal = case graph of
|
|
|
|
(SyntaxGraph [namedNode] [] _ _ _) -> Right (namedNode, graph)
|
|
|
|
_ -> Left (graphAndRef, port)
|
|
|
|
|
2016-12-28 07:40:50 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
graphToTuple ::
|
|
|
|
SyntaxGraph
|
|
|
|
-> ([SgNamedNode], [Edge], [SgSink], [SgBind], [(NodeName, NodeName)])
|
2016-12-28 07:40:50 +03:00
|
|
|
graphToTuple (SyntaxGraph a b c d e) = (a, b, c, d, e)
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
graphsToComponents ::
|
|
|
|
[SyntaxGraph]
|
|
|
|
-> ([SgNamedNode], [Edge], [SgSink], [SgBind], [(NodeName, NodeName)])
|
|
|
|
graphsToComponents graphs = (concat a, concat b, concat c, concat d, concat e)
|
|
|
|
where
|
|
|
|
(a, b, c, d, e) = unzip5 $ fmap graphToTuple graphs
|
2016-12-28 07:40:50 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
makeNestedPatternGraph ::
|
|
|
|
NodeName
|
|
|
|
-> String
|
|
|
|
-> [(GraphAndRef, Maybe String)]
|
|
|
|
-> (SyntaxGraph, NameAndPort)
|
2016-12-28 07:40:50 +03:00
|
|
|
makeNestedPatternGraph applyIconName funStr argVals = nestedApplyResult
|
2016-12-26 12:25:14 +03:00
|
|
|
where
|
2017-01-02 11:37:27 +03:00
|
|
|
dummyNode = NestedPatternApplyNode "" []
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
argsAndPorts
|
|
|
|
= zip argVals $ map (nameAndPort applyIconName) $ argumentPorts dummyNode
|
2016-12-28 07:40:50 +03:00
|
|
|
mappedArgs = fmap patternArgumentMapper argsAndPorts
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
(unnestedArgsAndPort, nestedNamedNodesAndGraphs)
|
|
|
|
= partitionEithers (fmap snd mappedArgs)
|
2016-12-28 07:40:50 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
(nestedArgs, _, nestedSinks, nestedBinds, nestedEMaps)
|
|
|
|
= graphsToComponents $ fmap snd nestedNamedNodesAndGraphs
|
2016-12-28 07:40:50 +03:00
|
|
|
|
2017-01-02 11:37:27 +03:00
|
|
|
argListMapper (str, arg) = case arg of
|
2018-11-06 12:52:39 +03:00
|
|
|
Left _ -> Labeled Nothing str
|
|
|
|
Right (namedNode, _) -> Labeled (Just namedNode) str
|
2016-12-28 07:40:50 +03:00
|
|
|
|
|
|
|
argList = fmap argListMapper mappedArgs
|
|
|
|
|
|
|
|
combinedGraph = combineExpressions True unnestedArgsAndPort
|
2016-12-29 11:15:17 +03:00
|
|
|
|
2017-01-02 11:37:27 +03:00
|
|
|
pAppNode = NestedPatternApplyNode funStr argList
|
2016-12-28 08:02:11 +03:00
|
|
|
icons = [SgNamedNode applyIconName pAppNode]
|
2016-12-26 12:25:14 +03:00
|
|
|
|
|
|
|
asNameBinds = catMaybes $ fmap asNameBind argVals
|
2016-12-28 07:40:50 +03:00
|
|
|
allBinds = nestedBinds <> asNameBinds
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
newEMap = ((\(SgNamedNode n _) -> (n, applyIconName)) <$> nestedArgs)
|
|
|
|
<> nestedEMaps
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2016-12-28 07:40:50 +03:00
|
|
|
newGraph = SyntaxGraph icons [] nestedSinks allBinds newEMap
|
2018-11-12 10:13:19 +03:00
|
|
|
nestedApplyResult = (newGraph <> combinedGraph
|
|
|
|
, nameAndPort applyIconName (resultPort pAppNode))
|
|
|
|
|
|
|
|
|
|
|
|
evalPApp :: Show l =>
|
|
|
|
QName l
|
|
|
|
-> [Pat l]
|
|
|
|
-> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-14 00:40:23 +03:00
|
|
|
evalPApp name patterns = case patterns of
|
|
|
|
[] -> makeBox constructorName
|
|
|
|
_ -> do
|
2016-12-28 01:58:09 +03:00
|
|
|
patName <- getUniqueName
|
2016-12-14 00:40:23 +03:00
|
|
|
evaledPatterns <- mapM evalPattern patterns
|
2016-12-28 07:40:50 +03:00
|
|
|
pure $ makeNestedPatternGraph patName constructorName evaledPatterns
|
2016-12-14 00:40:23 +03:00
|
|
|
where
|
2016-03-22 03:36:02 +03:00
|
|
|
constructorName = qNameToString name
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalPApp
|
|
|
|
|
|
|
|
-- BEGIN evalPLit
|
2017-07-19 09:47:28 +03:00
|
|
|
showLiteral :: Exts.Literal l -> String
|
|
|
|
showLiteral (Exts.Int _ x _) = show x
|
|
|
|
showLiteral (Exts.Char _ x _) = show x
|
|
|
|
showLiteral (Exts.String _ x _) = show x
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Print the Rational as a floating point.
|
2017-07-19 09:47:28 +03:00
|
|
|
showLiteral (Exts.Frac _ x _) = show x
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Test the unboxed literals
|
2017-07-19 09:47:28 +03:00
|
|
|
showLiteral (Exts.PrimInt _ x _) = show x
|
|
|
|
showLiteral (Exts.PrimWord _ x _) = show x
|
|
|
|
showLiteral (Exts.PrimFloat _ x _) = show x
|
|
|
|
showLiteral (Exts.PrimDouble _ x _) = show x
|
|
|
|
showLiteral (Exts.PrimChar _ x _) = show x
|
|
|
|
showLiteral (Exts.PrimString _ x _) = show x
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalPLit ::
|
|
|
|
Exts.Sign l -> Exts.Literal l -> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-26 12:25:14 +03:00
|
|
|
evalPLit sign l = case sign of
|
2017-07-19 09:47:28 +03:00
|
|
|
Exts.Signless _ -> evalLit l
|
|
|
|
Exts.Negative _ -> makeBox ('-' : showLiteral l)
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalPLit
|
2016-02-23 09:01:03 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalPAsPat :: Show l =>
|
|
|
|
Name l -> Pat l -> State IDState (GraphAndRef, Maybe String)
|
2016-03-05 00:24:09 +03:00
|
|
|
evalPAsPat n p = do
|
2016-12-27 11:37:59 +03:00
|
|
|
(GraphAndRef evaledPatGraph evaledPatRef, mInnerName) <- evalPattern p
|
2016-03-05 00:24:09 +03:00
|
|
|
let
|
2016-12-26 08:45:58 +03:00
|
|
|
outerName = nameToString n
|
|
|
|
asBindGraph = makeAsBindGraph (Left outerName) [mInnerName]
|
2018-11-12 10:13:19 +03:00
|
|
|
pure (GraphAndRef (asBindGraph <> evaledPatGraph) evaledPatRef
|
|
|
|
, Just outerName)
|
2016-12-26 08:45:58 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
makePatternResult :: Functor f =>
|
|
|
|
f (SyntaxGraph, NameAndPort) -> f (GraphAndRef, Maybe String)
|
|
|
|
makePatternResult
|
|
|
|
= fmap (\(graph, namePort) -> (GraphAndRef graph (Right namePort), Nothing))
|
2016-03-05 00:24:09 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalPattern :: Show l => Pat l -> State IDState (GraphAndRef, Maybe String)
|
2016-02-04 11:19:08 +03:00
|
|
|
evalPattern p = case p of
|
2017-07-19 09:47:28 +03:00
|
|
|
PVar _ n -> pure (GraphAndRef mempty (Left $ nameToString n), Nothing)
|
|
|
|
PLit _ s l -> makePatternResult $ evalPLit s l
|
|
|
|
PInfixApp l p1 qName p2 -> evalPattern (PApp l qName [p1, p2])
|
|
|
|
PApp _ name patterns -> makePatternResult $ evalPApp name patterns
|
2016-02-24 10:14:00 +03:00
|
|
|
-- TODO special tuple handling.
|
2017-07-19 09:47:28 +03:00
|
|
|
PTuple l _ patterns ->
|
2018-11-12 10:13:19 +03:00
|
|
|
makePatternResult $ evalPApp
|
|
|
|
(Exts.UnQual l . Ident l . nTupleString . length $ patterns)
|
|
|
|
patterns
|
2017-07-19 09:47:28 +03:00
|
|
|
PList l patterns ->
|
2018-11-12 10:13:19 +03:00
|
|
|
makePatternResult $ evalPApp
|
|
|
|
(Exts.UnQual l . Ident l . nListString . length $ patterns)
|
|
|
|
patterns
|
2017-07-19 09:47:28 +03:00
|
|
|
PParen _ pat -> evalPattern pat
|
|
|
|
PAsPat _ n subPat -> evalPAsPat n subPat
|
|
|
|
PWildCard _ -> makePatternResult $ makeBox "_"
|
2016-03-05 00:24:09 +03:00
|
|
|
_ -> error $ "evalPattern: No pattern in case for " ++ show p
|
|
|
|
-- TODO: Other cases
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalPattern
|
|
|
|
|
|
|
|
-- BEGIN evalQName
|
|
|
|
|
2016-03-05 05:49:02 +03:00
|
|
|
-- strToGraphRef is not in TranslateCore, since it is only used by evalQName.
|
2016-12-27 11:37:59 +03:00
|
|
|
strToGraphRef :: EvalContext -> String -> State IDState GraphAndRef
|
2016-03-05 05:49:02 +03:00
|
|
|
strToGraphRef c str = fmap mapper (makeBox str) where
|
|
|
|
mapper gr = if str `elem` c
|
2016-12-27 11:37:59 +03:00
|
|
|
then GraphAndRef mempty (Left str)
|
|
|
|
else grNamePortToGrRef gr
|
2016-03-05 05:49:02 +03:00
|
|
|
|
2018-11-05 09:54:17 +03:00
|
|
|
evalQName :: Show l => QName l -> EvalContext -> State IDState GraphAndRef
|
2016-12-14 00:40:23 +03:00
|
|
|
evalQName qName c = case qName of
|
2017-07-19 09:47:28 +03:00
|
|
|
UnQual _ _ -> graphRef
|
|
|
|
Qual _ _ _ -> graphRef
|
2016-12-27 11:37:59 +03:00
|
|
|
_ -> grNamePortToGrRef <$> makeBox qNameString
|
2016-12-14 00:40:23 +03:00
|
|
|
where
|
|
|
|
qNameString = qNameToString qName
|
|
|
|
graphRef = strToGraphRef c qNameString
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalQName
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
-- TODO Delete these commented out functions.
|
2017-07-19 09:47:28 +03:00
|
|
|
-- evalQOp :: QOp l -> EvalContext -> State IDState GraphAndRef
|
2016-03-28 02:49:58 +03:00
|
|
|
-- evalQOp (QVarOp n) = evalQName n
|
|
|
|
-- evalQOp (QConOp n) = evalQName n
|
2016-02-19 09:07:38 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
-- qOpToString :: QOp l -> String
|
2016-06-18 23:17:09 +03:00
|
|
|
-- qOpToString (QVarOp n) = qNameToString n
|
|
|
|
-- qOpToString (QConOp n) = qNameToString n
|
2016-03-22 05:11:19 +03:00
|
|
|
|
2016-12-07 04:02:54 +03:00
|
|
|
--findReferencedIcon :: Reference -> [(NodeName, Icon)] -> Maybe (Name, Icon)
|
|
|
|
-- findReferencedIcon :: Either t NameAndPort -> [(NodeName, t1)] -> Maybe (NodeName, t1)
|
2016-06-18 23:17:09 +03:00
|
|
|
-- findReferencedIcon (Left str) _ = Nothing
|
|
|
|
-- findReferencedIcon (Right (NameAndPort name _)) nameIconMap = (\x -> (name, x)) <$> lookup name nameIconMap
|
2016-04-09 09:54:59 +03:00
|
|
|
|
2016-12-07 08:09:04 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN apply and compose helper functions
|
2016-12-26 08:45:58 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
removeParen :: Exp l -> Exp l
|
2016-12-26 12:25:14 +03:00
|
|
|
removeParen e = case e of
|
2017-07-19 09:47:28 +03:00
|
|
|
Paren _ x -> removeParen x
|
2016-12-26 12:25:14 +03:00
|
|
|
_ -> e
|
2016-12-09 06:19:47 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalFunExpAndArgs :: Show l =>
|
|
|
|
EvalContext
|
|
|
|
-> LikeApplyFlavor
|
|
|
|
-> (Exp l, [Exp l])
|
|
|
|
-> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-30 10:40:10 +03:00
|
|
|
evalFunExpAndArgs c flavor (funExp, argExps) = do
|
2016-02-10 05:58:28 +03:00
|
|
|
funVal <- evalExp c funExp
|
|
|
|
argVals <- mapM (evalExp c) argExps
|
2016-12-28 01:58:09 +03:00
|
|
|
applyIconName <- getUniqueName
|
2018-11-12 10:13:19 +03:00
|
|
|
pure
|
|
|
|
$ makeApplyGraph (length argExps) flavor False applyIconName funVal argVals
|
2016-02-19 09:07:38 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END apply and compose helper functions
|
2016-03-05 08:35:23 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN evalInfixApp
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalFunctionComposition :: Show l =>
|
|
|
|
EvalContext -> [Exp l] -> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-30 10:40:10 +03:00
|
|
|
evalFunctionComposition c functions = do
|
2016-12-12 09:19:23 +03:00
|
|
|
let reversedFunctios = reverse functions
|
|
|
|
evaluatedFunctions <- mapM (evalExp c) reversedFunctios
|
|
|
|
neverUsedPort <- Left <$> getUniqueString "unusedArgument"
|
2016-12-28 01:58:09 +03:00
|
|
|
applyIconName <- getUniqueName
|
2018-11-12 10:13:19 +03:00
|
|
|
pure $ makeApplyGraph
|
|
|
|
(length evaluatedFunctions)
|
|
|
|
ComposeNodeFlavor
|
|
|
|
False
|
|
|
|
applyIconName
|
|
|
|
(GraphAndRef mempty neverUsedPort)
|
|
|
|
evaluatedFunctions
|
2016-12-12 09:19:23 +03:00
|
|
|
|
2016-12-30 10:40:10 +03:00
|
|
|
-- | Turn (a . b . c) into [a, b, c]
|
2017-07-19 09:47:28 +03:00
|
|
|
compositionToList :: Exp l -> [Exp l]
|
2016-12-30 10:40:10 +03:00
|
|
|
compositionToList e = case removeParen e of
|
2018-11-12 10:13:19 +03:00
|
|
|
(InfixApp _ exp1 (QVarOp _ (UnQual _ (Symbol _ "."))) exp2)
|
|
|
|
-> exp1 : compositionToList exp2
|
2016-12-12 09:19:23 +03:00
|
|
|
x -> [x]
|
|
|
|
|
2016-12-30 10:40:10 +03:00
|
|
|
-- | In the general case, infix is converted to prefix.
|
|
|
|
-- Special cases:
|
|
|
|
-- a $ b is converted to (a b)
|
|
|
|
-- (a . b . c) uses the compose apply icon with no argument
|
2018-11-12 10:13:19 +03:00
|
|
|
evalInfixApp :: Show l =>
|
|
|
|
l -> EvalContext -> Exp l -> QOp l -> Exp l -> State IDState GraphAndRef
|
2017-07-19 09:47:28 +03:00
|
|
|
evalInfixApp l c e1 op e2 = case op of
|
|
|
|
QVarOp _ (UnQual _ (Symbol _ sym)) -> case sym of
|
|
|
|
"$" -> evalExp c (App l e1 e2)
|
2018-11-12 10:13:19 +03:00
|
|
|
"." -> grNamePortToGrRef
|
|
|
|
<$> evalFunctionComposition c (e1 : compositionToList e2)
|
2016-12-14 00:40:23 +03:00
|
|
|
_ -> defaultCase
|
|
|
|
_ -> defaultCase
|
|
|
|
where
|
2017-07-19 09:47:28 +03:00
|
|
|
defaultCase = evalExp c $ App l (App l (qOpToExp op) e1) e2
|
2016-12-09 06:19:47 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalInfixApp
|
|
|
|
|
|
|
|
-- BEGIN evaluateAppExpression
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
simplifyExp :: Exp l -> Exp l
|
2016-12-30 10:40:10 +03:00
|
|
|
simplifyExp e = case removeParen e of
|
2017-07-19 09:47:28 +03:00
|
|
|
InfixApp l exp1 (QVarOp _ (UnQual _ (Symbol _ "$"))) exp2 -> App l exp1 exp2
|
2016-12-30 10:40:10 +03:00
|
|
|
-- Don't convert compose to apply
|
2017-07-19 09:47:28 +03:00
|
|
|
InfixApp _ _ (QVarOp _ (UnQual _ (Symbol _ "."))) _ -> e
|
2018-11-12 10:13:19 +03:00
|
|
|
App l (Var _ (UnQual _ (Symbol _ "<$>"))) arg
|
|
|
|
-> App l (makeVarExp l "fmap") arg
|
2017-07-19 09:47:28 +03:00
|
|
|
InfixApp l exp1 op exp2 -> App l (App l (qOpToExp op) exp1) exp2
|
|
|
|
LeftSection l exp1 op -> App l (qOpToExp op) exp1
|
2016-12-30 10:40:10 +03:00
|
|
|
x -> x
|
|
|
|
|
|
|
|
-- | Given two expressions f and x, where f is applied to x,
|
|
|
|
-- return the nesting depth if (f x) is rendered with
|
|
|
|
-- the (normal apply icon, compose apply icon)
|
2017-07-19 09:47:28 +03:00
|
|
|
applyComposeScoreHelper :: Exp l -> Exp l -> (Int, Int)
|
2016-12-30 10:40:10 +03:00
|
|
|
applyComposeScoreHelper exp1 exp2 = (appScore, compScore) where
|
2016-12-09 06:19:47 +03:00
|
|
|
(e1App, e1Comp) = applyComposeScore exp1
|
|
|
|
(e2App, e2Comp) = applyComposeScore exp2
|
|
|
|
|
|
|
|
leftApp = min e1App (1 + e1Comp)
|
|
|
|
rightApp = 1 + min e2App e2Comp
|
|
|
|
|
|
|
|
appScore = max leftApp rightApp
|
|
|
|
|
|
|
|
leftComp = 1 + min e1App e1Comp
|
|
|
|
rightComp = min (1 + e2App) e2Comp
|
2018-11-11 14:17:06 +03:00
|
|
|
|
2016-12-09 06:19:47 +03:00
|
|
|
compScore = max leftComp rightComp
|
|
|
|
|
|
|
|
-- TODO Consider putting this logic in a separate "simplifyExpression" function.
|
2018-11-12 10:13:19 +03:00
|
|
|
-- | Returns the amount of nesting if the App is converted to
|
|
|
|
-- (applyNode, composeNode)
|
2017-07-19 09:47:28 +03:00
|
|
|
applyComposeScore :: Exp l -> (Int, Int)
|
2016-12-13 12:53:04 +03:00
|
|
|
applyComposeScore e = case simplifyExp e of
|
2017-07-19 09:47:28 +03:00
|
|
|
App _ exp1 exp2 -> applyComposeScoreHelper exp1 exp2
|
2016-12-12 09:19:23 +03:00
|
|
|
_ -> (0, 0)
|
2016-12-09 06:19:47 +03:00
|
|
|
|
|
|
|
-- Todo add test for this function
|
2016-12-30 10:40:10 +03:00
|
|
|
-- | Given an App expression, return
|
|
|
|
-- (function, list of arguments)
|
2017-07-19 09:47:28 +03:00
|
|
|
appExpToFuncArgs :: Exp l -> (Exp l, [Exp l])
|
2016-12-30 10:40:10 +03:00
|
|
|
appExpToFuncArgs e = case simplifyExp e of
|
2017-07-19 09:47:28 +03:00
|
|
|
App _ exp1 exp2 -> (funExp, args <> [exp2])
|
2016-12-13 12:53:04 +03:00
|
|
|
where
|
2016-12-30 10:40:10 +03:00
|
|
|
(funExp, args) = appExpToFuncArgs exp1
|
2016-12-13 12:53:04 +03:00
|
|
|
x -> (x, [])
|
2016-02-06 08:07:06 +03:00
|
|
|
|
2016-12-30 10:40:10 +03:00
|
|
|
-- | Given and App expression, return
|
|
|
|
-- (argument, list composed functions)
|
2017-07-19 09:47:28 +03:00
|
|
|
appExpToArgFuncs :: Exp l -> (Exp l, [Exp l])
|
2016-12-30 10:40:10 +03:00
|
|
|
appExpToArgFuncs e = case simplifyExp e of
|
2017-07-19 09:47:28 +03:00
|
|
|
App _ exp1 exp2 -> (argExp, funcs <> [exp1])
|
2016-12-09 06:19:47 +03:00
|
|
|
where
|
2016-12-30 10:40:10 +03:00
|
|
|
(argExp, funcs) = appExpToArgFuncs exp2
|
2016-12-09 06:19:47 +03:00
|
|
|
simpleExp -> (simpleExp, [])
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
removeCompose :: l -> Exp l -> Exp l -> Exp l
|
|
|
|
removeCompose l f x = case removeParen f of
|
2018-11-12 10:13:19 +03:00
|
|
|
(InfixApp _ f1 (QVarOp _ (UnQual _ (Symbol _ "."))) f2)
|
|
|
|
-> App l f1 $ removeCompose l f2 x
|
2017-07-19 09:47:28 +03:00
|
|
|
_ -> App l f x
|
2016-12-26 12:25:14 +03:00
|
|
|
|
|
|
|
-- TODO Refactor this and all sub-expressions
|
2018-11-12 10:13:19 +03:00
|
|
|
evalApp :: Show l =>
|
|
|
|
l -> EvalContext -> Exp l -> Exp l -> State IDState (SyntaxGraph, NameAndPort)
|
2017-07-19 09:47:28 +03:00
|
|
|
evalApp l c f e = if appScore <= compScore
|
2016-12-30 10:40:10 +03:00
|
|
|
then evalFunExpAndArgs c ApplyNodeFlavor (appExpToFuncArgs noComposeExp)
|
|
|
|
else evalFunExpAndArgs c ComposeNodeFlavor (appExpToArgFuncs noComposeExp)
|
2016-12-26 12:25:14 +03:00
|
|
|
where
|
2017-07-19 09:47:28 +03:00
|
|
|
noComposeExp = removeCompose l f e
|
2016-12-26 12:25:14 +03:00
|
|
|
(appScore, compScore) = applyComposeScore noComposeExp
|
|
|
|
|
|
|
|
-- END evaluateAppExpression
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalIf :: Show l =>
|
|
|
|
EvalContext
|
|
|
|
-> Exp l
|
|
|
|
-> Exp l
|
|
|
|
-> Exp l
|
|
|
|
-> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-30 13:15:43 +03:00
|
|
|
evalIf c boolExp trueExp falseExp = makeGuardGraph 2
|
2016-12-30 10:40:10 +03:00
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
-- Use (pure <$>) to put the evaluated expression in a single item list
|
2016-12-30 13:15:43 +03:00
|
|
|
(pure <$> evalExp c boolExp)
|
2016-12-30 10:40:10 +03:00
|
|
|
<*>
|
2016-12-30 13:15:43 +03:00
|
|
|
mapM (evalExp c) [trueExp, falseExp]
|
2016-02-18 02:36:57 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN evalGeneralLet
|
2016-02-23 09:01:03 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
getBoundVarName :: Show l => Decl l -> [String]
|
2016-02-23 00:26:47 +03:00
|
|
|
-- TODO Should evalState be used here?
|
2018-11-12 10:13:19 +03:00
|
|
|
getBoundVarName (PatBind _ pat _ _)
|
|
|
|
= namesInPattern $ evalState (evalPattern pat) initialIdState
|
2017-07-19 09:47:28 +03:00
|
|
|
getBoundVarName (FunBind _ (Match _ name _ _ _:_)) = [nameToString name]
|
2016-03-05 05:49:02 +03:00
|
|
|
-- TODO: Other cases
|
2016-03-06 09:26:03 +03:00
|
|
|
getBoundVarName (TypeSig _ _ _) = []
|
2018-11-12 10:13:19 +03:00
|
|
|
getBoundVarName decl
|
|
|
|
= error $ "getBoundVarName: No pattern in case for " ++ show decl
|
2016-02-21 05:47:56 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalBinds :: Show l =>
|
|
|
|
EvalContext -> Binds l -> State IDState (SyntaxGraph, EvalContext)
|
2017-07-19 09:47:28 +03:00
|
|
|
evalBinds c (BDecls _ decls) =
|
2016-02-21 05:47:56 +03:00
|
|
|
let
|
2016-02-22 07:26:12 +03:00
|
|
|
boundNames = concatMap getBoundVarName decls
|
2016-02-21 05:47:56 +03:00
|
|
|
augmentedContext = boundNames <> c
|
2017-01-01 06:11:51 +03:00
|
|
|
in
|
|
|
|
((,augmentedContext) . mconcat) <$> mapM (evalDecl augmentedContext) decls
|
2018-11-05 09:54:17 +03:00
|
|
|
evalBinds _ binds = error $ "Unsupported syntax in evalBinds: " <> show binds
|
2016-02-21 05:47:56 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalGeneralLet :: Show l =>
|
|
|
|
(EvalContext -> State IDState GraphAndRef)
|
|
|
|
-> EvalContext
|
|
|
|
-> Binds l
|
|
|
|
-> State IDState GraphAndRef
|
2016-02-22 06:34:33 +03:00
|
|
|
evalGeneralLet expOrRhsEvaler c bs = do
|
2016-02-21 09:35:13 +03:00
|
|
|
(bindGraph, bindContext) <- evalBinds c bs
|
2016-02-22 06:34:33 +03:00
|
|
|
expVal <- expOrRhsEvaler bindContext
|
2016-02-21 05:47:56 +03:00
|
|
|
let
|
2016-12-27 11:37:59 +03:00
|
|
|
GraphAndRef expGraph expResult = expVal
|
2016-02-22 02:15:16 +03:00
|
|
|
newGraph = deleteBindings . makeEdges $ expGraph <> bindGraph
|
2016-12-27 03:37:10 +03:00
|
|
|
bindings = sgBinds bindGraph
|
2016-12-27 11:37:59 +03:00
|
|
|
pure $ GraphAndRef newGraph (lookupReference bindings expResult)
|
2016-02-20 00:46:14 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalGeneralLet
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalLet :: Show l => EvalContext -> Binds l -> Exp l-> State IDState GraphAndRef
|
2016-02-22 06:34:33 +03:00
|
|
|
evalLet context binds e = evalGeneralLet (`evalExp` e) context binds
|
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN rhsWithBinds
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalStmt :: Show l => EvalContext -> Stmt l -> State IDState GraphAndRef
|
|
|
|
evalStmt c (Qualifier _ e) = evalExp c e
|
2018-11-05 09:54:17 +03:00
|
|
|
evalStmt _ q = error $ "Unsupported syntax in evalStmt: " <> show q
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalStmts :: Show l => EvalContext -> [Stmt l] -> State IDState GraphAndRef
|
2016-12-26 12:25:14 +03:00
|
|
|
evalStmts c [stmt] = evalStmt c stmt
|
2018-11-05 09:54:17 +03:00
|
|
|
evalStmts _ stmts = error $ "Unsupported syntax in evalStmts: " <> show stmts
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalGuardedRhs :: Show l =>
|
|
|
|
EvalContext -> GuardedRhs l -> State IDState (GraphAndRef, GraphAndRef)
|
|
|
|
evalGuardedRhs c (GuardedRhs _ stmts e)
|
|
|
|
= (,) <$> evalStmts c stmts <*> evalExp c e
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalGuardedRhss :: Show l =>
|
|
|
|
EvalContext -> [GuardedRhs l] -> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-30 10:40:10 +03:00
|
|
|
evalGuardedRhss c rhss = let
|
|
|
|
evaledRhss = unzip <$> mapM (evalGuardedRhs c) rhss
|
|
|
|
in
|
|
|
|
makeGuardGraph (length rhss)
|
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
fmap fst evaledRhss
|
|
|
|
<*>
|
|
|
|
fmap snd evaledRhss
|
2016-12-26 12:25:14 +03:00
|
|
|
|
|
|
|
-- | First argument is the right hand side.
|
|
|
|
-- The second arugement is a list of strings that are bound in the environment.
|
2017-07-19 09:47:28 +03:00
|
|
|
evalRhs :: Show l => EvalContext -> Rhs l -> State IDState GraphAndRef
|
|
|
|
evalRhs c (UnGuardedRhs _ e) = evalExp c e
|
|
|
|
evalRhs c (GuardedRhss _ rhss) = grNamePortToGrRef <$> evalGuardedRhss c rhss
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
rhsWithBinds :: Show l =>
|
|
|
|
Maybe (Binds l) -> Rhs l -> EvalContext -> State IDState GraphAndRef
|
2016-12-26 12:25:14 +03:00
|
|
|
rhsWithBinds maybeWhereBinds rhs rhsContext = case maybeWhereBinds of
|
|
|
|
Nothing -> evalRhs rhsContext rhs
|
|
|
|
Just b -> evalGeneralLet (`evalRhs` rhs) rhsContext b
|
|
|
|
|
|
|
|
-- END rhsWithBinds
|
|
|
|
|
|
|
|
-- BEGIN evalCase
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
-- TODO patRhsAreConnected is sometimes incorrectly true if the pat is just a
|
|
|
|
-- name
|
|
|
|
evalPatAndRhs :: Show l =>
|
|
|
|
EvalContext
|
|
|
|
-> Pat l
|
|
|
|
-> Rhs l
|
|
|
|
-> Maybe (Binds l)
|
|
|
|
-> State IDState (Bool, SyntaxGraph, Reference, Reference, Maybe String)
|
2016-02-24 07:47:08 +03:00
|
|
|
evalPatAndRhs c pat rhs maybeWhereBinds = do
|
2016-12-30 13:15:43 +03:00
|
|
|
((GraphAndRef patGraph patRef, mPatAsName), GraphAndRef rhsGraph rhsRef) <-
|
|
|
|
bindOrAltHelper c pat rhs maybeWhereBinds
|
2016-02-24 07:47:08 +03:00
|
|
|
let
|
|
|
|
grWithEdges = makeEdges (rhsGraph <> patGraph)
|
2016-12-27 03:37:10 +03:00
|
|
|
lookedUpRhsRef = lookupReference (sgBinds grWithEdges) rhsRef
|
2018-11-12 10:13:19 +03:00
|
|
|
-- The pattern and rhs are conneted if makeEdges added extra edges, or if
|
|
|
|
-- the rhsRef refers to a source in the pattern.
|
|
|
|
patRhsAreConnected
|
|
|
|
= (rhsRef /= lookedUpRhsRef)
|
|
|
|
|| ( length (sgEdges grWithEdges)
|
|
|
|
>
|
|
|
|
(length (sgEdges rhsGraph) + length (sgEdges patGraph)))
|
|
|
|
pure (patRhsAreConnected
|
|
|
|
, deleteBindings grWithEdges
|
|
|
|
, patRef
|
|
|
|
, lookedUpRhsRef
|
|
|
|
, mPatAsName)
|
2016-02-24 07:47:08 +03:00
|
|
|
|
|
|
|
-- returns (combined graph, pattern reference, rhs reference)
|
2018-11-12 10:13:19 +03:00
|
|
|
evalAlt :: Show l =>
|
|
|
|
EvalContext
|
|
|
|
-> Exts.Alt l
|
|
|
|
-> State IDState (Bool, SyntaxGraph, Reference, Reference, Maybe String)
|
2016-02-27 09:58:49 +03:00
|
|
|
evalAlt c (Exts.Alt _ pat rhs maybeBinds) = evalPatAndRhs c pat rhs maybeBinds
|
2016-02-24 07:47:08 +03:00
|
|
|
|
2017-01-01 06:44:43 +03:00
|
|
|
evalCaseHelper ::
|
|
|
|
Int
|
|
|
|
-> NodeName
|
|
|
|
-> [NodeName]
|
|
|
|
-> GraphAndRef
|
|
|
|
-> [(Bool, SyntaxGraph, Reference, Reference, Maybe String)]
|
|
|
|
-> (SyntaxGraph, NameAndPort)
|
2018-11-12 10:13:19 +03:00
|
|
|
evalCaseHelper numAlts caseIconName resultIconNames
|
|
|
|
(GraphAndRef expGraph expRef) evaledAlts
|
|
|
|
= result
|
|
|
|
where
|
|
|
|
(patRhsConnected, altGraphs, patRefs, rhsRefs, asNames) = unzip5 evaledAlts
|
|
|
|
combindedAltGraph = mconcat altGraphs
|
|
|
|
caseNode = CaseNode numAlts
|
|
|
|
icons = [SgNamedNode caseIconName caseNode]
|
|
|
|
caseGraph = syntaxGraphFromNodes icons
|
|
|
|
expEdge = (expRef, nameAndPort caseIconName (inputPort caseNode))
|
|
|
|
patEdges = zip patRefs $ map (nameAndPort caseIconName) casePatternPorts
|
|
|
|
rhsEdges = zip patRhsConnected $ zip rhsRefs
|
|
|
|
$ map (nameAndPort caseIconName) caseRhsPorts
|
|
|
|
(connectedRhss, unConnectedRhss) = partition fst rhsEdges
|
|
|
|
|
|
|
|
makeCaseResult :: NodeName -> Reference -> SyntaxGraph
|
|
|
|
makeCaseResult resultIconName rhsRef = case rhsRef of
|
|
|
|
Left _ -> mempty
|
|
|
|
Right rhsPort -> syntaxGraphFromNodesEdges rhsNewIcons rhsNewEdges
|
|
|
|
where
|
|
|
|
rhsNewIcons = [SgNamedNode resultIconName CaseResultNode]
|
|
|
|
rhsNewEdges = [makeSimpleEdge (rhsPort, justName resultIconName)]
|
|
|
|
|
|
|
|
caseResultGraphs =
|
|
|
|
mconcat
|
|
|
|
$ zipWith makeCaseResult resultIconNames (fmap (fst . snd) connectedRhss)
|
|
|
|
filteredRhsEdges = fmap snd unConnectedRhss
|
|
|
|
patternEdgesGraph = edgesForRefPortList True patEdges
|
|
|
|
caseEdgeGraph = edgesForRefPortList False (expEdge : filteredRhsEdges)
|
|
|
|
|
|
|
|
bindGraph = makeAsBindGraph expRef asNames
|
|
|
|
|
|
|
|
finalGraph = deleteBindings $ makeEdges $ mconcat [bindGraph
|
|
|
|
, patternEdgesGraph
|
|
|
|
, caseResultGraphs
|
|
|
|
, expGraph
|
|
|
|
, caseEdgeGraph
|
|
|
|
, caseGraph
|
|
|
|
, combindedAltGraph]
|
|
|
|
result = (finalGraph, nameAndPort caseIconName (resultPort caseNode))
|
|
|
|
|
|
|
|
|
|
|
|
evalCase :: Show l =>
|
|
|
|
EvalContext -> Exp l -> [Alt l] -> State IDState (SyntaxGraph, NameAndPort)
|
2017-01-01 06:44:43 +03:00
|
|
|
evalCase c e alts =
|
2016-02-24 07:47:08 +03:00
|
|
|
let
|
2017-01-01 06:44:43 +03:00
|
|
|
numAlts = length alts
|
|
|
|
in
|
|
|
|
evalCaseHelper (length alts)
|
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
replicateM numAlts getUniqueName
|
|
|
|
<*>
|
|
|
|
evalExp c e
|
|
|
|
<*>
|
|
|
|
mapM (evalAlt c) alts
|
2016-02-24 07:47:08 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalCase
|
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalTuple :: Show l =>
|
|
|
|
EvalContext -> [Exp l] -> State IDState (SyntaxGraph, NameAndPort)
|
2017-01-01 09:32:57 +03:00
|
|
|
evalTuple c exps =
|
|
|
|
let
|
|
|
|
numExps = length exps
|
|
|
|
in
|
|
|
|
makeApplyGraph numExps ApplyNodeFlavor False
|
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
(grNamePortToGrRef <$> makeBox (nTupleString numExps))
|
|
|
|
<*>
|
|
|
|
mapM (evalExp c) exps
|
2016-02-24 10:14:00 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalTupleSection :: Show l =>
|
|
|
|
EvalContext -> [Maybe (Exp l)] -> State IDState (SyntaxGraph, NameAndPort)
|
2017-01-01 06:11:51 +03:00
|
|
|
evalTupleSection c mExps =
|
|
|
|
let
|
|
|
|
exps = catMaybes mExps
|
|
|
|
expIsJustList = fmap isJust mExps
|
|
|
|
in
|
2017-01-01 06:20:01 +03:00
|
|
|
makeApplyGraph (length exps) ApplyNodeFlavor False
|
2017-01-01 06:11:51 +03:00
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
(grNamePortToGrRef <$> makeBox (nTupleSectionString expIsJustList))
|
|
|
|
<*>
|
2017-01-01 06:20:01 +03:00
|
|
|
mapM (evalExp c) exps
|
2017-01-01 06:11:51 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalListExp :: Show l =>
|
|
|
|
l -> EvalContext -> [Exp l] -> State IDState (SyntaxGraph, NameAndPort)
|
2017-07-19 09:47:28 +03:00
|
|
|
evalListExp _ _ [] = makeBox "[]"
|
2018-11-12 10:13:19 +03:00
|
|
|
evalListExp l c exps = evalFunExpAndArgs
|
|
|
|
c
|
|
|
|
ApplyNodeFlavor
|
|
|
|
(makeVarExp l . nListString . length $ exps, exps)
|
2016-03-05 10:49:48 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalLeftSection :: Show l =>
|
|
|
|
l -> EvalContext -> Exp l -> QOp l -> State IDState GraphAndRef
|
2017-07-19 09:47:28 +03:00
|
|
|
evalLeftSection l c e op = evalExp c $ App l (qOpToExp op) e
|
2016-03-05 08:35:23 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalRightSection :: Show l =>
|
|
|
|
EvalContext -> QOp l -> Exp l -> State IDState (SyntaxGraph, NameAndPort)
|
2017-01-01 09:32:57 +03:00
|
|
|
evalRightSection c op e =
|
|
|
|
makeApplyGraph 2 ApplyNodeFlavor False
|
|
|
|
<$>
|
|
|
|
getUniqueName
|
|
|
|
<*>
|
|
|
|
evalExp c (qOpToExp op)
|
|
|
|
<*>
|
|
|
|
((\x y -> [x, y]) <$>
|
2018-11-12 10:13:19 +03:00
|
|
|
-- TODO: A better option would be for makeApplyGraph to take the list of
|
|
|
|
-- expressions as Maybes.
|
2017-01-01 09:32:57 +03:00
|
|
|
fmap (GraphAndRef mempty . Left) (getUniqueString "unusedArgument")
|
|
|
|
<*>
|
|
|
|
evalExp c e
|
|
|
|
)
|
2016-03-05 08:35:23 +03:00
|
|
|
|
2016-03-05 05:49:02 +03:00
|
|
|
-- evalEnums is only used by evalExp
|
2018-11-12 10:13:19 +03:00
|
|
|
evalEnums :: Show l =>
|
|
|
|
l -> EvalContext -> String -> [Exp l] -> State IDState GraphAndRef
|
|
|
|
evalEnums l c s exps
|
|
|
|
= grNamePortToGrRef
|
|
|
|
<$> evalFunExpAndArgs c ApplyNodeFlavor (makeVarExp l s, exps)
|
2016-03-06 05:01:35 +03:00
|
|
|
|
2018-11-05 09:54:17 +03:00
|
|
|
desugarDo :: Show l => [Stmt l] -> Exp l
|
2017-07-19 09:47:28 +03:00
|
|
|
desugarDo [Qualifier _ e] = e
|
|
|
|
desugarDo (Qualifier l e : stmts) = InfixApp l e thenOp (desugarDo stmts)
|
|
|
|
where thenOp = makeQVarOp l ">>"
|
|
|
|
desugarDo (Generator l pat e : stmts) =
|
|
|
|
InfixApp l e (makeQVarOp l ">>=") (Lambda l [pat] (desugarDo stmts))
|
|
|
|
desugarDo (LetStmt l binds : stmts) = Let l binds (desugarDo stmts)
|
2018-11-05 09:54:17 +03:00
|
|
|
desugarDo stmts = error $ "Unsupported syntax in degugarDo: " <> show stmts
|
2016-03-06 05:01:35 +03:00
|
|
|
|
2016-03-06 09:26:03 +03:00
|
|
|
-- TODO: Finish evalRecConstr
|
2018-11-12 10:13:19 +03:00
|
|
|
evalRecConstr :: Show l =>
|
|
|
|
EvalContext -> QName l -> [Exts.FieldUpdate l] -> State IDState GraphAndRef
|
2016-03-28 02:49:58 +03:00
|
|
|
evalRecConstr c qName _ = evalQName qName c
|
2016-03-06 09:26:03 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- BEGIN generalEvalLambda
|
2016-02-22 06:34:33 +03:00
|
|
|
|
2016-12-26 08:45:58 +03:00
|
|
|
-- TODO Returning a SyntaxGraph is probably not very efficient
|
|
|
|
asBindGraphZipper :: Maybe String -> NameAndPort -> SyntaxGraph
|
|
|
|
asBindGraphZipper asName nameNPort = makeAsBindGraph (Right nameNPort) [asName]
|
|
|
|
|
2018-11-05 09:54:17 +03:00
|
|
|
generalEvalLambda :: Show l
|
|
|
|
=> EvalContext
|
|
|
|
-> [Pat l]
|
|
|
|
-> (EvalContext -> State IDState GraphAndRef)
|
|
|
|
-> State IDState (SyntaxGraph, NameAndPort)
|
2016-02-23 09:01:03 +03:00
|
|
|
generalEvalLambda context patterns rhsEvalFun = do
|
2016-12-28 01:58:09 +03:00
|
|
|
lambdaName <- getUniqueName
|
2016-12-26 08:45:58 +03:00
|
|
|
patternValsWithAsNames <- mapM evalPattern patterns
|
2016-02-23 03:13:53 +03:00
|
|
|
let
|
2016-12-26 08:45:58 +03:00
|
|
|
patternVals = fmap fst patternValsWithAsNames
|
|
|
|
patternStrings = concatMap namesInPattern patternValsWithAsNames
|
2016-02-23 09:01:03 +03:00
|
|
|
rhsContext = patternStrings <> context
|
2018-11-11 14:17:06 +03:00
|
|
|
GraphAndRef rhsRawGraph rhsRef <- rhsEvalFun rhsContext
|
|
|
|
let
|
2017-01-02 11:37:27 +03:00
|
|
|
paramNames = fmap patternName patternValsWithAsNames
|
2018-11-11 14:17:06 +03:00
|
|
|
enclosedNodeNames = snnName <$> sgNodes combinedGraph
|
|
|
|
lambdaNode = FunctionDefNode paramNames enclosedNodeNames
|
2016-12-29 11:15:17 +03:00
|
|
|
lambdaPorts = map (nameAndPort lambdaName) $ argumentPorts lambdaNode
|
2016-12-27 11:37:59 +03:00
|
|
|
patternGraph = mconcat $ fmap graphAndRefToGraph patternVals
|
2016-02-23 03:13:53 +03:00
|
|
|
|
2016-03-21 12:00:04 +03:00
|
|
|
(patternEdges, newBinds) =
|
2016-03-28 02:49:58 +03:00
|
|
|
partitionEithers $ zipWith makePatternEdges patternVals lambdaPorts
|
2016-12-18 04:13:36 +03:00
|
|
|
|
2016-12-28 08:02:11 +03:00
|
|
|
icons = [SgNamedNode lambdaName lambdaNode]
|
2016-12-29 11:15:17 +03:00
|
|
|
returnPort = nameAndPort lambdaName (inputPort lambdaNode)
|
2016-12-18 04:13:36 +03:00
|
|
|
(newEdges, newSinks) = case rhsRef of
|
2016-12-27 03:52:04 +03:00
|
|
|
Left s -> (patternEdges, [SgSink s returnPort])
|
2018-11-11 14:17:06 +03:00
|
|
|
Right rhsPort ->
|
|
|
|
(makeSimpleEdge (rhsPort, returnPort) : patternEdges, mempty)
|
2016-12-18 04:13:36 +03:00
|
|
|
finalGraph = SyntaxGraph icons newEdges newSinks newBinds mempty
|
2016-12-26 08:45:58 +03:00
|
|
|
|
2018-11-11 14:17:06 +03:00
|
|
|
asBindGraph = mconcat $ zipWith
|
|
|
|
asBindGraphZipper
|
|
|
|
(fmap snd patternValsWithAsNames)
|
|
|
|
lambdaPorts
|
|
|
|
combinedGraph = deleteBindings . makeEdges
|
|
|
|
$ (asBindGraph <> rhsRawGraph <> patternGraph <> finalGraph)
|
|
|
|
|
|
|
|
pure (combinedGraph, nameAndPort lambdaName (resultPort lambdaNode))
|
2016-02-27 09:58:49 +03:00
|
|
|
where
|
2018-11-12 10:13:19 +03:00
|
|
|
-- TODO Like evalPatBind, this edge should have an indicator that it is the
|
|
|
|
-- input to a pattern.
|
|
|
|
-- makePatternEdges creates the edges between the patterns and the parameter
|
|
|
|
-- ports.
|
2016-12-27 03:37:10 +03:00
|
|
|
makePatternEdges :: GraphAndRef -> NameAndPort -> Either Edge SgBind
|
2016-12-27 11:37:59 +03:00
|
|
|
makePatternEdges (GraphAndRef _ ref) lamPort = case ref of
|
|
|
|
Right patPort -> Left $ makeSimpleEdge (lamPort, patPort)
|
|
|
|
Left str -> Right $ SgBind str (Right lamPort)
|
2016-02-27 09:58:49 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END generalEvalLambda
|
2016-02-23 09:01:03 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
evalLambda :: Show l =>
|
|
|
|
EvalContext -> [Pat l] -> Exp l -> State IDState (SyntaxGraph, NameAndPort)
|
2016-02-23 09:01:03 +03:00
|
|
|
evalLambda c patterns e = generalEvalLambda c patterns (`evalExp` e)
|
2016-02-23 02:45:53 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalExp :: Show l => EvalContext -> Exp l -> State IDState GraphAndRef
|
2016-12-26 12:25:14 +03:00
|
|
|
evalExp c x = case x of
|
2017-07-19 09:47:28 +03:00
|
|
|
Var _ n -> evalQName n c
|
|
|
|
Con _ n -> evalQName n c
|
|
|
|
Lit _ l -> grNamePortToGrRef <$> evalLit l
|
|
|
|
InfixApp l e1 op e2 -> evalInfixApp l c e1 op e2
|
|
|
|
App l f arg -> grNamePortToGrRef <$> evalApp l c f arg
|
|
|
|
NegApp l e -> evalExp c (App l (makeVarExp l "negate") e)
|
2016-12-27 11:37:59 +03:00
|
|
|
Lambda _ patterns e -> grNamePortToGrRef <$> evalLambda c patterns e
|
2017-07-19 09:47:28 +03:00
|
|
|
Let _ bs e -> evalLet c bs e
|
|
|
|
If _ e1 e2 e3 -> grNamePortToGrRef <$> evalIf c e1 e2 e3
|
|
|
|
Case _ e alts -> grNamePortToGrRef <$> evalCase c e alts
|
|
|
|
Do _ stmts -> evalExp c (desugarDo stmts)
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO special tuple symbol
|
2017-07-19 09:47:28 +03:00
|
|
|
Tuple _ _ exps -> grNamePortToGrRef <$> evalTuple c exps
|
|
|
|
TupleSection _ _ mExps -> grNamePortToGrRef <$> evalTupleSection c mExps
|
|
|
|
List l exps -> grNamePortToGrRef <$> evalListExp l c exps
|
|
|
|
Paren _ e -> evalExp c e
|
|
|
|
LeftSection l e op -> evalLeftSection l c e op
|
|
|
|
RightSection _ op e -> grNamePortToGrRef <$> evalRightSection c op e
|
|
|
|
RecConstr _ n updates -> evalRecConstr c n updates
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Do RecUpdate correcly
|
2017-07-19 09:47:28 +03:00
|
|
|
RecUpdate _ e _ -> evalExp c e
|
|
|
|
EnumFrom l e -> evalEnums l c "enumFrom" [e]
|
|
|
|
EnumFromTo l e1 e2 -> evalEnums l c "enumFromTo" [e1, e2]
|
|
|
|
EnumFromThen l e1 e2 -> evalEnums l c "enumFromThen" [e1, e2]
|
|
|
|
EnumFromThenTo l e1 e2 e3 -> evalEnums l c "enumFromThenTo" [e1, e2, e3]
|
2016-12-26 12:25:14 +03:00
|
|
|
-- TODO: Add the type signiture to ExpTypeSig.
|
|
|
|
ExpTypeSig _ e _ -> evalExp c e
|
|
|
|
-- TODO: Add other cases
|
|
|
|
_ -> error $ "evalExp: No pattern in case for " ++ show x
|
|
|
|
|
|
|
|
-- BEGIN evalDecl
|
|
|
|
|
|
|
|
-- BEGIN evalMatches
|
2016-02-23 02:45:53 +03:00
|
|
|
|
2016-03-22 01:42:32 +03:00
|
|
|
-- Only used by matchesToCase
|
2018-11-05 09:54:17 +03:00
|
|
|
matchToAlt :: Show l => Match l -> Alt l
|
2017-07-19 09:47:28 +03:00
|
|
|
matchToAlt (Match l _ mtaPats rhs binds) = Alt l altPattern rhs binds where
|
2016-03-22 01:42:32 +03:00
|
|
|
altPattern = case mtaPats of
|
|
|
|
[onePat] -> onePat
|
2017-07-19 09:47:28 +03:00
|
|
|
_ -> PTuple l Exts.Boxed mtaPats
|
2018-11-05 09:54:17 +03:00
|
|
|
matchToAlt match = error $ "Unsupported syntax in matchToAlt: " <> show match
|
2016-02-27 09:58:49 +03:00
|
|
|
|
2018-11-05 09:54:17 +03:00
|
|
|
matchesToCase :: Show l => Match l -> [Match l] -> State IDState (Match l)
|
2016-02-27 02:58:50 +03:00
|
|
|
matchesToCase match [] = pure match
|
2017-07-19 09:47:28 +03:00
|
|
|
matchesToCase firstMatch@(Match srcLoc funName pats _ _) restOfMatches = do
|
2017-01-02 04:43:00 +03:00
|
|
|
-- There is a special case in Icons.hs/makeLabelledPort to exclude " tempvar"
|
|
|
|
tempStrings <- replicateM (length pats) (getUniqueString " tempvar")
|
2016-02-25 01:46:49 +03:00
|
|
|
let
|
2017-07-19 09:47:28 +03:00
|
|
|
tempPats = fmap (PVar srcLoc . Ident srcLoc) tempStrings
|
|
|
|
tempVars = fmap (makeVarExp srcLoc) tempStrings
|
|
|
|
tuple = Tuple srcLoc Exts.Boxed tempVars
|
2016-02-27 02:58:50 +03:00
|
|
|
caseExp = case tempVars of
|
2017-07-19 09:47:28 +03:00
|
|
|
[oneTempVar] -> Case srcLoc oneTempVar alts
|
|
|
|
_ -> Case srcLoc tuple alts
|
|
|
|
rhs = UnGuardedRhs srcLoc caseExp
|
|
|
|
match = Match srcLoc funName tempPats rhs Nothing
|
2016-02-25 01:46:49 +03:00
|
|
|
pure match
|
2016-02-27 09:58:49 +03:00
|
|
|
where
|
|
|
|
allMatches = firstMatch:restOfMatches
|
|
|
|
alts = fmap matchToAlt allMatches
|
2018-11-05 09:54:17 +03:00
|
|
|
matchesToCase firstMatch _
|
|
|
|
= error $ "Unsupported syntax in matchesToCase: " <> show firstMatch
|
2016-02-27 09:58:49 +03:00
|
|
|
|
2018-10-28 10:25:31 +03:00
|
|
|
evalMatch :: Show l => EvalContext -> Match l -> State IDState SyntaxGraph
|
2017-07-19 09:47:28 +03:00
|
|
|
evalMatch c (Match _ name patterns rhs maybeWhereBinds) = do
|
2016-12-26 12:25:14 +03:00
|
|
|
let
|
|
|
|
matchFunNameString = nameToString name
|
|
|
|
newContext = matchFunNameString : c
|
|
|
|
(lambdaGraph, lambdaPort) <-
|
|
|
|
generalEvalLambda newContext patterns (rhsWithBinds maybeWhereBinds rhs)
|
|
|
|
let
|
2018-11-12 10:13:19 +03:00
|
|
|
newBinding
|
|
|
|
= bindsToSyntaxGraph [SgBind matchFunNameString (Right lambdaPort)]
|
2016-12-26 12:25:14 +03:00
|
|
|
pure $ makeEdges (newBinding <> lambdaGraph)
|
2018-11-05 09:54:17 +03:00
|
|
|
evalMatch _ match = error $ "Unsupported syntax in evalMatch: " <> show match
|
2016-02-25 01:46:49 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalMatches :: Show l => EvalContext -> [Match l] -> State IDState SyntaxGraph
|
2016-02-22 02:15:16 +03:00
|
|
|
evalMatches _ [] = pure mempty
|
2018-11-12 10:13:19 +03:00
|
|
|
evalMatches c (firstMatch:restOfMatches)
|
|
|
|
= matchesToCase firstMatch restOfMatches >>= evalMatch c
|
2016-02-04 11:19:08 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalMatches
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalPatBind :: Show l => EvalContext -> Decl l -> State IDState SyntaxGraph
|
2016-12-26 12:25:14 +03:00
|
|
|
evalPatBind c (PatBind _ pat rhs maybeWhereBinds) = do
|
2016-12-30 13:15:43 +03:00
|
|
|
((GraphAndRef patGraph patRef, mPatAsName), GraphAndRef rhsGraph rhsRef) <-
|
|
|
|
bindOrAltHelper c pat rhs maybeWhereBinds
|
2016-12-26 12:25:14 +03:00
|
|
|
let
|
|
|
|
(newEdges, newSinks, bindings) = case patRef of
|
2016-12-27 03:37:10 +03:00
|
|
|
(Left s) -> (mempty, mempty, [SgBind s rhsRef])
|
2016-12-26 12:25:14 +03:00
|
|
|
(Right patPort) -> case rhsRef of
|
2016-12-27 03:52:04 +03:00
|
|
|
(Left rhsStr) -> (mempty, [SgSink rhsStr patPort], mempty)
|
2016-12-26 12:25:14 +03:00
|
|
|
(Right rhsPort) -> ([makeSimpleEdge (rhsPort, patPort)], mempty, mempty)
|
2016-12-30 13:15:43 +03:00
|
|
|
asBindGraph = makeAsBindGraph rhsRef [mPatAsName]
|
2016-12-26 12:25:14 +03:00
|
|
|
gr = asBindGraph <> SyntaxGraph mempty newEdges newSinks bindings mempty
|
|
|
|
pure . makeEdges $ (gr <> rhsGraph <> patGraph)
|
2018-11-05 09:54:17 +03:00
|
|
|
evalPatBind _ decl = error $ "Unsupported syntax in evalPatBind: " <> show decl
|
2016-12-26 12:25:14 +03:00
|
|
|
|
2016-12-16 11:47:48 +03:00
|
|
|
-- Pretty printing the entire type sig results in extra whitespace in the middle
|
|
|
|
-- TODO May want to trim whitespace from (prettyPrint typeForNames)
|
2018-11-05 09:54:17 +03:00
|
|
|
evalTypeSig :: Show l => Decl l -> State IDState (SyntaxGraph, NameAndPort)
|
2016-12-16 11:47:48 +03:00
|
|
|
evalTypeSig (TypeSig _ names typeForNames) = makeBox
|
2017-01-04 12:22:08 +03:00
|
|
|
(intercalate "," (fmap prettyPrintWithoutNewlines names)
|
2016-12-16 11:47:48 +03:00
|
|
|
++ " :: "
|
2017-01-04 12:22:08 +03:00
|
|
|
++ prettyPrintWithoutNewlines typeForNames)
|
|
|
|
where
|
|
|
|
-- TODO Make custom version of prettyPrint for type signitures.
|
2018-11-12 10:13:19 +03:00
|
|
|
-- Use (unwords . words) to convert consecutive whitspace characters to one
|
|
|
|
-- space.
|
2017-01-04 12:22:08 +03:00
|
|
|
prettyPrintWithoutNewlines = unwords . words . prettyPrint
|
2018-11-05 09:54:17 +03:00
|
|
|
evalTypeSig decl
|
|
|
|
= error $ "Unsupported syntax in evalTypeSig: " <> show decl
|
2016-12-16 11:47:48 +03:00
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
evalDecl :: Show l => EvalContext -> Decl l -> State IDState SyntaxGraph
|
2016-12-14 00:40:23 +03:00
|
|
|
evalDecl c d = case d of
|
|
|
|
PatBind _ _ _ _ -> evalPatBind c d
|
2017-07-19 09:47:28 +03:00
|
|
|
FunBind _ matches -> evalMatches c matches
|
2016-12-16 11:47:48 +03:00
|
|
|
TypeSig _ _ _ -> fst <$> evalTypeSig d
|
2016-02-24 10:14:00 +03:00
|
|
|
--TODO: Add other cases here
|
|
|
|
_ -> pure mempty
|
2016-02-21 08:26:25 +03:00
|
|
|
|
2016-12-26 12:25:14 +03:00
|
|
|
-- END evalDecl
|
|
|
|
|
|
|
|
-- BEGIN Exported functions
|
|
|
|
|
2016-07-03 00:43:18 +03:00
|
|
|
showTopLevelBinds :: SyntaxGraph -> State IDState SyntaxGraph
|
2016-12-07 05:39:38 +03:00
|
|
|
showTopLevelBinds gr = do
|
2016-07-03 00:43:18 +03:00
|
|
|
let
|
2016-12-27 03:37:10 +03:00
|
|
|
binds = sgBinds gr
|
|
|
|
addBind (SgBind _ (Left _)) = pure mempty
|
|
|
|
addBind (SgBind patName (Right port)) = do
|
2016-12-28 01:58:09 +03:00
|
|
|
uniquePatName <- getUniqueName
|
2016-07-03 00:43:18 +03:00
|
|
|
let
|
2016-12-27 12:32:51 +03:00
|
|
|
icons = [SgNamedNode uniquePatName (BindNameNode patName)]
|
2016-12-08 13:41:47 +03:00
|
|
|
edges = [makeSimpleEdge (port, justName uniquePatName)]
|
2016-07-03 00:43:18 +03:00
|
|
|
edgeGraph = syntaxGraphFromNodesEdges icons edges
|
|
|
|
pure edgeGraph
|
|
|
|
newGraph <- mconcat <$> mapM addBind binds
|
|
|
|
pure $ newGraph <> gr
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
translateDeclToSyntaxGraph :: Show l => Decl l -> SyntaxGraph
|
2016-12-16 09:58:19 +03:00
|
|
|
translateDeclToSyntaxGraph d = graph where
|
|
|
|
evaluatedDecl = evalDecl mempty d >>= showTopLevelBinds
|
|
|
|
graph = evalState evaluatedDecl initialIdState
|
|
|
|
|
2017-01-01 06:11:51 +03:00
|
|
|
customParseMode :: Exts.ParseMode
|
|
|
|
customParseMode = Exts.defaultParseMode
|
|
|
|
{Exts.extensions =
|
|
|
|
[Exts.EnableExtension Exts.MultiParamTypeClasses,
|
|
|
|
Exts.EnableExtension Exts.FlexibleContexts,
|
|
|
|
Exts.EnableExtension Exts.TupleSections
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
customParseDecl :: String -> Decl Exts.SrcSpanInfo
|
2017-01-01 06:11:51 +03:00
|
|
|
customParseDecl = fromParseResult . parseDeclWithMode customParseMode
|
|
|
|
|
2016-12-16 09:58:19 +03:00
|
|
|
-- | Convert a single function declaration into a SyntaxGraph
|
|
|
|
translateStringToSyntaxGraph :: String -> SyntaxGraph
|
2017-01-01 06:11:51 +03:00
|
|
|
translateStringToSyntaxGraph = translateDeclToSyntaxGraph . customParseDecl
|
2016-12-16 09:58:19 +03:00
|
|
|
|
2016-12-16 11:47:48 +03:00
|
|
|
syntaxGraphToCollapsedGraph :: SyntaxGraph -> IngSyntaxGraph FGR.Gr
|
|
|
|
syntaxGraphToCollapsedGraph = collapseNodes . syntaxGraphToFglGraph
|
|
|
|
|
2017-07-19 09:47:28 +03:00
|
|
|
translateDeclToCollapsedGraph :: Show l => Decl l -> IngSyntaxGraph FGR.Gr
|
2018-11-12 10:13:19 +03:00
|
|
|
translateDeclToCollapsedGraph
|
|
|
|
= syntaxGraphToCollapsedGraph . translateDeclToSyntaxGraph
|
2016-02-27 09:58:49 +03:00
|
|
|
|
2016-12-29 11:15:17 +03:00
|
|
|
-- Profiling: At one point, this was about 1.5% of total time.
|
2018-11-12 10:13:19 +03:00
|
|
|
translateStringToCollapsedGraphAndDecl ::
|
|
|
|
String -> (IngSyntaxGraph FGR.Gr, Decl Exts.SrcSpanInfo)
|
2016-12-16 09:58:19 +03:00
|
|
|
translateStringToCollapsedGraphAndDecl s = (drawing, decl) where
|
2017-01-01 06:11:51 +03:00
|
|
|
decl = customParseDecl s -- :: ParseResult Module
|
2016-12-16 09:58:19 +03:00
|
|
|
drawing = translateDeclToCollapsedGraph decl
|
2016-07-03 00:43:18 +03:00
|
|
|
|
2018-11-12 10:13:19 +03:00
|
|
|
translateModuleToCollapsedGraphs :: Show l =>
|
|
|
|
Module l -> [IngSyntaxGraph FGR.Gr]
|
|
|
|
translateModuleToCollapsedGraphs (Module _ _ _ _ decls)
|
|
|
|
= fmap translateDeclToCollapsedGraph decls
|
2018-11-05 09:54:17 +03:00
|
|
|
translateModuleToCollapsedGraphs moduleSyntax
|
|
|
|
= error $ "Unsupported syntax in translateModuleToCollapsedGraphs: "
|
|
|
|
<> show moduleSyntax
|
2016-12-26 12:25:14 +03:00
|
|
|
|
|
|
|
-- END Exported functions
|