Add more unit tests for Virtual Machine
This commit is contained in:
@@ -612,3 +612,46 @@ spec = do
|
|||||||
let expected = Left "Attempt to pop from empty stack: tried to pop 1 elements, got 0"
|
let expected = Left "Attempt to pop from empty stack: tried to pop 1 elements, got 0"
|
||||||
actual <- run input
|
actual <- run input
|
||||||
actual `shouldBe` expected
|
actual `shouldBe` expected
|
||||||
|
|
||||||
|
describe "call" $ do
|
||||||
|
it "pushes return address and previous frame pointer to the stack" $ do
|
||||||
|
let input = " nop \n\
|
||||||
|
\ nop \n\
|
||||||
|
\ call &fun \n\
|
||||||
|
\ nop \n\
|
||||||
|
\ halt \n\
|
||||||
|
\ fun: halt "
|
||||||
|
-- ┌────┬─ fp points to the beginning of active stack frame
|
||||||
|
-- 1 0 │
|
||||||
|
-- │ │
|
||||||
|
let expected = done [4, -1] 6 0
|
||||||
|
-- ├───┤
|
||||||
|
-- │ │
|
||||||
|
-- │ └─ previous fp
|
||||||
|
-- └───── return address (points to the next instruction after call)
|
||||||
|
actual <- run input
|
||||||
|
actual `shouldBe` expected
|
||||||
|
it "pushes stack frames in correct order for multiple calls" $ do
|
||||||
|
let input = " nop \n\
|
||||||
|
\ call &f \n\
|
||||||
|
\ halt \n\
|
||||||
|
\ f: nop \n\
|
||||||
|
\ push 1 \n\
|
||||||
|
\ nop \n\
|
||||||
|
\ call &g \n\
|
||||||
|
\ halt \n\
|
||||||
|
\ g: nop \n\
|
||||||
|
\ call &h \n\
|
||||||
|
\ h: halt "
|
||||||
|
-- ┌──────────────────────┬─ fp points to the beginning of active stack frame
|
||||||
|
-- 6 5 4 3 2 1 0 │
|
||||||
|
-- │ │
|
||||||
|
let expected = done [14, 3, 10, 0, 1, 3, -1] 14 5
|
||||||
|
-- ├──┤ ├──┤ │ ├───┤
|
||||||
|
-- │ │ │ │ │ │ │
|
||||||
|
-- │ │ │ │ │ └───┴─ call &f
|
||||||
|
-- │ │ │ │ └──────── push 1
|
||||||
|
-- │ │ └──┴─────────── call &g
|
||||||
|
-- └──┴────────────────── call &h
|
||||||
|
actual <- run input
|
||||||
|
actual `shouldBe` expected
|
||||||
|
|||||||
Reference in New Issue
Block a user