diff --git a/package.yaml b/package.yaml index 77952a0cbcebaa8455a1d3ddf9f1eeee98100095..bc2352919ee1cb1d0e77e01703480e9cbb459883 100644 --- a/package.yaml +++ b/package.yaml @@ -14,6 +14,7 @@ tests: copyright: 2020 Author name here maintainer: example@example.com dependencies: +- containers >= 0.6 && < 1 - mtl >= 2.2.2 && < 3 - trifecta >= 2 && < 3 - base >= 4.7 && < 5 diff --git a/src/Interpreter/Definitions.hs b/src/Interpreter/Definitions.hs index b7c97b77ddf86cde71254db68deed2b84dd40ec4..27dcb8380d81e77da8af706c5244e3eecbeb7307 100644 --- a/src/Interpreter/Definitions.hs +++ b/src/Interpreter/Definitions.hs @@ -2,9 +2,9 @@ module Interpreter.Definitions where data InterpreterCode = - InterAdd Integer + InterAdd Int | InterMov Integer - | InterSet Integer + | InterSet Int | InterRead | InterWrite | InterLoop [InterpreterCode] diff --git a/src/Interpreter/Interpreter.hs b/src/Interpreter/Interpreter.hs index 3b04be35a96a0b6a6bf6c6bef754557c9d301472..007f989c51634e3ba8671acf6d2517a0496848a6 100644 --- a/src/Interpreter/Interpreter.hs +++ b/src/Interpreter/Interpreter.hs @@ -1,5 +1,7 @@ module Interpreter.Interpreter where +import qualified Data.Map as M +import Data.Map.Strict import System.IO import Text.Trifecta import Parser.LangParser @@ -10,15 +12,12 @@ import Interpreter.Definitions data InterpreterState = InterpreterState{ - buffer :: [Integer], + buffer :: M.Map Integer Int, inputNumber :: Integer, index :: Integer, offset :: Integer } deriving (Show) --- Initial buffer length and expanding rate -replicaFactor :: Int -replicaFactor = 350 io :: IO a -> StateT InterpreterState IO a io = liftIO @@ -30,26 +29,18 @@ prompt text = do getLine defaultState :: InterpreterState -defaultState = InterpreterState { buffer = replicate replicaFactor 0 +defaultState = InterpreterState { buffer = M.empty , inputNumber = 0 , index = 0 , offset = 0 } -updateListElement :: [Integer] -> Integer -> (Integer -> Integer) -> [Integer] -updateListElement list index update = do - let element = update $ list !! fromInteger index - let (x, _ : ys) = splitAt (fromInteger index) list - x ++ element : ys - -expandIfNeeded :: [Integer] -> Integer -> [Integer] -expandIfNeeded old_buffer new_index - | new_index < 0 = replicate replicaFactor 0 ++ old_buffer - | new_index >= 0 = old_buffer - ++ needed (new_index - toInteger (length old_buffer)) - where - needed len | len >= 0 = replicate replicaFactor 0 - | len < 0 = [] +getBufferSlice :: Integer -> Integer -> M.Map Integer Int -> [Int] +getBufferSlice size current_index current_buffer = do + let start = fromInteger $ current_index - size + let end = fromInteger $ current_index + size + let map_array = [start .. end] + Prelude.map (\el -> findWithDefault 0 el current_buffer) map_array increaseInputNumber :: InterpreterState -> InterpreterState increaseInputNumber state = state { inputNumber = inputNumber state + 1 } @@ -58,28 +49,18 @@ increaseInputNumber state = state { inputNumber = inputNumber state + 1 } walkUpdate :: Integer -> InterpreterState -> InterpreterState walkUpdate steps old_state = do let update_func t = t + steps - let updated_buffer = - expandIfNeeded (buffer old_state) (update_func $ index old_state) - -- Finding diff because we need to update current index correctly - let len_diff = - toInteger $ length updated_buffer - length (buffer old_state) -- Finding new index of our pointer - let new_index = case () of - _ | steps < 0 -> update_func $ index old_state + len_diff - | steps > 0 -> update_func $ index old_state - - old_state { buffer = updated_buffer - , index = new_index + old_state { index = update_func $ index old_state , offset = update_func $ offset old_state } -updateStateCell :: (Integer -> Integer) -> InterpreterState -> InterpreterState +updateStateCell :: (Int -> Int) -> InterpreterState -> InterpreterState updateStateCell update_func old_state = do - let new_buffer = - updateListElement (buffer old_state) (index old_state) update_func + let value = findWithDefault 0 (index old_state) (buffer old_state) + let new_buffer = insert (index old_state) (update_func value) (buffer old_state) old_state { buffer = new_buffer } -updateCell :: (Integer -> Integer) -> StateT InterpreterState IO () +updateCell :: (Int -> Int) -> StateT InterpreterState IO () updateCell update_func = modify (updateStateCell update_func) walk :: Integer -> StateT InterpreterState IO () @@ -90,29 +71,22 @@ walk steps = do doAction :: REPLCode -> State InterpreterState () doAction = undefined - -getBufferSlice :: Integer -> Integer -> [Integer] -> [Integer] -getBufferSlice size current_index current_buffer = do - let start = fromInteger $ current_index - size - let end = fromInteger $ current_index + size - drop start $ take end current_buffer - -getCell :: StateT InterpreterState IO Integer +getCell :: StateT InterpreterState IO Int getCell = do state <- get - return $ buffer state !! fromInteger (index state) + return $ findWithDefault 0 (index state) (buffer state) printCell :: StateT InterpreterState IO () printCell = do cell <- getCell - io $ putChar (toEnum (fromInteger cell) :: Char) + io $ putChar (toEnum cell :: Char) io $ hFlush stdout return () readCell :: StateT InterpreterState IO () readCell = do char <- io getChar - updateCell (const $ toInteger $ fromEnum char) + updateCell (const $ fromEnum char) return () runInterpreterLoop :: InterpreterCodeBlock -> StateT InterpreterState IO () diff --git a/src/Interpreter/REPL.hs b/src/Interpreter/REPL.hs index 78f2a78b30535873c93b1aa44b26322a3c50b186..9a67a1074e4765f73815eff7a91b5976b44caaa6 100644 --- a/src/Interpreter/REPL.hs +++ b/src/Interpreter/REPL.hs @@ -28,7 +28,7 @@ runHelper PrintBufChars = do current_state <- get let buffer_slice = getBufferSlice 5 (index current_state) (buffer current_state) - io $ print $ map (\t -> toEnum (fromInteger t) :: Char) buffer_slice + io $ print $ map (\t -> toEnum t :: Char) buffer_slice return ()