From e353caca8d4c5e3c3445497adb0950810e4b035c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Przemys=C5=82aw=20Pluta?= Date: Mon, 8 Nov 2021 16:39:17 +0100 Subject: [PATCH] Add some tests for emitters --- test/Assembler/EmitterSpec.hs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/test/Assembler/EmitterSpec.hs b/test/Assembler/EmitterSpec.hs index 6f87339..fbd9f98 100644 --- a/test/Assembler/EmitterSpec.hs +++ b/test/Assembler/EmitterSpec.hs @@ -3,14 +3,21 @@ module Assembler.EmitterSpec where import Test.Hspec import qualified Data.Map as M - +import Control.Monad.State (execState) import Assembler.Tokenizer (tokenize) -import Assembler.Parser (parse) -import Assembler.Emitter +import Assembler.Parser (AST(..), parse) +import Assembler.Emitter as E +import VirtualMachine (Op(..)) spec :: Spec spec = do + describe "emitLabelDef" $ do + it "inserts label definition to the context" $ do + let ctx = E.empty + let input = LabelDef "main" + execState (emitLabelDef input) ctx `shouldBe` ctx { _labels = M.fromList[("main", 0)] } + describe "resolveLabels" $ do it "replaces reference with actual byte number" $ do let beans = [ Byte 1, Byte 2, Reference "main", Byte 4 ] @@ -21,6 +28,26 @@ spec = do let labels = M.fromList [("main", 3)] resolveLabels labels beans `shouldBe` Left "Label 'not_existing_label' is not defined" + describe "emitParam" $ do + it "emits byte for integer literal" $ do + let ctx = E.empty + let input = Param (Integer 4) + execState (emitParam input) ctx `shouldBe` ctx { _beans = [Byte 0x04] } + it "emits reference mark for label reference" $ do + let ctx = E.empty + let input = Param (LabelRef "main") + execState (emitParam input) ctx `shouldBe` ctx { _beans = [Reference "main"] } + + describe "emitInstr" $ do + it "emits byte for no-param instruction" $ do + let ctx = E.empty + let input = Instruction (Operator Halt) Empty + execState (emitInstr input) ctx `shouldBe` ctx { _beans = [Byte 0x01] } + it "emits bytes for 2-param instruction" $ do + let ctx = E.empty + let input = Instruction (Operator Push) (Params [(Param (Integer 11)), (Param (LabelRef "main"))]) + execState (emitInstr input) ctx `shouldBe` ctx { _beans = [Byte 0x02, Byte 0x0B, Reference "main"] } + describe "emit" $ do it "label resolution works" $ do let input = "main: \n\