-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A Haskell implementation of the 1# Text Register Machine -- -- An implementation of Lawrence S. Moss' 1# language and Text -- Register Machine (http://www.indiana.edu/~iulg/trm/). @package text-register-machine @version 0.2.0 -- | An implementation of Lawrence S. Moss' 1# language and Text -- Register Machine (http://www.indiana.edu/~iulg/trm/). -- -- This module also includes a slightly higher-level language, -- 1#L, that replaces the forward and backward relative jumps of -- 1# with labels and goto instructions. module Language.TRM -- | Typed representation of the 1# letters. data Letter One :: Letter Hash :: Letter -- | A wrapper around a list of Letters with an IsString -- instance, so that literal strings of 1s, #s, and -- whitespace can be used instead of lists of Ones and -- Hashes. This requires the -XOverloadedStrings flag. -- --
--   loop :: Word
--   loop = "1### 11####"
--   
newtype Word W :: [Letter] -> Word -- | Convert a Word back into a String. wordToString :: Word -> String -- | Register identifiers. newtype Register R :: Int -> Register -- | Abstract syntax for the primitive 1# instructions. data Instruction SnocOne :: Register -> Instruction SnocHash :: Register -> Instruction Forward :: Int -> Instruction Backward :: Int -> Instruction Case :: Register -> Instruction -- | Convert an Instruction to concrete syntax. instructionToString :: Instruction -> String -- | A 1# program is a Vector of Instructions. type Program = Vector Instruction -- | Convert a Program to concrete syntax. programToString :: Program -> String -- | Parse a Word into a Program; returns Nothing if -- an invalid instruction is found. parseProgram :: Word -> Maybe Program -- | A Machine consists of a Program, a program counter, and -- a Map from registers to the words they contain. data Machine M :: Program -> Int -> Map Register Word -> Machine program :: Machine -> Program pc :: Machine -> Int regs :: Machine -> Map Register Word -- | Performs the single Instruction indicated by the program -- counter, if available. Returns 'Left mach' if a step cannot be -- performed, and 'Right mach' with an updated Machine otherwise. step :: Machine -> Either Machine Machine -- | Given a Program and the initial state of the registers, return -- the final state of the registers. run :: Program -> Map Register Word -> Map Register Word -- | Wrapper around run that parses the given Word into a -- Program, and then runs it in the given register state. Returns -- the value in register 1 once the program halts. -- -- Returns Nothing when either the given Word fails to -- parse, or if the machine halts abnormally with an invalid program -- counter or values in registers other than register 1. phi :: Word -> [(Register, Word)] -> Maybe Word -- | Label representation. type Label = Int -- | Abstract syntax for a variant of 1#, 1#L with labels -- and gotos instead of forward and backward jumps. data LInstruction LSnocOne :: Register -> LInstruction LSnocHash :: Register -> LInstruction LCase :: Register -> LInstruction LGoto :: Label -> LInstruction LLabel :: Label -> LInstruction -- | A 1#L program is a Vector of LInstructions. type LProgram = Vector LInstruction -- | Convert a 1# Program into a semantically-equivalent -- 1#L LProgram. May fail with an error if the original -- Program is non-tidy, that is it contains forward or -- backward jumps to instructions outside of the program. toLabeledProgram :: Program -> LProgram -- | Convert a 1#L LProgram into a semantically-equivalent -- 1# Program. May fail with an error if the -- LProgram contains duplicate labels, jumps to undefined labels. -- An error will also occur if the LProgram contains a goto that -- would translate into a jump of 0 instructions, as this is impossible -- to express in 1#. fromLabeledProgram :: LProgram -> Program -- | Concrete syntax for 1#L, indexed by backend representation in -- the typed tagless style -- (http://okmij.org/ftp/tagless-final/index.html). class LSymantics repr snocOne :: LSymantics repr => Register -> repr () snocHash :: LSymantics repr => Register -> repr () freshLabel :: LSymantics repr => repr Label label :: LSymantics repr => Label -> repr () goto :: LSymantics repr => Label -> repr () cond :: LSymantics repr => Register -> repr () -> repr () -> repr () -> repr () -- | The default backend for LSymantics. newtype LComp a LC :: StateT (Int, Set Label) (Writer LProgram) a -> LComp a unLC :: LComp a -> StateT (Int, Set Label) (Writer LProgram) a -- | Compiles an LComp program into an LProgram. compileL :: LComp () -> LProgram -- | Given an LComp program and an initial register state, and then -- runs it in the given register state. May return Nothing if the -- program does not halt cleanly, as with run. runL :: LComp () -> [(Register, Word)] -> Maybe Word -- | A combinator to cleanly implement looping structures in LComp -- code. -- -- Takes a function that expects two arguments, continue and -- break. The body of the function is a block of LComp -- code that gets repeated whenever continue is run. If -- break is run, control jumps to the instruction after the call -- to do_. do_ :: (LComp () -> LComp () -> LComp ()) -> LComp () -- | Convenience function to create a fresh label and place it at the -- current position. freshLabelHere :: (Monad repr, LSymantics repr) => repr Label -- | Encodes an Integral type into a Word of backwards-binary -- digits using 1s and #s for 1s and -- 0s, respectively. Note that the representation of zero is a -- single # rather than the empty Word. encodeBB :: Integral a => a -> Word -- | Decodes a Word containing backwards-binary digits into a -- Num type. Fails with an error if the Word is empty. decodeBB :: Num a => Word -> a clear :: Register -> LComp () move :: Register -> Register -> LComp () copy :: Register -> Register -> Register -> LComp () succBB :: Register -> Register -> LComp () -- | Yields the successor of the backwards-binary number in register 1. -- --
--   *Language.TRM> decodeBB <$> phi succBB [(1, encodeBB 0)]
--   Just 1
--   *Language.TRM> decodeBB <$> phi succBB [(1, encodeBB 119)]
--   Just 120
--   
succBB' :: Word -- | Yields the sum of two backwards-binary numbers in registers 1 and 2. -- --
--   *Language.TRM> decodeBB <$> phi plusBB [(1, encodeBB 2), (2, encodeBB 3)]
--   Just 5
--   *Language.TRM> decodeBB <$> phi plusBB [(1, encodeBB 100), (2, encodeBB 20)]
--   Just 120
--   
plusBB' :: Word instance Eq Letter instance Eq Word instance Monoid Word instance Eq Register instance Ord Register instance Show Register instance Enum Register instance Real Register instance Integral Register instance Num Register instance Eq Instruction instance Show Instruction instance Eq Machine instance Show Machine instance Eq LInstruction instance Show LInstruction instance Functor LComp instance Applicative LComp instance Monad LComp instance MonadFix LComp instance MonadState (Int, Set Label) LComp instance MonadWriter LProgram LComp instance LSymantics LComp instance Show Word instance IsString Word