Commit beaf81d2 authored by Tadej Borovšak's avatar Tadej Borovšak
Browse files

Add unit tests for parser

parent 3638e0ef
import Test.Hspec
import Imp_AbsSyntax
import Imp_Lex
import Imp_Parse
gen_ast = imp_parse . imp_lex
main :: IO ()
main = hspec $ do
describe "imp_parse" $ do
it "parses empty program as nop" $ do
gen_ast "" `shouldBe`
Skip
it "parses skip" $ do
gen_ast "skip" `shouldBe`
Skip
it "parses assignment and location" $ do
gen_ast "x := x" `shouldBe`
(Assign ("x", Loc "x"))
it "parses numeric literal" $ do
gen_ast "y := 4" `shouldBe`
(Assign ("y", Num 4))
it "parses addition" $ do
gen_ast "y := 3 + 2" `shouldBe`
(Assign ("y", AOp ("+", Num 3, Num 2)))
it "parses sub" $ do
gen_ast "y := 3 - 2" `shouldBe`
(Assign ("y", AOp ("-", Num 3, Num 2)))
it "parses addition" $ do
gen_ast "y := 3 * 2" `shouldBe`
(Assign ("y", AOp ("*", Num 3, Num 2)))
it "parses while statement" $ do
gen_ast "while True do skip" `shouldBe`
(While (Boolean True, Skip))
it "parses boolean literals" $ do
gen_ast "while True do while False do skip" `shouldBe`
(While (Boolean True, While (Boolean False, Skip)))
it "parses boolean expressions" $ do
gen_ast "while 3 < x do skip" `shouldBe`
(While (BOp ("<", Num 3, Loc "x"), Skip))
it "parses nested expressions" $ do
gen_ast "while 2 + x * 4 == 5 do skip" `shouldBe`
(While (BOp ("==",
AOp ("+", Num 2, AOp ("*", Loc "x", Num 4)),
Num 5),
Skip))
it "makes multiplication left associative" $ do
gen_ast "x := 3 * 4 * 5" `shouldBe`
(Assign ("x", AOp ("*", AOp ("*", Num 3, Num 4), Num 5)))
it "makes addition and subtraction left associative" $ do
gen_ast "x := 3 - 4 + 5" `shouldBe`
(Assign ("x", AOp ("+", AOp ("-", Num 3, Num 4), Num 5)))
it "parses if statement" $ do
gen_ast "if False then skip else skip" `shouldBe`
(Cond (Boolean False, Skip, Skip))
it "parses sequences" $ do
gen_ast "skip ; skip" `shouldBe`
(Seq (Skip, Skip))
it "makes while eat as much as possible" $ do
gen_ast "skip ; while True do skip ; skip" `shouldBe`
(Seq (Skip, While (Boolean True, Seq (Skip, Skip))))
it "makes if eat as much commands as possible" $ do
gen_ast "if False then skip ; skip else skip ; skip" `shouldBe`
(Cond (Boolean False,
Seq (Skip, Skip),
Seq (Skip, Skip)))
it "makes inner while take over" $ do
gen_ast "skip ; while True do skip ; while False do skip ; skip"
`shouldBe` (Seq (Skip,
While (Boolean True,
Seq (Skip,
While (Boolean False,
Seq (Skip, Skip))))))
it "properly handles nesting with parentheses" $ do
gen_ast "skip; (while True do skip) ; skip" `shouldBe`
(Seq (Skip,
Seq (While (Boolean True, Skip),
Skip)))
it "properly handles nesting" $ do
gen_ast (
unlines [ "(if False "
, "then while False do skip ; skip "
, "else (while True do skip) ; skip);"
, "skip"
]
) `shouldBe` (Seq (Cond (Boolean False,
While (Boolean False,
Seq (Skip, Skip)),
Seq (While (Boolean True,
Skip),
Skip)),
Skip))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment