65 lines
1.8 KiB
Haskell
65 lines
1.8 KiB
Haskell
module Instruction (
|
|
Op(..),
|
|
Instruction(..),
|
|
Command(..),
|
|
instructions,
|
|
instructionByOp,
|
|
toOp
|
|
) where
|
|
|
|
import qualified Data.Char as Char
|
|
import qualified Data.Map as Map
|
|
import qualified VirtualMachine as VM
|
|
|
|
data Op = Nop -- 0x00
|
|
| Halt -- 0x01
|
|
| Push -- 0x02
|
|
| Pop -- 0x03
|
|
| Dup -- 0x04
|
|
| Swap -- 0x05
|
|
| Add -- 0x06
|
|
| Sub -- 0x07
|
|
| Mul -- 0x08
|
|
| Div -- 0x09
|
|
| Neg -- 0x0a
|
|
| Not -- 0x0b
|
|
| Call -- 0x0c
|
|
| Ret -- 0x0d
|
|
| Jmp -- 0x0e
|
|
| Je -- 0x0f
|
|
| Jne -- 0x10
|
|
| Jg -- 0x11
|
|
| Jl -- 0x12
|
|
| Jge -- 0x13
|
|
| Jle -- 0x14
|
|
| Ld -- 0x15
|
|
deriving (Eq, Ord, Enum, Show, Read, Bounded)
|
|
|
|
data Instruction = Simple { op :: Op
|
|
, noParams :: Int
|
|
, noPops :: Int }
|
|
| Complex { op :: Op
|
|
, vm :: VM.VM
|
|
}
|
|
deriving (Eq, Show)
|
|
|
|
data Command = Command { instr :: Instruction
|
|
, args :: [Int]
|
|
} deriving (Eq, Show)
|
|
|
|
instructions :: [Instruction]
|
|
instructions = [ Simple { op = Nop, noParams = 0, noPops = 0 }
|
|
, Simple { op = Halt, noParams = 0, noPops = 0 }
|
|
, Simple { op = Push, noParams = 1, noPops = 0 }
|
|
, Simple { op = Pop, noParams = 0, noPops = 1 }
|
|
]
|
|
|
|
instructionByOp :: Map.Map Op Instruction
|
|
instructionByOp = Map.fromList $ map (\i -> (op i, i)) instructions
|
|
|
|
|
|
toOp :: String -> Op
|
|
toOp = read . capitalize
|
|
where capitalize :: String -> String
|
|
capitalize [] = []
|
|
capitalize (x:xs) = Char.toUpper x : map Char.toLower xs |