Skip to content
Snippets Groups Projects
Unverified Commit 61136436 authored by Pavel Kirilin's avatar Pavel Kirilin
Browse files

List replaced with array.

parent 79d87ccb
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
......@@ -2,9 +2,9 @@ module Interpreter.Definitions where
data InterpreterCode =
InterAdd Integer
InterAdd Int
| InterMov Integer
| InterSet Integer
| InterSet Int
| InterRead
| InterWrite
| InterLoop [InterpreterCode]
......
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 ()
......
......@@ -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 ()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment