Enable 'in' instruction handler
This commit is contained in:
36
README.md
36
README.md
@@ -30,6 +30,7 @@ List of available instructions:
|
||||
| ``0x18`` | ``CLR x`` | Wipe out ``x`` values before the top value from the stack |
|
||||
|
||||
## Example
|
||||
### Example 1
|
||||
The `2*3+5` formula written as the MVM assembly code:
|
||||
```asm
|
||||
main: push 2
|
||||
@@ -41,15 +42,15 @@ main: push 2
|
||||
clr 2
|
||||
halt
|
||||
|
||||
sum: ld 0
|
||||
ld 1
|
||||
add
|
||||
ret
|
||||
sum: ld 0
|
||||
ld 1
|
||||
add
|
||||
ret
|
||||
|
||||
prd: ld 0
|
||||
ld 1
|
||||
mul
|
||||
ret
|
||||
prd: ld 0
|
||||
ld 1
|
||||
mul
|
||||
ret
|
||||
```
|
||||
The result of execution with the `debug = True` flag:
|
||||
```
|
||||
@@ -90,4 +91,23 @@ VM {_pc = 14, _fp = -1, _stack = fromList [11], _halt = False, _debug = True}
|
||||
Done:
|
||||
VM {_pc = 14, _fp = -1, _stack = fromList [11], _halt = True, _debug = True}
|
||||
|
||||
```
|
||||
### Example 2
|
||||
The base I/O example - simple echo:
|
||||
```asm
|
||||
read: in
|
||||
dup
|
||||
out
|
||||
push 0x0A
|
||||
sub
|
||||
jne &read ; loop until the input != new line (0x0A)
|
||||
halt
|
||||
```
|
||||
The execution for the input string `Hello, world!`:
|
||||
```
|
||||
Hello, world!
|
||||
|
||||
|
||||
Done:
|
||||
VM {_pc = 8, _fp = -1, _stack = fromList [], _halt = True, _debug = False}
|
||||
```
|
||||
@@ -1,7 +1,8 @@
|
||||
module VirtualMachine.Instruction where
|
||||
|
||||
import Data.Char (chr)
|
||||
import Data.Char (chr, ord)
|
||||
import Data.Word (Word8)
|
||||
import System.IO (stdin, hGetChar)
|
||||
import Control.Monad.Except (throwError)
|
||||
import Control.Monad.Trans (lift, liftIO)
|
||||
import Control.Monad.Trans.Except (ExceptT, except)
|
||||
@@ -49,7 +50,7 @@ instructions = [ Simple { _op = Nop, _noParams = 0, _noPops = 0, _sAction = (\
|
||||
, Complex { _op = Jge, _noParams = 1, _noPops = 1, _cAction = jumpIf (>=) }
|
||||
, Complex { _op = Jle, _noParams = 1, _noPops = 1, _cAction = jumpIf (<=) }
|
||||
, Complex { _op = Ld, _noParams = 1, _noPops = 0, _cAction = load }
|
||||
, Complex { _op = In, _noParams = 0, _noPops = 0, _cAction = niy In }
|
||||
, Complex { _op = In, _noParams = 0, _noPops = 0, _cAction = input }
|
||||
, Complex { _op = Out, _noParams = 0, _noPops = 1, _cAction = output }
|
||||
, Complex { _op = Clr, _noParams = 1, _noPops = 0, _cAction = clear }
|
||||
]
|
||||
@@ -112,6 +113,13 @@ jumpIf p (addr:_) (top:_) = lift $ do
|
||||
jumpIf _ [] _ = throwError "Address expected"
|
||||
jumpIf _ _ [] = throwError "Empty stack - nothing to compare"
|
||||
|
||||
input :: Params -> Pops -> ExceptT String Machine ()
|
||||
input _ _ = lift $ do
|
||||
c <- liftIO $ hGetChar stdin
|
||||
push [ord c]
|
||||
forward 1
|
||||
return()
|
||||
|
||||
output :: Params -> Pops -> ExceptT String Machine ()
|
||||
output _ (char:_) = lift $ do
|
||||
liftIO $ putStr $ [chr char]
|
||||
@@ -119,7 +127,6 @@ output _ (char:_) = lift $ do
|
||||
return ()
|
||||
output _ [] = except $ Left $ "Empty stack - nothing to output"
|
||||
|
||||
|
||||
load :: Params -> Pops -> ExceptT String Machine ()
|
||||
load (index:_) _ = do
|
||||
fp <- lift getFp
|
||||
|
||||
Reference in New Issue
Block a user