Skip to content

Commit c117f4f

Browse files
committed
refactor: Simplify primitives tests
Now that primitives don't contain metadata, we don't need to juggle state and DSL functions. We also remove `allPrimDefs`, whise functionality has been subsumed by `primitiveModule`.
1 parent 5aebcd2 commit c117f4f

File tree

6 files changed

+98
-121
lines changed

6 files changed

+98
-121
lines changed

primer/src/Primer/Core.hs

+1-3
Original file line numberDiff line numberDiff line change
@@ -486,9 +486,7 @@ data Def
486486
type DefMap = Map GVarName Def
487487

488488
-- | A primitive, built-in definition.
489-
-- Names and definitions of primitives are hard-coded in Primer.Primitives.
490-
-- A @PrimDef@ simply exposes one of those, and thus the type must match
491-
-- the one stored in the corresponding 'PrimFun'.
489+
-- For each of these, we should have a test that the evaluator produces expected results.
492490
data PrimDef
493491
= ToUpper
494492
| IsSpace

primer/src/Primer/Primitives.hs

+24-31
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ module Primer.Primitives (
1111
primDefName,
1212
primDefType,
1313
defType,
14-
allPrimDefs,
1514
primFunDef,
1615
) where
1716

@@ -75,7 +74,7 @@ primitiveModule =
7574
Module
7675
{ moduleName = primitiveModuleName
7776
, moduleTypes = TypeDefPrim <$> M.mapKeys baseName allPrimTypeDefs
78-
, moduleDefs = M.fromList $ [(baseName $ primDefName def, DefPrim def) | def <- enumerate]
77+
, moduleDefs = M.fromList $ [(primDefName def, DefPrim def) | def <- enumerate]
7978
}
8079

8180
tChar :: TyConName
@@ -84,7 +83,7 @@ tChar = primitive "Char"
8483
tInt :: TyConName
8584
tInt = primitive "Int"
8685

87-
-- | Construct a reference to a primitive definition. For use in tests.
86+
-- | Construct a reference to a primitive definition.
8887
primitiveGVar :: Name -> GVarName
8988
primitiveGVar = primitive
9089

@@ -115,34 +114,28 @@ allPrimTypeDefs =
115114
PrimChar _ -> ()
116115
PrimInt _ -> ()
117116

118-
-- | Primitive term definitions.
119-
-- For each of these, we should have a test that the evaluator produces expected results.
120-
allPrimDefs :: Map GVarName PrimDef
121-
allPrimDefs = M.fromList [(primDefName def, def) | def <- enumerate]
122-
123-
primDefName :: PrimDef -> GVarName
124-
primDefName =
125-
primitiveGVar . \case
126-
ToUpper -> "toUpper"
127-
IsSpace -> "isSpace"
128-
HexToNat -> "hexToNat"
129-
NatToHex -> "natToHex"
130-
EqChar -> "eqChar"
131-
IntAdd -> "Int.+"
132-
IntMinus -> "Int.-"
133-
IntMul -> "Int.×"
134-
IntQuotient -> "Int.quotient"
135-
IntRemainder -> "Int.remainder"
136-
IntQuot -> "Int.quot"
137-
IntRem -> "Int.rem"
138-
IntLT -> "Int.<"
139-
IntLTE -> "Int.≤"
140-
IntGT -> "Int.>"
141-
IntGTE -> "Int.≥"
142-
IntEq -> "Int.="
143-
IntNeq -> "Int.≠"
144-
IntToNat -> "Int.toNat"
145-
IntFromNat -> "Int.fromNat"
117+
primDefName :: PrimDef -> Name
118+
primDefName = \case
119+
ToUpper -> "toUpper"
120+
IsSpace -> "isSpace"
121+
HexToNat -> "hexToNat"
122+
NatToHex -> "natToHex"
123+
EqChar -> "eqChar"
124+
IntAdd -> "Int.+"
125+
IntMinus -> "Int.-"
126+
IntMul -> "Int.×"
127+
IntQuotient -> "Int.quotient"
128+
IntRemainder -> "Int.remainder"
129+
IntQuot -> "Int.quot"
130+
IntRem -> "Int.rem"
131+
IntLT -> "Int.<"
132+
IntLTE -> "Int.≤"
133+
IntGT -> "Int.>"
134+
IntGTE -> "Int.≥"
135+
IntEq -> "Int.="
136+
IntNeq -> "Int.≠"
137+
IntToNat -> "Int.toNat"
138+
IntFromNat -> "Int.fromNat"
146139

147140
primDefType :: PrimDef -> Type' ()
148141
primDefType = uncurry (flip $ foldr $ TFun ()) . primFunTypes

primer/test/TestUtils.hs

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module TestUtils (
33
(@?=),
44
ExceptionPredicate,
55
assertException,
6-
withPrimDefs,
6+
primDefs,
77
constructTCon,
88
constructCon,
99
constructRefinedCon,
@@ -22,9 +22,8 @@ import Foreword
2222
import Control.Concurrent.STM (
2323
newTBQueueIO,
2424
)
25-
import Control.Monad.Fresh (MonadFresh)
26-
import Data.Coerce (coerce)
27-
import Data.String (String, fromString)
25+
import Data.Map qualified as Map
26+
import Data.String (String)
2827
import Data.Typeable (typeOf)
2928
import Optics (over, set, view)
3029
import Primer.API (
@@ -36,14 +35,14 @@ import Primer.Action (
3635
Action (ConstructCon, ConstructRefinedCon, ConstructTCon),
3736
)
3837
import Primer.Core (
38+
DefMap,
3939
Expr',
4040
ExprMeta,
4141
GVarName,
4242
GlobalName (baseName, qualifiedModule),
4343
HasID,
4444
HasMetadata (_metadata),
4545
ModuleName (ModuleName, unModuleName),
46-
PrimDef (..),
4746
TyConName,
4847
Type',
4948
TypeMeta,
@@ -61,17 +60,18 @@ import Primer.Database (
6160
runNullDb',
6261
serve,
6362
)
63+
import Primer.Module (Module (moduleDefs))
6464
import Primer.Name (Name (unName))
65-
import Primer.Primitives (allPrimDefs)
65+
import Primer.Primitives (primitiveGVar, primitiveModule)
6666
import StmContainers.Map qualified as StmMap
6767
import Test.Tasty.HUnit (
6868
assertBool,
6969
assertFailure,
7070
)
7171
import Test.Tasty.HUnit qualified as HUnit
7272

73-
withPrimDefs :: (Map GVarName PrimDef -> m a) -> m a
74-
withPrimDefs f = f allPrimDefs
73+
primDefs :: DefMap
74+
primDefs = Map.mapKeys primitiveGVar $ moduleDefs primitiveModule
7575

7676
-- impedence mismatch: ConstructTCon takes text, but tChar etc are TyConNames
7777
constructTCon :: TyConName -> Action

primer/test/Tests/Eval.hs

+15-19
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import Primer.Core (
3434
Kind (KType),
3535
Type,
3636
TypeDef (TypeDefAST),
37+
defPrim,
3738
getID,
3839
_id,
3940
)
@@ -65,7 +66,7 @@ import Primer.Primitives (primitiveGVar, primitiveModule, tChar)
6566
import Primer.Zipper (target)
6667
import Test.Tasty.HUnit (Assertion, assertBool, assertFailure, (@?=))
6768
import TestM (evalTestM)
68-
import TestUtils (gvn, vcn, withPrimDefs)
69+
import TestUtils (gvn, primDefs, vcn)
6970
import Tests.Action.Prog (runAppTestM)
7071

7172
-- * 'tryReduce' tests
@@ -625,15 +626,14 @@ unit_tryReduce_case_no_matching_branch = do
625626

626627
unit_tryReduce_prim :: Assertion
627628
unit_tryReduce_prim = do
628-
let ((expr, expectedResult, globals), i) =
629-
create . withPrimDefs $ \m ->
630-
(,,)
629+
let ((expr, expectedResult), i) =
630+
create $
631+
(,)
631632
<$> gvar (primitiveGVar "eqChar")
632633
`app` char 'a'
633634
`app` char 'a'
634635
<*> con cTrue
635-
<*> pure m
636-
result = runTryReduce (DefPrim <$> globals) mempty (expr, i)
636+
result = runTryReduce primDefs mempty (expr, i)
637637
case result of
638638
Right (expr', ApplyPrimFun detail) -> do
639639
expr' ~= expectedResult
@@ -646,25 +646,21 @@ unit_tryReduce_prim = do
646646

647647
unit_tryReduce_prim_fail_unsaturated :: Assertion
648648
unit_tryReduce_prim_fail_unsaturated = do
649-
let ((expr, globals), i) =
650-
create . withPrimDefs $ \m ->
651-
(,)
652-
<$> gvar (primitiveGVar "eqChar")
649+
let (expr, i) =
650+
create $
651+
gvar (primitiveGVar "eqChar")
653652
`app` char 'a'
654-
<*> pure m
655-
result = runTryReduce (DefPrim <$> globals) mempty (expr, i)
653+
result = runTryReduce primDefs mempty (expr, i)
656654
result @?= Left NotRedex
657655

658656
unit_tryReduce_prim_fail_unreduced_args :: Assertion
659657
unit_tryReduce_prim_fail_unreduced_args = do
660-
let ((expr, globals), i) =
661-
create . withPrimDefs $ \m ->
662-
(,)
663-
<$> gvar (primitiveGVar "eqChar")
658+
let (expr, i) =
659+
create $
660+
gvar (primitiveGVar "eqChar")
664661
`app` char 'a'
665662
`app` (gvar (primitiveGVar "toUpper") `app` char 'a')
666-
<*> pure m
667-
result = runTryReduce (DefPrim <$> globals) mempty (expr, i)
663+
result = runTryReduce primDefs mempty (expr, i)
668664
result @?= Left NotRedex
669665

670666
-- One can call the eval-step api endpoint with an expression and ID
@@ -859,7 +855,7 @@ redexesOf = redexes mempty . create'
859855

860856
-- | A variation of 'redexesOf' for when the expression tested requires primitives to be in scope.
861857
redexesOfWithPrims :: S Expr -> Set ID
862-
redexesOfWithPrims x = uncurry redexes $ create' $ withPrimDefs $ \globals -> (globals,) <$> x
858+
redexesOfWithPrims = redexes (Map.mapMaybe defPrim primDefs) . create'
863859

864860
unit_redexes_con :: Assertion
865861
unit_redexes_con = redexesOf (con' ["M"] "C") @?= mempty

0 commit comments

Comments
 (0)