Create Fibbonacci sequence example and test

This commit is contained in:
2021-11-15 09:33:01 +01:00
parent e7c413e9eb
commit 4735f56372
2 changed files with 101 additions and 23 deletions

View File

@@ -116,7 +116,7 @@ Done:
VM {_pc = 8, _fp = -1, _stack = fromList [], _halt = True, _debug = False}
```
### Example 3
The power ($2^{10}$) computation - loop variant
The power (`2^10`) computation - loop variant
```asm
push 2
push 10
@@ -153,7 +153,7 @@ Done:
VM {_pc = 8, _fp = -1, _stack = fromList [1024], _halt = True, _debug = False}
```
### Example 4
The power ($2^{10}$) computation - recursive variant
The power (`2^10`) computation - recursive variant
```asm
push 2 ; base
push 10 ; exp
@@ -187,3 +187,43 @@ The result of execution:
Done:
VM {_pc = 8, _fp = -1, _stack = fromList [1024], _halt = True, _debug = False}
```
### Example 5
The `N`-th element of Fibbonaci sequence - recursive variant
```asm
push 6
call &fibb
clr 1
halt
fibb: lda 0 ; n | Stack:
ldl 0 ; n == 0 -> return 1 | n
je &done0 ; | n
pop ; |
ldl 0 ; n == 1 -> return 1 | n
push 1 ; | n 1
sub ; | n-1
je &done1 ; | n-1
dup ; Evaluate fibb | n-1 n-1
push 1 ; | n-1 n-1 1
sub ; | n-1 n-2
call &fibb ; | n-1 n-2 f(n-2)
clr 1 ; | n-1 f(n-2)
over ; | n-1 f(n-2) n-1
call &fibb ; | n-1 f(n-2) n-1 f(n-1)
clr 1 ; | n-1 f(n-2) f(n-1)
add ; | n-1 f(n-2)+f(n-1)
ret
done1: pop
push 1
ret
done0: pop
push 1
ret
```
The result of execution:
```
Done:
VM {_pc = 6, _fp = -1, _stack = fromList [13], _halt = True, _debug = False}
```

View File

@@ -10,6 +10,11 @@ import Runner (run, exec)
done :: [Int] -> Int -> Int -> Either String VM
done stack pc fp = return $ empty { _stack = S.fromList stack, _pc = pc, _fp = fp, _halt = True }
fibb :: Int -> Int
fibb 0 = 1
fibb 1 = 1
fibb n = fibb (n-1) + fibb (n-2)
spec :: Spec
spec = do
describe "nop" $ do
@@ -694,7 +699,7 @@ spec = do
\ call &f \n\
\ halt \n\
\ f: nop \n\
\ ret \n"
\ ret "
let expected = done [] 3 (-1)
actual <- run input
actual `shouldBe` expected
@@ -704,7 +709,7 @@ spec = do
\ halt \n\
\ f: nop \n\
\ push 4 \n\
\ ret \n"
\ ret "
-- ┌──── this is the top stack value at the time 'ret' instruction being invoked
let expected = done [4] 3 (-1)
actual <- run input
@@ -724,7 +729,7 @@ spec = do
\ add \n\
\ ret \n\
\ h: push 6 \n\
\ ret \n"
\ ret "
-- ┌───── h: _ -> 6 │ = 6
-- │ g: _ -> h + 4 │ = 10 = 6 + 4
-- │ f: _ -> h * 2 │ = 20 = 10 * 2
@@ -753,7 +758,7 @@ spec = do
\ call &f \n\
\ nop \n\
\ f: lda 0 \n\
\ halt"
\ halt "
let expected = done [14, 4, -1, 14] 7 1
actual <- run input
actual `shouldBe` expected
@@ -766,7 +771,7 @@ spec = do
\ f: lda 2 \n\
\ lda 1 \n\
\ lda 0 \n\
\ halt"
\ halt "
let expected = done [4, 11, 14, 8, -1, 4, 11, 14] 15 3
actual <- run input
actual `shouldBe` expected
@@ -1125,3 +1130,36 @@ spec = do
let expected = done [4 ^ (7 :: Int)] 8 (-1)
actual <- run input
actual `shouldBe` expected
it "example #5: 11-th element of Fibonacci sequence - recursive variant" $ do
let input = " push 11 \n\
\ call &fibb \n\
\ clr 1 \n\
\ halt \n\
\ fibb: lda 0 \n\
\ ldl 0 \n\
\ je &done0 \n\
\ pop \n\
\ ldl 0 \n\
\ push 1 \n\
\ sub \n\
\ je &done1 \n\
\ dup \n\
\ push 1 \n\
\ sub \n\
\ call &fibb \n\
\ clr 1 \n\
\ over \n\
\ call &fibb \n\
\ clr 1 \n\
\ add \n\
\ ret \n\
\ done1: pop \n\
\ push 1 \n\
\ ret \n\
\ done0: pop \n\
\ push 1 \n\
\ ret "
let expected = done [fibb 11] 6 (-1)
actual <- run input
actual `shouldBe` expected