Initial work on interval trees · purescript/purescript@b252926 · GitHub
Skip to content

Commit b252926

Browse files
committed
Initial work on interval trees
1 parent b1825f9 commit b252926

5 files changed

Lines changed: 144 additions & 8 deletions

File tree

‎play/Main.hs‎

Lines changed: 8 additions & 0 deletions

‎purescript.cabal‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ common defaults
190190
parallel >=3.2.2.0 && <3.3,
191191
parsec >=3.1.15.0 && <3.2,
192192
pattern-arrows >=0.0.2 && <0.1,
193+
pretty-simple >=4.1.2.0 && <5,
193194
process ==1.6.13.1,
194195
protolude >=0.3.1 && <0.4,
195196
regex-tdfa >=1.3.1.2 && <1.4,
@@ -326,6 +327,7 @@ library
326327
Language.PureScript.Interactive.Parser
327328
Language.PureScript.Interactive.Printer
328329
Language.PureScript.Interactive.Types
330+
Language.PureScript.Interface.Types
329331
Language.PureScript.Label
330332
Language.PureScript.Linter
331333
Language.PureScript.Linter.Exhaustive
@@ -396,6 +398,13 @@ library
396398
autogen-modules:
397399
Paths_purescript
398400

401+
executable play
402+
import: defaults
403+
hs-source-dirs: play
404+
main-is: Main.hs
405+
build-depends:
406+
purescript
407+
399408
executable purs
400409
import: defaults
401410
hs-source-dirs: app

‎src/Language/PureScript/AST/SourcePos.hs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,14 @@ widenSourceSpan (SourceSpan n1 s1 e1) (SourceSpan n2 s2 e2) =
114114
n | n1 == "" = n2
115115
| otherwise = n1
116116

117+
containsSpan :: SourceSpan -> SourceSpan -> Bool
118+
containsSpan i o = (spanStart i <= spanStart o) && (spanEnd i >= spanEnd o)
119+
120+
rightOf :: SourceSpan -> SourceSpan -> Bool
121+
rightOf i o = spanStart i >= spanEnd o
122+
123+
leftOf :: SourceSpan -> SourceSpan -> Bool
124+
leftOf i o = spanEnd i <= spanStart o
125+
117126
widenSourceAnn :: SourceAnn -> SourceAnn -> SourceAnn
118127
widenSourceAnn (s1, _) (s2, _) = (widenSourceSpan s1 s2, [])
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
module Language.PureScript.Interface.Types where
2+
3+
import Protolude
4+
5+
import Control.Monad.Supply (evalSupplyT)
6+
import Control.Monad.Trans.Writer (WriterT(..))
7+
import Language.PureScript.AST.Declarations (importPrim, getModuleDeclarations, Expr (..), Declaration, pattern ValueDecl, pattern MkUnguarded)
8+
import Language.PureScript.AST.SourcePos (SourceSpan (..), containsSpan, leftOf, rightOf)
9+
import Language.PureScript.AST.Traversals (everythingOnValues)
10+
import Language.PureScript.Crash (internalError)
11+
import Language.PureScript.CST (parseFromFile)
12+
import Language.PureScript.Environment (initEnvironment)
13+
import Language.PureScript.Sugar (desugar)
14+
import Language.PureScript.Sugar.Names.Env (primEnv)
15+
import Language.PureScript.TypeChecker (typeCheckModule, emptyCheckState, debugType)
16+
import Text.Pretty.Simple (pPrint)
17+
import Data.String (String)
18+
19+
data NodeContext = DeclarationNode | ExpressionNode
20+
deriving (Show)
21+
22+
data NodeInfo a = NodeInfo
23+
{ nodeType :: a
24+
, nodeContext :: NodeContext
25+
} deriving (Show)
26+
27+
data InterfaceAST a = InterfaceNode
28+
{ nodeInfo :: NodeInfo a
29+
, nodeSpan :: SourceSpan,
30+
nodeLeaves :: [InterfaceAST a]
31+
} deriving (Show)
32+
33+
makeNode :: NodeInfo a -> SourceSpan -> InterfaceAST a
34+
makeNode i s = InterfaceNode i s []
35+
36+
combineAST :: forall a. InterfaceAST a -> InterfaceAST a -> InterfaceAST a
37+
combineAST x@(InterfaceNode xInfo xSpan xLeaves) y@(InterfaceNode _ ySpan yLeaves)
38+
-- for same spans, just merge the leaves
39+
| xSpan == ySpan = InterfaceNode xInfo xSpan (mergeASTs xLeaves yLeaves)
40+
-- if x contains y, then flip the arguments
41+
| xSpan `containsSpan` ySpan = combineAST y x
42+
-- at this point, we can just insert y into x
43+
combineAST y (InterfaceNode xInfo xSpan xLeaves) = InterfaceNode xInfo xSpan (insertAST y xLeaves)
44+
45+
insertAST :: forall a. InterfaceAST a -> [InterfaceAST a] -> [InterfaceAST a]
46+
insertAST x = mergeASTs [x]
47+
48+
mergeASTs :: forall a. [InterfaceAST a] -> [InterfaceAST a] -> [InterfaceAST a]
49+
mergeASTs xs [] = xs
50+
mergeASTs [] ys = ys
51+
mergeASTs xs@(x : xr) ys@(y : yr)
52+
-- x contains y, insert y to x
53+
| xSpan `containsSpan` ySpan = mergeASTs (combineAST x y : xr) yr
54+
-- y contains x, insert x to y
55+
| ySpan `containsSpan` xSpan = mergeASTs xr (combineAST x y : yr)
56+
-- x comes after y
57+
| xSpan `rightOf` ySpan = y : mergeASTs xs yr
58+
-- y comes after x
59+
| xSpan `leftOf` ySpan = x : mergeASTs xr ys
60+
-- fully disjoint, just recurse
61+
| otherwise = x : mergeASTs xr ys
62+
where
63+
xSpan :: SourceSpan
64+
xSpan = nodeSpan x
65+
66+
ySpan :: SourceSpan
67+
ySpan = nodeSpan y
68+
69+
source :: Text
70+
source = unlines
71+
[ "module Main where"
72+
, "values :: Array Int"
73+
, "values = [0, 1]"
74+
]
75+
76+
main :: IO ()
77+
main = do
78+
case snd $ parseFromFile "<stdin>" source of
79+
Left _ -> internalError "Could not parse file."
80+
Right parsedModule -> do
81+
checkResult <- runExceptT $ fmap fst $ runWriterT $ evalSupplyT 0 $ do
82+
(desugardModule, (externsEnv, _)) <- runStateT (desugar [] (importPrim parsedModule)) (primEnv, mempty)
83+
let moduleExports = (\(_, _, exports) -> exports) <$> externsEnv
84+
evalStateT (typeCheckModule moduleExports desugardModule) (emptyCheckState initEnvironment)
85+
case checkResult of
86+
Left _ -> internalError "Could not check file."
87+
Right checkedModule' ->
88+
forM_ (concatMap declarationToAST $ getModuleDeclarations checkedModule') $ \i ->
89+
pPrint i
90+
91+
where
92+
declarationToAST :: Declaration -> [InterfaceAST String]
93+
(declarationToAST, _, _, _, _) = everythingOnValues mergeASTs onDecl onExpr noAST noAST noAST
94+
where
95+
noAST :: forall a. a -> [InterfaceAST String]
96+
noAST = const []
97+
98+
onDecl :: Declaration -> [InterfaceAST String]
99+
onDecl = \case
100+
ValueDecl (s, _) _ _ _ [MkUnguarded (TypedValue _ (PositionedValue _ _ _) t)] ->
101+
[ makeNode (NodeInfo (debugType t) DeclarationNode) s ]
102+
_ ->
103+
[]
104+
105+
onExpr :: Expr -> [InterfaceAST String]
106+
onExpr = \case
107+
TypedValue _ (PositionedValue s _ _) t ->
108+
[ makeNode (NodeInfo (debugType t) ExpressionNode) s ]
109+
_ ->
110+
[]

‎src/Language/PureScript/Sugar/TypeDeclarations.hs‎

Lines changed: 8 additions & 8 deletions

0 commit comments

Comments
 (0)