diff options
Diffstat (limited to 'src/Grasp')
-rw-r--r-- | src/Grasp/Monad.hs | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/Grasp/Monad.hs b/src/Grasp/Monad.hs index 77cbb7f..ea6cfee 100644 --- a/src/Grasp/Monad.hs +++ b/src/Grasp/Monad.hs @@ -5,7 +5,15 @@ module Grasp.Monad ( finalise, getReadHandle, - getWriteHandle + getWriteHandle, + + updateIP, + pushIP, + popIP, + peekIP, + nextIP, + + nodesOut ) where @@ -13,6 +21,8 @@ module Grasp.Monad ( import System.IO( Handle, FilePath, IOMode ) import qualified System.IO as IO +import qualified System.Random as Random + import Control.Monad.Trans.State.Lazy( StateT ) import qualified Control.Monad.Trans.State.Lazy as State @@ -182,3 +192,72 @@ nodesWithName :: [GNode] -> [GEdge] -> String -> [GNode] nodesWithName ns es name = (map fst) . (filter (\x -> (Types.gninst . snd $ x) == (Instruction name))) $ (nameNodeList ns es) + + +updateIP :: GraspM () +updateIP = do + program <- State.get + curNode <- peekIP + Monad.when (Maybe.isJust curNode) (do + nexts <- nodesOut (EdgeLabel "next") (Maybe.fromJust curNode) + r <- liftIO (Random.getStdRandom (Random.randomR (0, length nexts - 1))) + + let ips = instPtrs program + updated = if (length nexts == 0) then IP.empty else IP.shift (nexts !! r) (head ips) + ips' = updated:(tail ips) + + State.put (GraspProgram (programGraph program) ips' (fileHandles program)) ) + + + +pushIP :: GNode -> GraspM () +pushIP n = do + program <- State.get + let ips = instPtrs program + ips' = if (length ips == 0) then [] else (IP.push n (head ips)):(tail ips) + State.put (GraspProgram (programGraph program) ips' (fileHandles program)) + + + +popIP :: GraspM () +popIP = do + program <- State.get + let ips = instPtrs program + ips' = if (length ips == 0) then [] else (IP.pop (head ips)):(tail ips) + State.put (GraspProgram (programGraph program) ips' (fileHandles program)) + + + +peekIP :: GraspM (Maybe GNode) +peekIP = do + program <- State.get + let ips = instPtrs program + if (length ips == 0) then return Nothing else return (IP.peek (head ips)) + + + +nextIP :: GraspM () +nextIP = do + program <- State.get + let ips = instPtrs program + ips' = if (length ips == 0) + then [] + else if (IP.isEmpty (head ips)) + then tail ips + else (tail ips) ++ [head ips] + State.put (GraspProgram (programGraph program) ips' (fileHandles program)) + + + +nodesOut :: EdgeLabel -> GNode -> GraspM [GNode] +nodesOut s n = do + program <- State.get + curNode <- peekIP + + let gr = programGraph program + nout = Graph.lsuc gr (Types.gnode (Maybe.fromJust curNode)) + filtered = filter ((== s) . snd) nout + result = map (\(x,y) -> GNode (x, Maybe.fromJust (Graph.lab gr x))) filtered + + if (Maybe.isNothing curNode) then return [] else return result + |