2026-01-14 12:36:24 +00:00
|
|
|
{-# LANGUAGE DuplicateRecordFields #-}
|
|
|
|
|
{-# LANGUAGE OverloadedRecordDot #-}
|
|
|
|
|
{-# HLINT ignore "Use const" #-}
|
|
|
|
|
{-# HLINT ignore "Unused LANGUAGE pragma" #-}
|
|
|
|
|
{-# HLINT ignore "Avoid lambda" #-}
|
|
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
|
{-# LANGUAGE NoFieldSelectors #-}
|
|
|
|
|
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
|
|
|
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
|
|
|
|
|
|
module Test.SimpleParserSpec where
|
|
|
|
|
|
|
|
|
|
import Test.Hspec
|
2026-01-14 16:50:59 +00:00
|
|
|
import Text.Megaparsec
|
2026-01-14 12:36:24 +00:00
|
|
|
import SimpleParser
|
|
|
|
|
|
2026-01-15 10:15:07 +00:00
|
|
|
checkParse :: String -> Expr -> Expectation
|
|
|
|
|
checkParse text expectedExpr =
|
|
|
|
|
parse parseExpr "" text `shouldBe` Right expectedExpr
|
|
|
|
|
|
2026-01-15 16:01:15 +00:00
|
|
|
checkEval :: String -> Int -> Expectation
|
|
|
|
|
checkEval text expectedVal =
|
|
|
|
|
fmap eval (parse parseExpr "" text) `shouldBe` Right expectedVal
|
|
|
|
|
|
|
|
|
|
|
2026-01-14 12:36:24 +00:00
|
|
|
spec :: Spec
|
|
|
|
|
spec = do
|
|
|
|
|
describe "evaluate expressions" $ do
|
|
|
|
|
it "arithmetic on literals" $ do
|
2026-01-14 15:28:19 +00:00
|
|
|
eval (BinaryExpr Add (Literal 2) (Literal 3) ) `shouldBe` 5
|
|
|
|
|
eval (BinaryExpr Subtract (Literal 2) (Literal 3) ) `shouldBe` -1
|
|
|
|
|
eval (BinaryExpr Multiply (Literal 2) (Literal 3) ) `shouldBe` 6
|
|
|
|
|
eval (BinaryExpr Divide (Literal 7) (Literal 3) ) `shouldBe` 2
|
|
|
|
|
eval (UnaryExpr Negate (Literal 7) ) `shouldBe` -7
|
2026-01-14 12:39:15 +00:00
|
|
|
it "more complex arithmetic on literals" $ do
|
2026-01-14 15:28:19 +00:00
|
|
|
eval (BinaryExpr Add
|
|
|
|
|
(UnaryExpr Negate (Literal 1))
|
|
|
|
|
(BinaryExpr Divide (Literal 7) (Literal 3))
|
|
|
|
|
) `shouldBe` 1
|
2026-01-14 16:50:59 +00:00
|
|
|
it "can parse basic expressions" $ do
|
2026-01-15 10:15:07 +00:00
|
|
|
checkParse "2" (Literal 2)
|
|
|
|
|
checkParse "2+3" (BinaryExpr Add (Literal 2) (Literal 3))
|
|
|
|
|
checkParse "2+3+5" (BinaryExpr Add (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5))
|
2026-01-15 15:49:32 +00:00
|
|
|
checkParse "2+3*5" (BinaryExpr Add (Literal 2) (BinaryExpr Multiply (Literal 3) (Literal 5)))
|
|
|
|
|
checkParse "(2+3)*5" (BinaryExpr Multiply (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5) )
|
|
|
|
|
checkParse "((2+3))*5" (BinaryExpr Multiply (BinaryExpr Add (Literal 2) (Literal 3)) (Literal 5) )
|
2026-01-15 16:01:15 +00:00
|
|
|
it "can evaluate expressions correctly" $ do
|
|
|
|
|
checkEval "2" 2
|
|
|
|
|
checkEval "3*4/2" 6
|
|
|
|
|
checkEval "2+3*6" 20
|
|
|
|
|
checkEval "1-2+3" (-4)
|
|
|
|
|
|
2026-01-14 12:36:24 +00:00
|
|
|
|
|
|
|
|
|