Skip to content

Commit 5dc6980

Browse files
authored
Merge pull request #70 from grin-compiler/32-tests-ctx-based
Extended syntax: added context-based testing
2 parents a3b6d19 + acd2387 commit 5dc6980

File tree

6 files changed

+168
-10
lines changed

6 files changed

+168
-10
lines changed

grin/grin.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ library
137137
Test.ExtendedSyntax.Assertions
138138
Test.ExtendedSyntax.Old.Grammar
139139
Test.ExtendedSyntax.Old.Test
140+
Test.ExtendedSyntax.New.Test
140141
Test.ExtendedSyntax.Util
141142

142143
Transformations.ExtendedSyntax.BindNormalisation

grin/src/Grin/ExtendedSyntax/Grin.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,6 @@ concatPrograms prgs = Program (nub $ concat exts) (concat defs) where
105105
allowedSpecial :: String
106106
allowedSpecial = "._':!-"
107107

108+
-- QUESTION: Should upper-case letters be allowed?
108109
allowedInitial :: String
109110
allowedInitial = "._" ++ ['a'..'z'] ++ ['A'..'Z']

grin/src/Grin/ExtendedSyntax/Parse/AST.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,10 @@ parseProg :: Text -> Exp
128128
parseProg src = either (error . parseErrorPretty' src) id . parseGrin "" $ withoutTypeAnnots src
129129

130130
parseDef :: Text -> Exp
131-
parseDef src = either (error . parseErrorPretty' src) id . runParser def "" $ withoutTypeAnnots src
131+
parseDef src = either (error . parseErrorPretty' src) id . runParser (def <* sc <* eof) "" $ withoutTypeAnnots src
132132

133133
parseExpr :: Text -> Exp
134-
parseExpr src = either (error . parseErrorPretty' src) id . runParser (expr pos1) "" $ withoutTypeAnnots src
134+
parseExpr src = either (error . parseErrorPretty' src) id . runParser (expr pos1 <* sc <* eof) "" $ withoutTypeAnnots src
135135

136136

137137
withoutTypeAnnots :: Text -> Text
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
{-# LANGUAGE QuasiQuotes, ViewPatterns #-}
2+
module Test.ExtendedSyntax.New.Test where
3+
4+
import Data.Text (Text, pack)
5+
import Data.Bifunctor (second)
6+
7+
import Control.Monad (forM_, forM)
8+
9+
import Test.Hspec (Spec, describe)
10+
11+
import Grin.ExtendedSyntax.TH (expr)
12+
import Grin.ExtendedSyntax.Grin (Exp, Name)
13+
import Grin.ExtendedSyntax.TypeEnv (TypeEnv, emptyTypeEnv)
14+
import Grin.ExtendedSyntax.Pretty (Pretty, PP(..))
15+
16+
import Transformations.ExtendedSyntax.Names (evalNameM, deriveNewName)
17+
18+
type SpecWithProg = Exp -> Spec
19+
20+
type TestExpContext = (String, (TypeEnv, Exp) -> (TypeEnv, Exp))
21+
22+
testExprContext :: (((TypeEnv, Exp) -> (TypeEnv, Exp)) -> Spec) -> Spec
23+
testExprContext mkSpec = forM_ contexts $ \(label, ctx) -> describe (concat ["(", label, ")"]) $ mkSpec ctx
24+
25+
testExprContextE :: ((Exp -> Exp) -> Spec) -> Spec
26+
testExprContextE mkSpec =
27+
forM_ contexts $ \(label, ctx) ->
28+
describe (concat ["(", label, ")"]) $ mkSpec (\e -> snd $ ctx (emptyTypeEnv, e))
29+
30+
contexts :: [TestExpContext]
31+
contexts =
32+
[ emptyCtx
33+
, lastBindR
34+
, bindL
35+
, lastBindL
36+
, firstAlt
37+
, middleAlt
38+
, lastAlt
39+
]
40+
41+
emptyCtx :: TestExpContext
42+
emptyCtx = ("empty", id)
43+
44+
-- NOTE: These contexts contain some names. Make sure not to use these in your test code!
45+
46+
deriveNames :: Exp -> [Name]
47+
deriveNames e = fst <$> evalNameM e $ do
48+
forM [1..] $ \_ -> deriveNewName "ctxVar"
49+
50+
deriveNamesAsText :: Exp -> [Text]
51+
deriveNamesAsText = map toText . deriveNames
52+
53+
toText :: Pretty a => a -> Text
54+
toText = pack . show . PP
55+
56+
bindL :: TestExpContext
57+
bindL = ("bind left", second tr) where
58+
tr e
59+
| (v:_) <- deriveNamesAsText e
60+
, eText <- toText e = [expr|
61+
$v <- do
62+
$eText
63+
pure ()
64+
|]
65+
66+
lastBindL :: TestExpContext
67+
lastBindL = ("last bind left", second tr) where
68+
tr e
69+
| (v1:v2:_) <- deriveNamesAsText e
70+
, eText <- toText e = [expr|
71+
$v1 <- do
72+
$v2 <- pure ()
73+
$eText
74+
pure ()
75+
|]
76+
77+
firstAlt :: TestExpContext
78+
firstAlt = ("first alt", second tr) where
79+
tr e
80+
| (scrut:v1:v2:v3:x:_) <- deriveNamesAsText e
81+
, eText <- toText e = [expr|
82+
$scrut <- pure 1
83+
case $scrut of
84+
1 @ $v1 ->
85+
$x <- pure ()
86+
$eText
87+
2 @ $v2 ->
88+
pure ()
89+
3 @ $v3 ->
90+
pure ()
91+
|]
92+
93+
middleAlt :: TestExpContext
94+
middleAlt = ("middle alt", second tr) where
95+
tr e
96+
| (scrut:v1:v2:v3:x:_) <- deriveNamesAsText e
97+
, eText <- toText e = [expr|
98+
$scrut <- pure 1
99+
case $scrut of
100+
1 @ $v1 ->
101+
pure ()
102+
2 @ $v2 ->
103+
$x <- pure ()
104+
$eText
105+
3 @ $v3 ->
106+
pure ()
107+
|]
108+
109+
lastAlt :: TestExpContext
110+
lastAlt = ("last alt", second tr) where
111+
tr e
112+
| (scrut:v1:v2:v3:x:_) <- deriveNamesAsText e
113+
, eText <- toText e = [expr|
114+
$scrut <- pure 1
115+
case $scrut of
116+
1 @ $v1 ->
117+
pure ()
118+
2 @ $v2 ->
119+
pure ()
120+
3 @ $v3 ->
121+
$x <- pure ()
122+
$eText
123+
|]
124+
125+
lastBindR :: TestExpContext
126+
lastBindR = ("last bind right", second tr) where
127+
tr e
128+
| (v:_) <- deriveNamesAsText e
129+
, eText <- toText e = [expr|
130+
$v <- pure ()
131+
$eText
132+
|]

grin/src/Test/ExtendedSyntax/Util.hs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ module Test.ExtendedSyntax.Util where
55

66
import System.FilePath
77

8+
import Data.Set (Set)
9+
import Data.Map (Map)
10+
import Data.Vector (Vector)
811
import Data.Text (Text)
12+
13+
import qualified Data.Set as Set
14+
import qualified Data.Map as Map
15+
import qualified Data.Vector as V
916
import qualified Data.Text.IO as T (readFile)
1017

1118
import Grin.ExtendedSyntax.Grin
1219
import Grin.ExtendedSyntax.Parse
20+
import AbstractInterpretation.ExtendedSyntax.HeapPointsTo.Result as HPT
1321

1422
import Test.Hspec
1523
import Test.ExtendedSyntax.Assertions
@@ -56,6 +64,30 @@ cNope = Tag C "Nope"
5664
cNopeH :: Tag
5765
cNopeH = Tag C "NopeH"
5866

67+
loc :: HPT.Loc -> TypeSet
68+
loc = tySetFromTypes . pure . HPT.T_Location
69+
70+
unspecLoc :: TypeSet
71+
unspecLoc = tySetFromTypes [HPT.T_UnspecifiedLocation]
72+
73+
mkNode :: [[HPT.SimpleType]] -> Vector (Set HPT.SimpleType)
74+
mkNode = V.fromList . map Set.fromList
75+
76+
mkNodeSet :: [(Tag, [[HPT.SimpleType]])] -> NodeSet
77+
mkNodeSet = HPT.NodeSet . Map.fromList . map (\(t,v) -> (t,mkNode v))
78+
79+
mkTySet :: [(Tag, [[HPT.SimpleType]])] -> TypeSet
80+
mkTySet = tySetFromNodeSet . mkNodeSet
81+
82+
tySetFromNodeSet :: NodeSet -> TypeSet
83+
tySetFromNodeSet = TypeSet mempty
84+
85+
tySetFromTypes :: [HPT.SimpleType] -> TypeSet
86+
tySetFromTypes = flip TypeSet mempty . Set.fromList
87+
88+
mkSimpleMain :: HPT.SimpleType -> (TypeSet, Vector TypeSet)
89+
mkSimpleMain t = (tySetFromTypes [t], mempty)
90+
5991
-- name ~ name of the test case, and also the grin source file
6092
mkBeforeAfterTestCase :: String ->
6193
FilePath ->

grin/test/AbstractInterpretation/ExtendedSyntax/CreatedBySpec.hs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,6 @@ spec = do
3636
calcHPTResultWithCBy = _hptResult . calcCByResult
3737
mkProducerSet = ProducerSet . M.fromList . map (\(t,xs) -> (t,S.fromList xs))
3838
emptyProducerSet = mkProducerSet []
39-
unspecLoc = tySetFromTypes [T_UnspecifiedLocation]
40-
loc = tySetFromTypes . pure . T_Location
41-
mkNode = V.fromList . map S.fromList
42-
mkNodeSet = HPT.NodeSet . M.fromList . map (\(t,v) -> (t,mkNode v))
43-
mkTySet = tySetFromNodeSet . mkNodeSet
44-
tySetFromNodeSet = TypeSet mempty
45-
tySetFromTypes = flip TypeSet mempty . S.fromList
46-
mkSimpleMain t = (tySetFromTypes [t], mempty)
4739

4840
describe "Created-By producers are calculated correctly for" $ do
4941
it "pures" $ do

0 commit comments

Comments
 (0)