Last active
August 29, 2015 14:04
-
-
Save chris-taylor/03923d2c915c6a45ddd1 to your computer and use it in GitHub Desktop.
Interpreter for Hanno's made-up assembly language
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Map (Map, (!), insert, empty) | |
import Control.Monad.State (StateT, put, get, liftIO, evalStateT) | |
type Val = Int | |
type Var = String | |
data Instruction = | |
Set Val Var | |
| Print Var | |
| Add Var Var Var | |
| Copy Var Var | |
| Jump Var | |
type Program = [ Instruction ] | |
type Compiled = [ (Int, Instruction) ] | |
update var val = get >>= put . insert var val | |
retrieve var = fmap (!var) get | |
eval :: Program -> StateT (Map Var Int) IO () | |
eval program = go (compile program) | |
where | |
go [] = return () | |
go ((i, instr) : rest) = case instr of | |
Set val var -> do | |
update var val | |
go rest | |
Print var -> do | |
val <- retrieve var | |
liftIO (print val) | |
go rest | |
Add a b c -> do | |
aval <- retrieve a | |
bval <- retrieve b | |
update c (aval + bval) | |
go rest | |
Copy a b -> do | |
aval <- retrieve a | |
update b aval | |
go rest | |
Jump a -> do | |
jmp <- retrieve a | |
eval (drop (i - jmp) program) | |
compile :: Program -> Compiled | |
compile program = zip [0..] program | |
run :: Program -> IO () | |
run program = evalStateT (eval program) empty | |
----- | |
fib = [ | |
Set 1 "r0" | |
, Print "r0" | |
, Set 1 "r1" | |
, Print "r1" | |
, Add "r0" "r1" "r2" | |
, Print "r2" | |
, Copy "r1" "r0" | |
, Copy "r2" "r1" | |
, Set 5 "r3" | |
, Jump "r3" | |
] | |
main = run fib |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment