aboutsummaryrefslogtreecommitdiff
path: root/test/TypecheckTest.hs
blob: 4e410edb8a5ff0c75ae8a2581d170681de42af7d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
module TypecheckTest
  where
import Typecheck
import Syntax
import Control.Monad.Except (runExcept)
import Test.Hspec


typecheckTest :: Spec
typecheckTest = describe "inferExpr" $ do
  it "can infer variables" $ do
    infer (Var "a") [("a", TInt)] `shouldBe`  Just TInt
    infer (Var "a") [("a", TRecord [("b",TInt)])] `shouldBe`  (Just $ TRecord [("b",TInt)])
    infer (Var "a") [("a", TVariant [("b",TInt)])] `shouldBe` (Just $ TVariant[("b",TInt)])
    infer (Var "a") [("a", TPtr TInt)] `shouldBe` ( Just $ TPtr TInt )
  it "shouldn't infer undefined variables" $ do
    infer (Var "a") [] `shouldBe` Nothing
  it "should be able to infer types of arithmetic expressions" $ do
    infer (IntLit 5) [] `shouldBe` (Just TInt)
    infer (Add (IntLit 1) (IntLit 3)) [] `shouldBe` (Just TInt)
    infer (Mult (IntLit 1) (IntLit 3)) [] `shouldBe` (Just TInt)
    infer (Neg (IntLit 3)) [] `shouldBe` (Just TInt)
  it "shouldn't be able to do arithmetic operations on pointer" $ do
    infer (Add (IntLit 1) (Var "a")) [("a",(TPtr TInt))] `shouldBe` Nothing
    infer (Add (Var "a") (IntLit 1)) [("a",(TPtr TInt))] `shouldBe` Nothing
    infer (Mult (IntLit 1) (Var "a")) [("a",(TPtr TInt))] `shouldBe` Nothing
    infer (Mult (Var "a") (IntLit 1)) [("a",(TPtr TInt))] `shouldBe` Nothing
    infer (Neg (Var "a")) [("a",(TPtr TInt))] `shouldBe` Nothing
  it "should infer compound types" $ do
    infer (Variant (TVariant [("Cons",TInt),("Cons2",TPtr TInt)]) "Cons" (IntLit 5)) [] `shouldBe` (Just $ TVariant [("Cons",TInt),("Cons2",TPtr TInt)])
    infer (Record [("aa",Var "a"),("bb",Var "b")]) [("a",TInt), ("b",TPtr TInt)] `shouldBe` (Just $ TRecord [("aa",TInt),("bb",TPtr TInt)])
  it "should unpack Ptr for every dereference" $ do
    infer (Deref (Var "a")) [("a",TPtr TInt)] `shouldBe` (Just TInt)
    infer (Deref (Var "a")) [("a",TPtr $ TPtr TInt)] `shouldBe` (Just $ TPtr TInt)
  where
    infer :: Expr -> Environment -> Maybe Typ
    infer e env=  eitherToMaybe $ runExcept $ inferExpr e env
    eitherToMaybe (Right a) = Just a
    eitherToMaybe (Left _) = Nothing