diff --git a/.output/actual/examples/sq/output/simpleEval/logging/hello.out b/.output/actual/examples/sq/output/simpleEval/logging/hello.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/actual/examples/sq/output/simpleEval/logging/hello.out @@ -0,0 +1 @@ +-1 diff --git a/.output/actual/examples/sq/output/simpleEval/logging/longHello.out b/.output/actual/examples/sq/output/simpleEval/logging/longHello.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/actual/examples/sq/output/simpleEval/logging/longHello.out @@ -0,0 +1 @@ +-1 diff --git a/.output/actual/examples/sq/output/simpleEvalIL/logging/helloSQIL.out b/.output/actual/examples/sq/output/simpleEvalIL/logging/helloSQIL.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/actual/examples/sq/output/simpleEvalIL/logging/helloSQIL.out @@ -0,0 +1 @@ +-1 diff --git a/.output/golden/examples/sq/output/simpleEval/logging/hello.out b/.output/golden/examples/sq/output/simpleEval/logging/hello.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/golden/examples/sq/output/simpleEval/logging/hello.out @@ -0,0 +1 @@ +-1 diff --git a/.output/golden/examples/sq/output/simpleEval/logging/longHello.out b/.output/golden/examples/sq/output/simpleEval/logging/longHello.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/golden/examples/sq/output/simpleEval/logging/longHello.out @@ -0,0 +1 @@ +-1 diff --git a/.output/golden/examples/sq/output/simpleEvalIL/logging/helloSQIL.out b/.output/golden/examples/sq/output/simpleEvalIL/logging/helloSQIL.out new file mode 100644 index 000000000..3a2e3f498 --- /dev/null +++ b/.output/golden/examples/sq/output/simpleEvalIL/logging/helloSQIL.out @@ -0,0 +1 @@ +-1 diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 9c958ba55..b82bd39f6 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,4 +1,7 @@ # πŸ“… Revision history for HelMA +## 0.6.6.0 -- 2021-06-11 + +* Use Functional Dependency in Memories and Collections ## 0.6.5.0 -- 2021-06-06 diff --git a/docs/README.md b/docs/README.md index 3d2a7a46b..fee61076b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,10 @@ # Welcome to πŸ”§ 🎨 HelMA πŸ”§ 🎨 **HelMA** - Heavenly Esoteric Little Minimal Automaton for Esoteric Languages implemented in Haskell +**πŸ§‘β€πŸ”§ πŸ§‘β€πŸŽ¨ HAMAMAL** - Holistic Actual Minimalist Automatic Mechanical Languages is a kind of [Low-level] [First-generation] [Code] for Esoteric Languages. + +**πŸ§‘β€πŸ”§ πŸ§‘β€πŸŽ¨ HAMALAM** - Holistic Actual Minimalist Languages of Automatic Machine + ``` FOR everyone WHO want to run esoteric languages @@ -26,3 +30,7 @@ THAT is an Evaluator and an Interpreter for Esoteric Languages (EsoAutomata) * [CODE OF CONDUCT](CODE_OF_CONDUCT.md) ## 🌈 ❀️ πŸ’› πŸ’š πŸ’™ 🀍 πŸ–€ πŸ¦„ + +[Low-level]: https://en.wikipedia.org/wiki/Low-level_programming_language +[First-generation]: https://en.wikipedia.org/wiki/First-generation_programming_language +[Code]: https://en.wikipedia.org/wiki/Machine_code diff --git a/helma.cabal b/helma.cabal index c160067d7..d04faed83 100644 --- a/helma.cabal +++ b/helma.cabal @@ -1,7 +1,7 @@ cabal-version: 2.2 name: helma -version: 0.6.5.0 +version: 0.6.6.0 synopsis: HELMA - Heavenly Esoteric Little Minimal Automaton for Esoteric Languages implemented in Haskell description: Please see the README on GitHub at @@ -34,12 +34,27 @@ library exposed-modules: HelVM.HelMA.Common.API.EvalParams HelVM.HelMA.Common.API.TypeOptions + HelVM.HelMA.Common.BinaryOperator + HelVM.HelMA.Common.Collections + HelVM.HelMA.Common.Collections.Drop + HelVM.HelMA.Common.Collections.FromList + HelVM.HelMA.Common.Collections.Insert + HelVM.HelMA.Common.Collections.Lookup + HelVM.HelMA.Common.Collections.Pop + HelVM.HelMA.Common.Collections.SplitAt HelVM.HelMA.Common.Memories.RAM + HelVM.HelMA.Common.Memories.RAMConst + HelVM.HelMA.Common.Memories.RAMImpl + HelVM.HelMA.Common.Memories.RAMUtil HelVM.HelMA.Common.Memories.Stack + HelVM.HelMA.Common.Memories.StackConst + HelVM.HelMA.Common.Memories.StackImpl + HelVM.HelMA.Common.Memories.StackUtil HelVM.HelMA.Common.IO.MockIO HelVM.HelMA.Common.IO.WrapperIO HelVM.HelMA.Common.OrError HelVM.HelMA.Common.Types.CellType + HelVM.HelMA.Common.Types.IntCellType HelVM.HelMA.Common.Types.StackType HelVM.HelMA.Common.Types.TokenType HelVM.HelMA.Common.Types.RAMType @@ -56,7 +71,6 @@ library HelVM.HelMA.Automata.ETA.Evaluator HelVM.HelMA.Automata.ETA.EvaluatorUtil HelVM.HelMA.Automata.ETA.Lexer - HelVM.HelMA.Automata.ETA.StackOfSymbols HelVM.HelMA.Automata.ETA.Token HelVM.HelMA.Automata.SubLeq.Evaluator @@ -67,7 +81,6 @@ library HelVM.HelMA.Automata.WhiteSpace.Lexer HelVM.HelMA.Automata.WhiteSpace.OperandParsers HelVM.HelMA.Automata.WhiteSpace.Parser - HelVM.HelMA.Automata.WhiteSpace.StackOfSymbols HelVM.HelMA.Automata.WhiteSpace.Token other-extensions: build-depends: @@ -77,6 +90,7 @@ library , mtl , split , data-default + , ilist mixins: base hiding (Prelude) , relude (Relude as Prelude, Relude.Extra, Relude.Unsafe) @@ -149,6 +163,7 @@ test-suite spec Spec HelVM.HelMA.Common.FilterIf0Spec + HelVM.HelMA.Common.UtilSpec HelVM.HelMA.Automata.CartesianProduct HelVM.HelMA.Automata.Expectations diff --git a/hs/app/AppOptions.hs b/hs/app/AppOptions.hs index e32dfb4d4..854022d21 100644 --- a/hs/app/AppOptions.hs +++ b/hs/app/AppOptions.hs @@ -1,6 +1,7 @@ module AppOptions where import HelVM.HelMA.Common.Types.CellType +import HelVM.HelMA.Common.Types.IntCellType import HelVM.HelMA.Common.Types.StackType import HelVM.HelMA.Common.Types.RAMType @@ -63,6 +64,13 @@ optionParser = AppOptions <> value (show defaultCellType) <> showDefault ) + <*> strOption ( long "IntCellType" + <> short 'i' + <> metavar "[IntCellType]" + <> help ("Implementation of IntCell " <> show intCellTypes) + <> value (show defaultIntCellType) + <> showDefault + ) <*> switch ( long "exec" <> short 'e' <> help "Exec" @@ -80,6 +88,7 @@ data AppOptions = AppOptions , ramType :: String -- RAMType , stackType :: String -- StackType , cellType :: String -- CellType + , intCellType :: String -- IntCellType , exec :: Exec , file :: String } @@ -94,7 +103,7 @@ type Exec = Bool ---- data Lang = Cat | Rev | BF | ETA | SQ | STN | WS - deriving (Eq, Read, Show) + deriving (Eq , Read , Show) langs :: [Lang] langs = [Cat , Rev , BF , ETA , SQ , STN , WS] @@ -106,10 +115,10 @@ parseLang raw = valid $ readMaybe raw where ---- -data Impl = Monadic | Interact deriving (Eq, Read, Show) +data Impl = Monadic | Interact deriving (Eq , Read , Show) impls :: [Impl] -impls = [Monadic, Interact] +impls = [Monadic , Interact] parseImpl :: String -> Impl parseImpl raw = valid $ readMaybe raw where diff --git a/hs/app/Main.hs b/hs/app/Main.hs index b1b3ba3c8..f76d017ea 100644 --- a/hs/app/Main.hs +++ b/hs/app/Main.hs @@ -7,6 +7,7 @@ import HelVM.HelMA.Common.IO.WrapperIO import HelVM.HelMA.Common.API.TypeOptions import HelVM.HelMA.Common.Types.CellType +import HelVM.HelMA.Common.Types.IntCellType import HelVM.HelMA.Common.Types.StackType import HelVM.HelMA.Common.Types.TokenType import HelVM.HelMA.Common.Types.RAMType @@ -39,14 +40,15 @@ main :: IO () main = runApp =<< execParser opts where opts = info (optionParser <**> helper) ( fullDesc - <> header "HelMA: The Interpreter of BrainFuck, ETA, SubLeq and WhiteSpace" + <> header "HelMA: The Interpreter of BrainFuck , ETA , SubLeq and WhiteSpace" <> progDesc "Runs esoteric programs - complete with pretty bad error messages" ) runApp:: AppOptions -> IO () -runApp AppOptions{lang, minified, emitTL, emitIL, asciiLabels, impl, ramType, stackType, cellType, exec, file} = do +runApp AppOptions{lang , minified , emitTL , emitIL , asciiLabels , impl , ramType , stackType , cellType , intCellType , exec , file} = do IO.hSetBuffering stdout IO.NoBuffering source <- readSource exec file - run minified emitTL emitIL (parseImpl impl) (TypeOptions (parseRAMType ramType) (parseStackType stackType) (parseCellType cellType)) asciiLabels (parseLang lang) source + run minified emitTL emitIL (parseImpl impl) typeOptions asciiLabels (parseLang lang) source + where typeOptions = TypeOptions (parseRAMType ramType) (parseStackType stackType) (parseCellType cellType) (parseIntCellType intCellType) readSource :: Exec -> String -> IO Source readSource True = pure @@ -79,17 +81,17 @@ parse WS a = pPrintNoColor . flip (WS.parse WhiteTokenType) a parse lang _ = tokenize lang eval :: Impl -> TypeOptions -> AsciiLabels -> Lang -> Source -> IO () -eval impl options a lang s = evalParams impl (lang, EvalParams {asciiLabel = a, source = s, typeOptions = options}) +eval impl options a lang s = evalParams impl (lang , EvalParams {asciiLabel = a , source = s , typeOptions = options}) -evalParams :: Impl -> (Lang, EvalParams) -> IO () +evalParams :: Impl -> (Lang , EvalParams) -> IO () evalParams Interact = IO.interact . interactEval' evalParams Monadic = monadicEval' -interactEval' :: (Lang, EvalParams) -> Interact -interactEval' (lang, params) = interactEval lang params +interactEval' :: (Lang , EvalParams) -> Interact +interactEval' (lang , params) = interactEval lang params -monadicEval' :: WrapperIO m => (Lang, EvalParams) -> m () -monadicEval' (lang, params) = monadicEval lang params +monadicEval' :: WrapperIO m => (Lang , EvalParams) -> m () +monadicEval' (lang , params) = monadicEval lang params interactEval :: Lang -> EvalParams -> Interact interactEval Cat = Cat.evalParams diff --git a/hs/src/HelVM/HelMA/Automata/BrainFuck/Evaluator.hs b/hs/src/HelVM/HelMA/Automata/BrainFuck/Evaluator.hs index 2a1186be1..ea0b23c50 100644 --- a/hs/src/HelVM/HelMA/Automata/BrainFuck/Evaluator.hs +++ b/hs/src/HelVM/HelMA/Automata/BrainFuck/Evaluator.hs @@ -39,27 +39,28 @@ eval source Word32Type = start source (newTape :: FullTape Word32) eval source Int64Type = start source (newTape :: FullTape Int64) eval source Word64Type = start source (newTape :: FullTape Word64) -start :: (Symbol s, Evaluator r) => String -> FullTape s -> r -start source = doInstruction ([], tokenize source) - class Evaluator r where + + start :: Symbol s => String -> FullTape s -> r + start source = doInstruction ([] , tokenize source) + doInstruction :: Symbol s => Table -> FullTape s -> r - doInstruction table@(_, MoveR :_) tape = doInstruction (nextInst table) (moveHeadRight tape) - doInstruction table@(_, MoveL :_) tape = doInstruction (nextInst table) (moveHeadLeft tape) - doInstruction table@(_, Inc :_) tape = doInstruction (nextInst table) (wNextSymbol tape) - doInstruction table@(_, Dec :_) tape = doInstruction (nextInst table) (wPrevSymbol tape) - doInstruction table@(_, JmpPast :_) tape = doJmpPast table tape - doInstruction table@(_, JmpBack :_) tape = doJmpBack table tape - doInstruction table@(_, Output :_) tape = doOutputChar table tape - doInstruction table@(_, Input :_) tape = doInputChar table tape - doInstruction (_, [] ) _ = doEnd + doInstruction table@(_ , MoveR :_) tape = doInstruction (nextInst table) (moveHeadRight tape) + doInstruction table@(_ , MoveL :_) tape = doInstruction (nextInst table) (moveHeadLeft tape) + doInstruction table@(_ , Inc :_) tape = doInstruction (nextInst table) (wNextSymbol tape) + doInstruction table@(_ , Dec :_) tape = doInstruction (nextInst table) (wPrevSymbol tape) + doInstruction table@(_ , JmpPast :_) tape = doJmpPast table tape + doInstruction table@(_ , JmpBack :_) tape = doJmpBack table tape + doInstruction table@(_ , Output :_) tape = doOutputChar table tape + doInstruction table@(_ , Input :_) tape = doInputChar table tape + doInstruction (_ , [] ) _ = doEnd doJmpPast :: Symbol s => Table -> FullTape s -> r - doJmpPast table tape@(_, 0:_) = doInstruction (jumpPast table) tape + doJmpPast table tape@(_ , 0:_) = doInstruction (jumpPast table) tape doJmpPast table tape = doInstruction (nextInst table) tape doJmpBack :: Symbol s => Table -> FullTape s -> r - doJmpBack table tape@(_, 0:_) = doInstruction (nextInst table) tape + doJmpBack table tape@(_ , 0:_) = doInstruction (nextInst table) tape doJmpBack table tape = doInstruction (jumpBack table) tape doEnd :: r @@ -74,8 +75,8 @@ instance Evaluator Interact where doInputChar _ tape [] = error $ "Empty input " <> show tape doInputChar table tape (char:input) = doInstruction (nextInst table) (writeSymbol char tape) input - doOutputChar _ tape@(_, []) _ = error $ "Illegal State " <> show tape - doOutputChar table tape@(_, symbol:_) input = toChar symbol : doInstruction (nextInst table) tape input + doOutputChar _ tape@(_ , []) _ = error $ "Illegal State " <> show tape + doOutputChar table tape@(_ , symbol:_) input = toChar symbol : doInstruction (nextInst table) tape input ---- @@ -85,5 +86,5 @@ instance WrapperIO m => Evaluator (m ()) where doInputChar table tape = doInputChar' =<< wGetChar where doInputChar' char = doInstruction (nextInst table) $ writeSymbol char tape - doOutputChar _ (_, []) = error "Illegal State" - doOutputChar table tape@(_, symbol:_) = wPutChar (toChar symbol) *> doInstruction (nextInst table) tape + doOutputChar _ (_ , []) = error "Illegal State" + doOutputChar table tape@(_ , symbol:_) = wPutChar (toChar symbol) *> doInstruction (nextInst table) tape diff --git a/hs/src/HelVM/HelMA/Automata/BrainFuck/Symbol.hs b/hs/src/HelVM/HelMA/Automata/BrainFuck/Symbol.hs index ed32f04cd..9e81a1e89 100644 --- a/hs/src/HelVM/HelMA/Automata/BrainFuck/Symbol.hs +++ b/hs/src/HelVM/HelMA/Automata/BrainFuck/Symbol.hs @@ -1,15 +1,16 @@ module HelVM.HelMA.Automata.BrainFuck.Symbol ( Symbol, - HelVM.HelMA.Automata.BrainFuck.Symbol.def, - HelVM.HelMA.Automata.BrainFuck.Symbol.next, - HelVM.HelMA.Automata.BrainFuck.Symbol.prev, + def, + next, + prev, fromChar, toChar ) where -import Relude.Extra as Extra +import Data.Default (Default) -import Data.Default as Default +import qualified Data.Default as Default +import qualified Relude.Extra as Extra def :: Symbol s => s def = Default.def @@ -20,7 +21,7 @@ next = Extra.next prev :: Symbol s => s -> s prev = Extra.prev -class (Bounded a, Default a, Enum a, Eq a, Num a, Show a) => Symbol a where +class (Bounded a , Default a , Enum a , Eq a , Num a , Show a) => Symbol a where fromChar :: Char -> a toChar :: a -> Char diff --git a/hs/src/HelVM/HelMA/Automata/BrainFuck/TableOfInstructions.hs b/hs/src/HelVM/HelMA/Automata/BrainFuck/TableOfInstructions.hs index 26a05243c..0a706cd93 100644 --- a/hs/src/HelVM/HelMA/Automata/BrainFuck/TableOfInstructions.hs +++ b/hs/src/HelVM/HelMA/Automata/BrainFuck/TableOfInstructions.hs @@ -3,25 +3,25 @@ module HelVM.HelMA.Automata.BrainFuck.TableOfInstructions where import HelVM.HelMA.Automata.BrainFuck.Token type HalfTable = TokenList -type Table = (HalfTable, HalfTable) +type Table = (HalfTable , HalfTable) type TableD = Table -> Table prevInst :: TableD -prevInst (inst:prev, next) = (prev, inst:next) -prevInst ([], _) = error "End of the table" +prevInst (inst:prev , next) = (prev , inst:next) +prevInst ([] , _) = error "End of the table" nextInst :: TableD -nextInst (prev, inst:next) = (inst:prev, next) -nextInst (_, []) = error "End of the table" +nextInst (prev , inst:next) = (inst:prev , next) +nextInst (_ , []) = error "End of the table" matchPrevJmp :: TableD -matchPrevJmp table@(JmpPast:_, _) = table -matchPrevJmp table@(JmpBack:_, _) = matchPrevJmp $ prevInst $ matchPrevJmp $ prevInst table +matchPrevJmp table@(JmpPast:_ , _) = table +matchPrevJmp table@(JmpBack:_ , _) = matchPrevJmp $ prevInst $ matchPrevJmp $ prevInst table matchPrevJmp table = matchPrevJmp $ prevInst table matchNextJmp :: TableD -matchNextJmp table@(_, JmpBack:_) = nextInst table -matchNextJmp table@(_, JmpPast:_) = matchNextJmp $ matchNextJmp $ nextInst table +matchNextJmp table@(_ , JmpBack:_) = nextInst table +matchNextJmp table@(_ , JmpPast:_) = matchNextJmp $ matchNextJmp $ nextInst table matchNextJmp table = matchNextJmp $ nextInst table jumpPast :: TableD diff --git a/hs/src/HelVM/HelMA/Automata/BrainFuck/TapeOfSymbols.hs b/hs/src/HelVM/HelMA/Automata/BrainFuck/TapeOfSymbols.hs index e5087b9ad..55911f2aa 100644 --- a/hs/src/HelVM/HelMA/Automata/BrainFuck/TapeOfSymbols.hs +++ b/hs/src/HelVM/HelMA/Automata/BrainFuck/TapeOfSymbols.hs @@ -14,7 +14,7 @@ import HelVM.HelMA.Common.Util ---- -type FullTape s = (HalfTape s, HalfTape s) +type FullTape s = (HalfTape s , HalfTape s) type FullTapeD s = D (FullTape s) type HalfTape s = [s] @@ -22,20 +22,20 @@ type HalfTape s = [s] ---- newTape :: (Symbol s) => FullTape s -newTape = ([def], [def]) +newTape = ([def] , [def]) moveHeadRight :: (Symbol s) => FullTapeD s -moveHeadRight (cell:left, right) = pad (left, cell:right) -moveHeadRight ([], _) = error "End of the Tipe" +moveHeadRight (cell:left , right) = pad (left , cell:right) +moveHeadRight ([] , _) = error "End of the Tipe" moveHeadLeft :: (Symbol s) => FullTapeD s -moveHeadLeft (left, cell:right) = pad (cell:left, right) -moveHeadLeft (_, []) = error "End of the Tipe" +moveHeadLeft (left , cell:right) = pad (cell:left , right) +moveHeadLeft (_ , []) = error "End of the Tipe" pad :: (Symbol s) => FullTapeD s -pad ([], []) = newTape -pad ([], right) = ([def], right) -pad (left, []) = (left, [def]) +pad ([] , []) = newTape +pad ([] , right) = ([def] , right) +pad (left , []) = (left , [def]) pad tape = tape ---- @@ -50,5 +50,5 @@ writeSymbol :: (Symbol s) => Char -> FullTapeD s writeSymbol symbol = modifyCell (const $ fromChar symbol) modifyCell :: D s -> FullTapeD s -modifyCell f (left, cell:right) = (left, f cell:right) -modifyCell _ (_, []) = error "End of the Tape" +modifyCell f (left , cell:right) = (left , f cell:right) +modifyCell _ (_ , []) = error "End of the Tape" diff --git a/hs/src/HelVM/HelMA/Automata/BrainFuck/Token.hs b/hs/src/HelVM/HelMA/Automata/BrainFuck/Token.hs index d8aabc099..291f5a947 100644 --- a/hs/src/HelVM/HelMA/Automata/BrainFuck/Token.hs +++ b/hs/src/HelVM/HelMA/Automata/BrainFuck/Token.hs @@ -13,7 +13,7 @@ data Token = | Input | JmpPast | JmpBack - deriving (Eq, Ord, Enum) + deriving (Eq , Ord , Enum) type TokenList = [Token] @@ -34,6 +34,6 @@ instance Read Token where readsPrec _ "-" = [( Dec , "")] readsPrec _ "." = [( Output , "")] readsPrec _ "," = [( Input , "")] - readsPrec _ "[" = [( JmpPast, "")] - readsPrec _ "]" = [( JmpBack, "")] + readsPrec _ "[" = [( JmpPast , "")] + readsPrec _ "]" = [( JmpBack , "")] readsPrec _ _ = [] diff --git a/hs/src/HelVM/HelMA/Automata/ETA/Evaluator.hs b/hs/src/HelVM/HelMA/Automata/ETA/Evaluator.hs index 02a9b0008..b45de01b6 100644 --- a/hs/src/HelVM/HelMA/Automata/ETA/Evaluator.hs +++ b/hs/src/HelVM/HelMA/Automata/ETA/Evaluator.hs @@ -9,17 +9,18 @@ module HelVM.HelMA.Automata.ETA.Evaluator ( import HelVM.HelMA.Automata.ETA.EvaluatorUtil import HelVM.HelMA.Automata.ETA.Lexer -import HelVM.HelMA.Automata.ETA.StackOfSymbols as Stack import HelVM.HelMA.Automata.ETA.Token import HelVM.HelMA.Common.API.EvalParams import HelVM.HelMA.Common.API.TypeOptions import HelVM.HelMA.Common.IO.WrapperIO -import HelVM.HelMA.Common.Memories.Stack as Stack +import HelVM.HelMA.Common.Memories.StackConst as Stack import HelVM.HelMA.Common.Util import HelVM.HelMA.Common.Types.StackType -import Data.Sequence as Seq (fromList) +import Data.Default as Default + +import qualified Data.Sequence as Seq batchUncurryEval :: (Source , StackType) -> Output batchUncurryEval = flipUncurryEval emptyInput @@ -27,35 +28,36 @@ batchUncurryEval = flipUncurryEval emptyInput flipUncurryEval :: Input -> (Source , StackType) -> Output flipUncurryEval = flip uncurryEval -uncurryEval :: Evaluator r => (Source , StackType) -> r +uncurryEval :: Evaluator Symbol r => (Source , StackType) -> r uncurryEval = uncurry eval ---- -evalParams :: Evaluator r => EvalParams -> r +evalParams :: Evaluator Symbol r => EvalParams -> r evalParams p = eval (source p) (stack $ typeOptions p) -eval :: Evaluator r => Source -> StackType -> r +eval :: Evaluator Symbol r => Source -> StackType -> r eval source = evalTL $ tokenize source -evalTL :: Evaluator r => TokenList -> StackType -> r -evalTL tl ListStackType = start tl ([] :: SymbolList) -evalTL tl SeqStackType = start tl (Seq.fromList [] :: Seq Symbol) +evalTL :: Evaluator Symbol r => TokenList -> StackType -> r +evalTL tl ListStackType = start tl [] +evalTL tl SeqStackType = start tl Seq.empty -start :: (Stack Symbol m, Evaluator r) => TokenList -> m -> r +start :: Evaluator Symbol r => Stack Symbol m => TokenList -> m -> r start il = next (IU il 0) -class Evaluator r where - next :: Stack Symbol m => InstructionUnit -> m -> r - next iu s = doInstruction t iu' s where (t, iu') = nextIU iu +class (Show cell , Integral cell) => Evaluator cell r where + + next :: Stack cell m => InstructionUnit -> m -> r + next iu s = doInstruction t iu' s where (t , iu') = nextIU iu - doInstruction :: Stack Symbol m => Maybe Token -> InstructionUnit -> m -> r + doInstruction :: Stack cell m => Maybe Token -> InstructionUnit -> m -> r -- IO instructions doInstruction (Just O) iu s = doOutputChar iu s doInstruction (Just I) iu s = doInputChar iu s -- Stack instructions - doInstruction (Just N) iu s = next iu' (push1 (symbol::Symbol) s) where (symbol, iu') = parseNumber iu + doInstruction (Just N) iu s = next iu' (push1 symbol s) where (symbol , iu') = parseNumber iu doInstruction (Just H) iu s = next iu $ halibut s -- Arithmetic @@ -64,17 +66,17 @@ class Evaluator r where -- Control doInstruction (Just R) iu s = next iu s - doInstruction (Just A) iu@(IU il ic) s = next iu (push1 (nextLabel il ic) s) + doInstruction (Just A) iu@(IU il ic) s = next iu (push1 (genericNextLabel il ic) s) doInstruction (Just T) iu@(IU il _ ) s = transfer $ pop2 s where - transfer (_, 0, s') = next iu s' - transfer (0, _, _ ) = doEnd iu s - transfer (l, _, s') = next (IU il $ findAddress il l) s' + transfer (_ , 0 , s') = next iu s' + transfer (0 , _ , _ ) = doEnd iu s + transfer (l , _ , s') = next (IU il $ genericFindAddress il l) s' doInstruction Nothing iu s = doEnd iu s ---- - doEnd :: Stack Symbol m => InstructionUnit -> m -> r - doOutputChar :: Stack Symbol m => InstructionUnit -> m -> r - doInputChar :: Stack Symbol m => InstructionUnit -> m -> r + doEnd :: Stack cell m => InstructionUnit -> m -> r + doOutputChar :: Stack cell m => InstructionUnit -> m -> r + doInputChar :: Stack cell m => InstructionUnit -> m -> r ---- @@ -83,20 +85,20 @@ emptyInputError t = error $ "Empty input for token " <> show t ---- -instance Evaluator Interact where +instance (Default cell , Read cell , Show cell , Integral cell) => Evaluator cell Interact where doEnd _ _ _ = [] doInputChar _ _ [] = emptyInputError I ([]::Input) - doInputChar iu s (char:input) = next iu (push1 (ord char) s) input + doInputChar iu s (char:input) = next iu (pushChar1 char s) input - doOutputChar iu s input = chr symbol : next iu s' input where (symbol, s') = pop1 s + doOutputChar iu s input = genericChr symbol : next iu s' input where (symbol , s') = pop1 s ---- -instance WrapperIO m => Evaluator (m ()) where +instance (Default cell , Read cell , Show cell , Integral cell , WrapperIO m) => Evaluator cell (m ()) where doEnd iu s = wLogShow iu *> wLogShow s doInputChar iu s = doInputChar' =<< wGetChar where - doInputChar' char = next iu $ push1 (ord char) s + doInputChar' char = next iu $ pushChar1 char s - doOutputChar iu s = wPutChar (chr symbol) *> next iu s' where (symbol, s') = pop1 s + doOutputChar iu s = wPutChar (genericChr symbol) *> next iu s' where (symbol , s') = pop1 s diff --git a/hs/src/HelVM/HelMA/Automata/ETA/EvaluatorUtil.hs b/hs/src/HelVM/HelMA/Automata/ETA/EvaluatorUtil.hs index bc84c99dc..f93d3dc46 100644 --- a/hs/src/HelVM/HelMA/Automata/ETA/EvaluatorUtil.hs +++ b/hs/src/HelVM/HelMA/Automata/ETA/EvaluatorUtil.hs @@ -16,29 +16,36 @@ type InstructionCounter = InstructionAddress data InstructionUnit = IU TokenList InstructionCounter deriving (Show) -type OperandIUParser a = InstructionUnit -> (a, InstructionUnit) +type OperandIUParser a = InstructionUnit -> (a , InstructionUnit) parseNumber :: (Integral a) => OperandIUParser a parseNumber iu = parseNumber' [] (nextIU iu) parseNumber' :: (Integral a) => TokenList -> (Maybe Token , InstructionUnit) -> (a , InstructionUnit) -parseNumber' acc (Just E , iu) = (makeIntegral acc, iu) +parseNumber' acc (Just E , iu) = (makeIntegral acc , iu) parseNumber' acc (Just R , iu) = parseNumber' acc (nextIU iu) parseNumber' acc (Just t , iu) = parseNumber' (t:acc) (nextIU iu) -parseNumber' acc (Nothing, iu) = (makeIntegral acc, iu) +parseNumber' acc (Nothing , iu) = (makeIntegral acc , iu) nextIU :: OperandIUParser (Maybe Token) nextIU iu@(IU il ic) | ic < length il = (Just (indexOrError ("nextIU"::Text,iu) il ic), IU il (ic+1)) - | otherwise = (Nothing, iu) + | otherwise = (Nothing , iu) makeIntegral :: (Integral a) => TokenList -> a makeIntegral = foldr (mul7AndAdd . toDigit) 0 -findAddress :: TokenList -> Symbol -> InstructionAddress +genericFindAddress :: Integral cell => TokenList -> cell -> InstructionAddress +genericFindAddress il address = findAddress il $ fromIntegral address + +genericNextLabel :: Integral cell => TokenList -> InstructionAddress -> cell +genericNextLabel il ic = fromIntegral $ nextLabel il ic + +---- + +findAddress :: TokenList -> Int -> InstructionAddress findAddress _ 1 = 0 findAddress il address = indexOrError ("findAddress"::Text,il,address) (elemIndices R (il <> [R])) (address-2) + 1 -nextLabel :: TokenList -> InstructionAddress -> Symbol -nextLabel il ic = length (elemIndices R il') + 2 - where (il',_) = splitAt ic il +nextLabel :: TokenList -> InstructionAddress -> Int +nextLabel il ic = length (elemIndices R il') + 2 where (il',_) = splitAt ic il diff --git a/hs/src/HelVM/HelMA/Automata/ETA/StackOfSymbols.hs b/hs/src/HelVM/HelMA/Automata/ETA/StackOfSymbols.hs deleted file mode 100644 index 37d9ede9e..000000000 --- a/hs/src/HelVM/HelMA/Automata/ETA/StackOfSymbols.hs +++ /dev/null @@ -1,31 +0,0 @@ -module HelVM.HelMA.Automata.ETA.StackOfSymbols where - -import HelVM.HelMA.Automata.ETA.EvaluatorUtil - -import HelVM.HelMA.Common.Memories.Stack - --- Arithmetic - -divMod :: Stack Symbol m => m -> m -divMod stack = push2 (symbol' `mod` symbol ::Symbol) (symbol' `div` symbol ::Symbol) stack' - where (symbol, symbol', stack') = pop2 stack - -sub :: Stack Symbol m => m -> m -sub stack = push1 (symbol' - symbol ::Symbol) stack' - where (symbol, symbol', stack') = pop2 stack - --- Stack instructions - -halibut :: Stack Symbol m => m -> m -halibut stack - | i <= 0 = copy (negate i) stack' - | otherwise = move (0 ::Symbol) i stack' - where (i, stack') = pop1 stack - -move :: Stack Symbol m => Symbol -> Index -> m -> m -move symbol i stack = tops <> middles <> bottoms where - (middles, stack') = splitAt' symbol i stack - (tops, bottoms) = splitAt' symbol 1 stack' - -copy :: Stack Symbol m => Index -> m -> m -copy i stack = push1 (select i stack ::Symbol) stack diff --git a/hs/src/HelVM/HelMA/Automata/ETA/Token.hs b/hs/src/HelVM/HelMA/Automata/ETA/Token.hs index 9c8f6c27a..40a3a0438 100644 --- a/hs/src/HelVM/HelMA/Automata/ETA/Token.hs +++ b/hs/src/HelVM/HelMA/Automata/ETA/Token.hs @@ -5,7 +5,7 @@ import Text.Read import qualified Text.Show data Token = E | T | A | O | I | N | S | H | R - deriving (Eq, Ord, Enum, Show, Read) + deriving (Eq , Ord , Enum , Show , Read) type TokenList = [Token] @@ -47,8 +47,8 @@ instance Read WhiteToken where readsPrec _ "H" = [( WhiteToken H , "")] readsPrec _ _ = [] -tokenToWhiteTokenPair :: Token -> (WhiteToken, String) -tokenToWhiteTokenPair t = (WhiteToken t, "") +tokenToWhiteTokenPair :: Token -> (WhiteToken , String) +tokenToWhiteTokenPair t = (WhiteToken t , "") whiteTokenListToTokenList :: WhiteTokenList -> TokenList whiteTokenListToTokenList = fmap whiteTokenToToken diff --git a/hs/src/HelVM/HelMA/Automata/SubLeq/Evaluator.hs b/hs/src/HelVM/HelMA/Automata/SubLeq/Evaluator.hs index 0ea8d5600..b8c4ca2fb 100644 --- a/hs/src/HelVM/HelMA/Automata/SubLeq/Evaluator.hs +++ b/hs/src/HelVM/HelMA/Automata/SubLeq/Evaluator.hs @@ -14,11 +14,16 @@ import HelVM.HelMA.Automata.SubLeq.Symbol import HelVM.HelMA.Common.API.EvalParams import HelVM.HelMA.Common.API.TypeOptions +import HelVM.HelMA.Common.Collections.FromList import HelVM.HelMA.Common.IO.WrapperIO -import HelVM.HelMA.Common.Memories.RAM as RAM +import HelVM.HelMA.Common.Memories.RAMConst as RAM import HelVM.HelMA.Common.Types.RAMType import HelVM.HelMA.Common.Util +import Data.Default as Default + +import qualified Data.Sequence as Seq + batchSimpleEval :: Source -> Output batchSimpleEval = flipSimpleEval emptyInput @@ -31,61 +36,65 @@ flipSimpleEval = flip simpleEval flipSimpleEvalIL :: Input -> SymbolList -> Output flipSimpleEvalIL = flip simpleEvalIL -simpleEval :: Evaluator r => Source -> r +simpleEval :: Evaluator Symbol r => Source -> r simpleEval source = eval source defaultRAMType -simpleEvalIL :: Evaluator r => SymbolList -> r +simpleEvalIL :: Evaluator Symbol r => SymbolList -> r simpleEvalIL il = evalIL il defaultRAMType -evalParams :: Evaluator r => EvalParams -> r +evalParams :: Evaluator Symbol r => EvalParams -> r evalParams p = eval (source p) (ram $ typeOptions p) -eval :: Evaluator r => Source -> RAMType -> r +eval :: Evaluator Symbol r => Source -> RAMType -> r eval source = evalIL $ tokenize source -evalIL :: Evaluator r => SymbolList -> RAMType -> r -evalIL il ListRAMType = start (RAM.fromList il::SymbolList) -evalIL il SeqRAMType = start (RAM.fromList il::Seq Symbol) -evalIL il IntMapRAMType = start (RAM.fromList il::IntMap Symbol) +class (Default cell , Integral cell) => Evaluator cell r where + + evalIL :: [cell] -> RAMType -> r + evalIL = flip evalIL' + + evalIL' :: RAMType -> [cell] -> r + evalIL' ListRAMType = start + evalIL' SeqRAMType = start . Seq.fromList + evalIL' IntMapRAMType = start . intMapFromList -start ::(RAM Symbol m, Evaluator r) => m -> r -start = doInstruction 0 + start :: RAM cell m => m -> r + start = doInstruction 0 -class Evaluator r where - doInstruction :: RAM Symbol m => Symbol -> m -> r + doInstruction :: RAM cell m => cell -> m -> r doInstruction ic memory - | ic < 0 = doEnd + | ic < 0 = doEnd ic memory | src < 0 = doInputChar dst ic memory | dst < 0 = doOutputChar src ic memory | otherwise = doInstruction ic' $ store dst diff memory where - src = load memory ic - dst = load memory $ ic + 1 - diff = load memory dst - load memory src :: Symbol + src = genericLoad memory ic + dst = genericLoad memory $ ic + 1 + diff = genericLoad memory dst - genericLoad memory src ic' - | diff <= 0 = (load memory $ ic + 2) :: Symbol + | diff <= 0 = genericLoad memory $ ic + 2 | otherwise = ic + 3 - doEnd :: r - doInputChar :: RAM Symbol m => Symbol -> Symbol -> m -> r - doOutputChar :: RAM Symbol m => Symbol -> Symbol -> m -> r + doEnd :: RAM cell m => cell -> m -> r + doInputChar :: RAM cell m => cell -> cell -> m -> r + doOutputChar :: RAM cell m => cell -> cell -> m -> r ---- -instance Evaluator Interact where - doEnd _ = [] +instance (Default cell , Integral cell) => Evaluator cell Interact where + doEnd _ _ _ = [] doInputChar _ _ _ [] = error "Empty input" - doInputChar address ic memory (value:input) = doInstruction (ic+3) (store address (ord value) memory) input + doInputChar address ic memory (char:input) = doInstruction (ic+3) (storeChar address char memory) input - doOutputChar address ic memory input = chr (load memory address) : doInstruction (ic+3) memory input + doOutputChar address ic memory input = genericChr (genericLoad memory address) : doInstruction (ic+3) memory input ---- -instance WrapperIO m => Evaluator (m ()) where - doEnd = pass +instance (Show cell , Default cell , Integral cell , WrapperIO m) => Evaluator cell (m ()) where + doEnd ic _ = wLogStrLn (show ic) - doInputChar address ic memory = doInputChar' =<< wGetInt where - doInputChar' value = doInstruction (ic+3) $ store address value memory + doInputChar address ic memory = doInputChar' =<< wGetChar where + doInputChar' char = doInstruction (ic+3) $ storeChar address char memory - doOutputChar address ic memory = wPutInt (load memory address :: Symbol) *> doInstruction (ic+3) memory + doOutputChar address ic memory = wPutIntegral (genericLoad memory address) *> doInstruction (ic+3) memory diff --git a/hs/src/HelVM/HelMA/Automata/SubLeq/Lexer.hs b/hs/src/HelVM/HelMA/Automata/SubLeq/Lexer.hs index f10e28f67..ef49bb871 100644 --- a/hs/src/HelVM/HelMA/Automata/SubLeq/Lexer.hs +++ b/hs/src/HelVM/HelMA/Automata/SubLeq/Lexer.hs @@ -23,4 +23,4 @@ instance Show Symbols where show (Symbols symbols) = String.unwords $ show <$> symbols instance Read Symbols where - readsPrec _ source = [( Symbols $ (maybeToList . readMaybe) =<< splitOneOf " \t\n" source, "")] + readsPrec _ source = [( Symbols $ (maybeToList . readMaybe) =<< splitOneOf " \t\n" source , "")] diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Evaluator.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Evaluator.hs index 3c006d395..c38d584e9 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Evaluator.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Evaluator.hs @@ -13,7 +13,6 @@ import HelVM.HelMA.Automata.WhiteSpace.EvaluatorUtil import HelVM.HelMA.Automata.WhiteSpace.Instruction import HelVM.HelMA.Automata.WhiteSpace.Lexer import HelVM.HelMA.Automata.WhiteSpace.Parser -import HelVM.HelMA.Automata.WhiteSpace.StackOfSymbols as Stack import HelVM.HelMA.Automata.WhiteSpace.Token import HelVM.HelMA.Common.API.EvalParams @@ -21,8 +20,8 @@ import HelVM.HelMA.Common.API.TypeOptions import HelVM.HelMA.Common.IO.WrapperIO -import HelVM.HelMA.Common.Memories.RAM as RAM -import HelVM.HelMA.Common.Memories.Stack as Stack +import HelVM.HelMA.Common.Memories.RAMConst as RAM +import HelVM.HelMA.Common.Memories.StackConst as Stack import HelVM.HelMA.Common.OrError @@ -32,51 +31,52 @@ import HelVM.HelMA.Common.Types.TokenType import HelVM.HelMA.Common.Util -import Data.IntMap as IntMap -import Data.Sequence as Seq (fromList) +import Data.Default as Default + +import qualified Data.IntMap as IntMap +import qualified Data.Sequence as Seq flipSimpleEval :: Input -> (TokenType , Source , Bool , StackType , RAMType) -> Output flipSimpleEval = flip simpleEval -simpleEval :: Evaluator r => (TokenType , Source , Bool , StackType , RAMType) -> r +simpleEval :: Evaluator Symbol r => (TokenType , Source , Bool , StackType , RAMType) -> r simpleEval (tokenType , source , asciiLabel , stackType , ramType) = eval tokenType source asciiLabel stackType ramType flipSimpleEvalTL :: Input -> TokenList -> Output flipSimpleEvalTL = flip simpleEvalTL -simpleEvalTL :: Evaluator r => TokenList -> r +simpleEvalTL :: Evaluator Symbol r => TokenList -> r simpleEvalTL tl = evalTL tl False defaultStackType defaultRAMType ----- - -evalParams :: Evaluator r => TokenType -> EvalParams -> r +evalParams :: Evaluator Symbol r => TokenType -> EvalParams -> r evalParams tokenType p = eval tokenType (source p) (asciiLabel p) (stack $ typeOptions p) (ram $ typeOptions p) -eval :: Evaluator r => TokenType -> Source -> Bool -> StackType -> RAMType -> r +eval :: Evaluator Symbol r => TokenType -> Source -> Bool -> StackType -> RAMType -> r eval tokenType source = evalTL $ tokenize tokenType source -evalTL :: Evaluator r => TokenList -> Bool -> StackType -> RAMType -> r +evalTL :: Evaluator Symbol r => TokenList -> Bool -> StackType -> RAMType -> r evalTL tl ascii = evalIL $ parseTL tl ascii -evalIL :: Evaluator r => InstructionList -> StackType -> RAMType -> r -evalIL il s ListRAMType = evalIL' il s ([] :: SymbolList) -evalIL il s SeqRAMType = evalIL' il s (Seq.fromList [] :: Seq Symbol) -evalIL il s IntMapRAMType = evalIL' il s (IntMap.empty :: IntMap Symbol) +evalIL :: Evaluator Symbol r => InstructionList -> StackType -> RAMType -> r +evalIL il s ListRAMType = evalIL' il s [] +evalIL il s SeqRAMType = evalIL' il s Seq.empty +evalIL il s IntMapRAMType = evalIL' il s IntMap.empty + +evalIL' :: Evaluator Symbol r => RAM Symbol m => InstructionList -> StackType -> m -> r +evalIL' il ListStackType = start il [] +evalIL' il SeqStackType = start il Seq.empty -evalIL' :: (RAM Symbol m, Evaluator r) => InstructionList -> StackType -> m -> r -evalIL' il ListStackType = start il ([] :: SymbolList) -evalIL' il SeqStackType = start il (Seq.fromList [] :: Seq Symbol) +class (Default cell , Show cell , Integral cell) => Evaluator cell r where -start :: (Stack Symbol s, RAM Symbol m, Evaluator r) => InstructionList -> s -> m -> r -start il = next (IU il 0 (IS [])) + start :: (Stack cell s , RAM cell m) => InstructionList -> s -> m -> r + start il = next (IU il 0 (IS [])) -class Evaluator r where - next :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r + next :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r next iu@(IU il ic is) = doInstruction (indexOrError ("next"::Text,iu) il ic) (IU il (ic+1) is) ---- - doInstruction :: (Stack Symbol s, RAM Symbol m) => Instruction -> InstructionUnit -> s -> m -> r + doInstruction :: (Stack cell s , RAM cell m) => Instruction -> InstructionUnit -> s -> m -> r -- IO instructions doInstruction OutputChar iu stack h = doOutputChar iu stack h @@ -85,7 +85,7 @@ class Evaluator r where doInstruction InputNum iu stack h = doInputNum iu stack h -- Stack instructions - doInstruction (Liter symbol) iu stack h = next iu (push1 symbol stack) h + doInstruction (Liter symbol) iu stack h = next iu (push1 (fromIntegral symbol) stack) h doInstruction (Copy index) iu stack h = next iu (copy index stack) h doInstruction (Slide index) iu stack h = next iu (slide index stack) h doInstruction Dup iu stack h = next iu (dup stack) h @@ -96,8 +96,8 @@ class Evaluator r where doInstruction (Binary op) iu stack h = next iu (binaryOp op stack) h -- Heap access - doInstruction Store iu stack h = next iu stack' (store (address::Symbol) value h) where (value, address, stack') = pop2 stack - doInstruction Load iu stack h = next iu (push1 (load h (address::Symbol) ::Symbol) stack') h where (address, stack') = pop1 stack + doInstruction Store iu stack h = next iu stack' (store address value h) where (value , address , stack') = pop2 stack + doInstruction Load iu stack h = next iu (push1 (genericLoad h address) stack') h where (address , stack') = pop1 stack -- Control doInstruction (Mark _) iu stack h = next iu stack h @@ -107,73 +107,62 @@ class Evaluator r where doInstruction (Branch t l) (IU il ic is) stack h | doBranchTest t symbol = next (IU il (findAddress il l) is) stack' h | otherwise = next (IU il ic is) stack' h - where (symbol, stack') = pop1 stack + where (symbol , stack') = pop1 stack -- Other doInstruction End iu s m = doEnd iu s m doInstruction i iu _ _ = error $ "Can't do " <> show i <> " " <> show iu - ---- - - emptyInputError :: Instruction -> r - emptyInputError i = error $ "Empty input for instruction " <> show i - -- Special - doEnd :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r + doEnd :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r -- IO instructions - doOutputChar :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r - doInputChar :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r - doOutputNum :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r - doInputNum :: (Stack Symbol s, RAM Symbol m) => InstructionUnit -> s -> m -> r + doOutputChar :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r + doInputChar :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r + doOutputNum :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r + doInputNum :: (Stack cell s , RAM cell m) => InstructionUnit -> s -> m -> r ---- -storeNum :: RAM Symbol m => Symbol -> Input -> m -> m -storeNum address line = store address (readOrError line :: Symbol) +storeNum :: (Read cell , Integral cell , RAM cell m) => cell -> Input -> m -> m +storeNum address = store address . readOrError ---- -instance Evaluator Interact where +emptyInputError :: Instruction -> Output +emptyInputError i = error $ "Empty input for instruction " <> show i + +---- + +instance (Default cell , Read cell , Show cell , Integral cell) => Evaluator cell Interact where doEnd _ _ _ _ = [] - doInputChar _ _ _ [] = emptyInputError InputChar ([]::Input) - doInputChar iu stack h (char:input) = next iu stack' (store (address::Symbol) (toInteger (ord char)) h) input where - (address, stack') = pop1 stack + doInputChar _ _ _ [] = emptyInputError InputChar + doInputChar iu stack h (char:input) = next iu stack' (storeChar address char h) input where + (address , stack') = pop1 stack - doInputNum _ _ _ [] = emptyInputError InputNum ([]::Input) + doInputNum _ _ _ [] = emptyInputError InputNum doInputNum iu stack h input = next iu stack' (storeNum address line h) input' where - (address, stack') = pop1 stack - (line, input') = splitStringByEndLine input + (address , stack') = pop1 stack + (line , input') = splitStringByEndLine input - doOutputChar iu stack h input = chr (fromInteger symbol) : next iu stack' h input where (symbol, stack') = pop1 stack + doOutputChar iu stack h input = genericChr symbol : next iu stack' h input where (symbol , stack') = pop1 stack - doOutputNum iu stack h input = show (symbol :: Symbol) <> next iu stack' h input where (symbol, stack') = pop1 stack + doOutputNum iu stack h input = show symbol <> next iu stack' h input where (symbol , stack') = pop1 stack ---- -instance WrapperIO m => Evaluator (m ()) where - doEnd iu stack _ = wLogStrLn (show stack) *> wLogStrLn (show iu) *> pass - -- fromList [0,0,-1,0,0,0,0,0,0,3]\n" - -- fromList [0,0,-1,0,0,0,0,0,3]\n +instance (Default cell , Read cell , Show cell , Integral cell , WrapperIO m) => Evaluator cell (m ()) where + doEnd iu stack _ = wLogStrLn (show stack) *> wLogStrLn (show iu) doInputChar iu stack h = doInputChar' =<< wGetChar where - doInputChar' char = next iu stack' (store (address::Symbol) (toInteger (ord char)) h) - (address, stack') = pop1 stack + doInputChar' char = next iu stack' (storeChar address char h) + (address , stack') = pop1 stack doInputNum iu stack h = doInputNum' =<< wGetLine where doInputNum' line = next iu stack' (storeNum address line h) - (address, stack') = pop1 stack - - doOutputChar iu stack h = wPutChar (chr (fromInteger symbol)) *> next iu stack' h where (symbol, stack') = pop1 stack - - doOutputNum iu stack h = wPutStr (show (symbol::Symbol)) *> next iu stack' h where (symbol, stack') = pop1 stack - --- doOutputChar iu stack h = wLogStrLn (">" <> show stack) *> wPutChar (chr (fromInteger symbol)) *> wLogStrLn ("<" <> show stack) *> next iu stack' h where (symbol, stack') = pop1 stack - --- doOutputNum iu stack h = wLogStrLn (">" <> show stack) *> wPutStr (show (symbol::Symbol)) *> wLogStrLn ("<" <> show stack) *> next iu stack' h where (symbol, stack') = pop1 stack - + (address , stack') = pop1 stack ---type Evaluated = Text + doOutputChar iu stack h = wPutChar (genericChr symbol) *> next iu stack' h where (symbol , stack') = pop1 stack ---newtype Evaluated s m = Evaluated (InstructionUnit , s , m) \ No newline at end of file + doOutputNum iu stack h = wPutStr (show symbol) *> next iu stack' h where (symbol , stack') = pop1 stack diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/EvaluatorUtil.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/EvaluatorUtil.hs index adbab7465..86a2dfb48 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/EvaluatorUtil.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/EvaluatorUtil.hs @@ -9,14 +9,7 @@ newtype InstructionStack = IS [InstructionAddress] data InstructionUnit = IU InstructionList InstructionCounter InstructionStack deriving (Show) -doBinary :: BinaryOperator -> Symbol -> Symbol -> Symbol -doBinary Add s s' = s' + s -doBinary Sub s s' = s' - s -doBinary Mul s s' = s' * s -doBinary Div s s' = s' `div` s -doBinary Mod s s' = s' `mod` s - -doBranchTest :: BranchTest -> Symbol -> Bool +doBranchTest :: Integral s => BranchTest -> s -> Bool doBranchTest EZ s = s == 0 doBranchTest Neg s = s < 0 diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Instruction.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Instruction.hs index bd7ff9bcc..d6803926d 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Instruction.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Instruction.hs @@ -2,17 +2,18 @@ module HelVM.HelMA.Automata.WhiteSpace.Instruction where import HelVM.HelMA.Automata.WhiteSpace.OperandParsers -import HelVM.HelMA.Common.Memories.Stack +import HelVM.HelMA.Common.BinaryOperator +import HelVM.HelMA.Common.Memories.StackConst data Instruction = - Liter Symbol + Liter Integer | Copy Index | Slide Index | Dup | Swap | Discard | Binary BinaryOperator - | Store + | Store --Save | Load --Restore | Mark Label | Call Label @@ -24,15 +25,12 @@ data Instruction = | InputChar | InputNum | End - deriving (Eq, Show, Read) + deriving (Eq , Show , Read) type InstructionList = [Instruction] -data BinaryOperator = Add | Sub | Mul | Div | Mod - deriving (Eq, Show, Read) - data BranchTest = EZ | Neg - deriving (Eq, Show, Read) + deriving (Eq , Show , Read) ---- diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/OperandParsers.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/OperandParsers.hs index 21beb20d8..45d39f629 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/OperandParsers.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/OperandParsers.hs @@ -4,10 +4,10 @@ import HelVM.HelMA.Automata.WhiteSpace.Token import HelVM.HelMA.Common.Util -type OperandParser a = TokenList -> (a, TokenList) +type OperandParser a = TokenList -> (a , TokenList) parseInt :: OperandParser Int -parseInt tokens = (fromIntegral integer, tokens') where (integer, tokens') = parseInteger tokens +parseInt tokens = (fromIntegral integer , tokens') where (integer , tokens') = parseInteger tokens parseInteger :: OperandParser Integer parseInteger [] = error "EOL" @@ -15,8 +15,8 @@ parseInteger (S:tokens) = parseUtil makeIntegral tokens parseInteger (T:tokens) = negationIntegral $ parseUtil makeIntegral tokens parseInteger (N:tokens) = (0,tokens) -negationIntegral :: (Integer, TokenList) -> (Integer, TokenList) -negationIntegral (i,l) = (-i,l) +negationIntegral :: (Integer , TokenList) -> (Integer , TokenList) +negationIntegral (i , l) = (-i , l) parseNatural :: OperandParser Natural parseNatural = parseUtil makeIntegral @@ -24,7 +24,7 @@ parseNatural = parseUtil makeIntegral parseUtil :: (TokenList -> a) -> OperandParser a parseUtil maker = parseUtil' ([]::TokenList) where parseUtil' acc [] = error $ show acc - parseUtil' acc (N:tokens) = (maker acc, tokens) + parseUtil' acc (N:tokens) = (maker acc , tokens) parseUtil' acc (t:tokens) = parseUtil' (t:acc) tokens parseBitString :: OperandParser String @@ -34,12 +34,12 @@ parseAsciiString :: OperandParser String parseAsciiString = parseString' makeAsciiString parseString' :: (TokenList -> a) -> OperandParser a -parseString' maker tokens = (maker acc, tokens') where (acc, tokens') = splitByN tokens +parseString' maker tokens = (maker acc , tokens') where (acc , tokens') = splitByN tokens splitByN :: OperandParser TokenList splitByN [] = error "Empty list" -splitByN (N:tokens) = ([], tokens) -splitByN (t:tokens) = (t:acc, tokens') where (acc, tokens') = splitByN tokens +splitByN (N:tokens) = ([] , tokens) +splitByN (t:tokens) = (t:acc , tokens') where (acc , tokens') = splitByN tokens ---- diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Parser.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Parser.hs index 2ffc0a2c0..4371ad29e 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Parser.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Parser.hs @@ -10,8 +10,8 @@ import HelVM.HelMA.Automata.WhiteSpace.Token import HelVM.HelMA.Automata.WhiteSpace.Lexer import HelVM.HelMA.Automata.WhiteSpace.Instruction +import HelVM.HelMA.Common.BinaryOperator import HelVM.HelMA.Common.Types.TokenType - import HelVM.HelMA.Common.Util flipParseVisible :: Bool -> Source -> InstructionList @@ -31,10 +31,10 @@ parseTL tl ascii = parseTL' tl where parseTL' :: TokenList -> InstructionList parseTL' [] = [] -- Stack instructions - parseTL' (S:S:tokens) = Liter symbol : parseTL' tokens' where (symbol, tokens') = parseSymbol tokens - parseTL' (S:T:S:tokens) = Copy index : parseTL' tokens' where (index, tokens') = parseIndex tokens + parseTL' (S:S:tokens) = Liter symbol : parseTL' tokens' where (symbol , tokens') = parseSymbol tokens + parseTL' (S:T:S:tokens) = Copy index : parseTL' tokens' where (index , tokens') = parseIndex tokens parseTL' (S:T:T:_) = panic "STT" - parseTL' (S:T:N:tokens) = Slide index : parseTL' tokens' where (index, tokens') = parseIndex tokens + parseTL' (S:T:N:tokens) = Slide index : parseTL' tokens' where (index , tokens') = parseIndex tokens parseTL' (S:N:S:tokens) = Dup : parseTL' tokens parseTL' (S:N:T:tokens) = Swap : parseTL' tokens parseTL' (S:N:N:tokens) = Discard : parseTL' tokens @@ -53,11 +53,11 @@ parseTL tl ascii = parseTL' tl where parseTL' (T:T:T:tokens) = Load : parseTL' tokens parseTL' (T:T:N:_) = panic "TTN" -- Control - parseTL' (N:S:S:tokens) = Mark label : parseTL' tokens' where (label, tokens') = parseLabel ascii tokens - parseTL' (N:S:T:tokens) = Call label : parseTL' tokens' where (label, tokens') = parseLabel ascii tokens - parseTL' (N:S:N:tokens) = Jump label : parseTL' tokens' where (label, tokens') = parseLabel ascii tokens - parseTL' (N:T:S:tokens) = Branch EZ label : parseTL' tokens' where (label, tokens') = parseLabel ascii tokens - parseTL' (N:T:T:tokens) = Branch Neg label : parseTL' tokens' where (label, tokens') = parseLabel ascii tokens + parseTL' (N:S:S:tokens) = Mark label : parseTL' tokens' where (label , tokens') = parseLabel ascii tokens + parseTL' (N:S:T:tokens) = Call label : parseTL' tokens' where (label , tokens') = parseLabel ascii tokens + parseTL' (N:S:N:tokens) = Jump label : parseTL' tokens' where (label , tokens') = parseLabel ascii tokens + parseTL' (N:T:S:tokens) = Branch EZ label : parseTL' tokens' where (label , tokens') = parseLabel ascii tokens + parseTL' (N:T:T:tokens) = Branch Neg label : parseTL' tokens' where (label , tokens') = parseLabel ascii tokens parseTL' (N:T:N:tokens) = Return : parseTL' tokens parseTL' (N:N:S:_) = panic "NNS" parseTL' (N:N:T:_) = panic "NNT" diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/StackOfSymbols.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/StackOfSymbols.hs deleted file mode 100644 index 3bb1114d2..000000000 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/StackOfSymbols.hs +++ /dev/null @@ -1,28 +0,0 @@ -module HelVM.HelMA.Automata.WhiteSpace.StackOfSymbols where - -import HelVM.HelMA.Automata.WhiteSpace.EvaluatorUtil -import HelVM.HelMA.Automata.WhiteSpace.Instruction - -import HelVM.HelMA.Common.Memories.Stack - --- Arithmetic - -binaryOp :: Stack Symbol m => BinaryOperator -> m -> m -binaryOp op stack = push1 (doBinary op symbol symbol' ::Symbol) stack' where (symbol, symbol', stack') = pop2 stack - --- Stack instructions - -swap :: Stack Symbol m => m -> m -swap stack = push2 (symbol'::Symbol) symbol stack' where (symbol, symbol', stack') = pop2 stack - -discard :: Stack Symbol m => m -> m -discard = drop' (0::Symbol) 1 - -slide :: Stack Symbol m => Index -> m -> m -slide i stack = push1 (symbol::Symbol) (drop' (0::Symbol) i stack') where (symbol, stack') = pop1 stack - -dup :: Stack Symbol m => m -> m -dup = copy 0 - -copy :: Stack Symbol m => Index -> m -> m -copy i stack = push1 (select i stack ::Symbol) stack diff --git a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Token.hs b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Token.hs index 291ee6d2a..51561b3dd 100644 --- a/hs/src/HelVM/HelMA/Automata/WhiteSpace/Token.hs +++ b/hs/src/HelVM/HelMA/Automata/WhiteSpace/Token.hs @@ -6,7 +6,7 @@ import Text.Read import qualified Text.Show data Token = S | T | N - deriving (Eq, Ord, Enum, Show, Read) + deriving (Eq , Ord , Enum , Show , Read) type TokenList = [Token] diff --git a/hs/src/HelVM/HelMA/Common/API/TypeOptions.hs b/hs/src/HelVM/HelMA/Common/API/TypeOptions.hs index ea4e21bca..522c552b8 100644 --- a/hs/src/HelVM/HelMA/Common/API/TypeOptions.hs +++ b/hs/src/HelVM/HelMA/Common/API/TypeOptions.hs @@ -1,10 +1,12 @@ module HelVM.HelMA.Common.API.TypeOptions where import HelVM.HelMA.Common.Types.CellType +import HelVM.HelMA.Common.Types.IntCellType import HelVM.HelMA.Common.Types.StackType import HelVM.HelMA.Common.Types.RAMType -data TypeOptions = TypeOptions { ram :: RAMType - , stack :: StackType - , cell :: CellType +data TypeOptions = TypeOptions { ram :: RAMType + , stack :: StackType + , cell :: CellType + , intCell :: IntCellType } diff --git a/hs/src/HelVM/HelMA/Common/BinaryOperator.hs b/hs/src/HelVM/HelMA/Common/BinaryOperator.hs new file mode 100644 index 000000000..11a9a66aa --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/BinaryOperator.hs @@ -0,0 +1,17 @@ +module HelVM.HelMA.Common.BinaryOperator where + +calculateOps :: Integral a => a -> a -> [BinaryOperator] -> [a] +calculateOps operand operand' = map (calculateOp operand operand') + +calculateOp :: Integral a => a -> a -> BinaryOperator -> a +calculateOp operand operand' operation = doBinary operation operand' operand + +doBinary :: Integral a => BinaryOperator -> a -> a -> a +doBinary Add = (+) +doBinary Sub = (-) +doBinary Mul = (*) +doBinary Div = div +doBinary Mod = mod + +data BinaryOperator = Add | Sub | Mul | Div | Mod + deriving (Eq , Show , Read) diff --git a/hs/src/HelVM/HelMA/Common/Collections.hs b/hs/src/HelVM/HelMA/Common/Collections.hs new file mode 100644 index 000000000..9aaff240f --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections.hs @@ -0,0 +1 @@ +module HelVM.HelMA.Common.Collections where diff --git a/hs/src/HelVM/HelMA/Common/Collections/Drop.hs b/hs/src/HelVM/HelMA/Common/Collections/Drop.hs new file mode 100644 index 000000000..ed8d0531f --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/Drop.hs @@ -0,0 +1,15 @@ +module HelVM.HelMA.Common.Collections.Drop where + +import Prelude hiding (drop) + +import qualified Data.Sequence as Seq +import qualified Prelude as List (drop) + +class Drop e c | c -> e where + drop :: Int -> c -> c + +instance Drop e [e] where + drop i c = List.drop i c + +instance Drop e (Seq e) where + drop i c = Seq.drop i c diff --git a/hs/src/HelVM/HelMA/Common/Collections/FromList.hs b/hs/src/HelVM/HelMA/Common/Collections/FromList.hs new file mode 100644 index 000000000..698b202fe --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/FromList.hs @@ -0,0 +1,27 @@ +module HelVM.HelMA.Common.Collections.FromList where + +import Prelude hiding (fromList) + +import qualified Data.List.Index as List +import qualified Data.IntMap as IntMap +import qualified Data.Sequence as Seq + +intMapFromList :: [e] -> IntMap e +intMapFromList = IntMap.fromList . List.indexed + +class FromList e c | c -> e where + fromList :: [e] -> c + empty :: c + empty = fromList [] + +instance FromList e [e] where + fromList = id + empty = [] + +instance FromList e (Seq e) where + fromList = Seq.fromList + empty = Seq.empty + +instance FromList e (IntMap e) where + fromList = intMapFromList + empty = IntMap.empty diff --git a/hs/src/HelVM/HelMA/Common/Collections/Insert.hs b/hs/src/HelVM/HelMA/Common/Collections/Insert.hs new file mode 100644 index 000000000..927f029dc --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/Insert.hs @@ -0,0 +1,25 @@ +module HelVM.HelMA.Common.Collections.Insert where + +import Data.Default +import Data.Sequence ((|>)) + +import qualified Data.IntMap as IntMap +import qualified Data.Sequence as Seq + +class Insert e c | c -> e where + insert :: Int -> e -> c -> c + +instance Default e => Insert e [e] where + insert 0 e [] = [e] + insert 0 e (_:xs) = e : xs + insert i e [] = def : insert (i-1) e [] + insert i e (x:xs) = x : insert (i-1) e xs + +instance Default e => Insert e (Seq e) where + insert i e c = insert' $ Seq.length c where + insert' l + | i < l = Seq.update i e c + | otherwise = c <> Seq.replicate (i - l) def |> e + +instance Insert e (IntMap e) where + insert = IntMap.insert diff --git a/hs/src/HelVM/HelMA/Common/Collections/Lookup.hs b/hs/src/HelVM/HelMA/Common/Collections/Lookup.hs new file mode 100644 index 000000000..7de017c41 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/Lookup.hs @@ -0,0 +1,24 @@ +module HelVM.HelMA.Common.Collections.Lookup where + +import qualified Data.IntMap as IntMap +import qualified Data.Sequence as Seq + +index :: (Show c , Lookup e c) => c -> Int -> e +index c i = check (c `indexMaybe` i) where + check (Just e) = e + check Nothing = error $ "Empty stack " <> show c <> " index " <> show i + +indexMaybe :: Lookup e c => c -> Int -> Maybe e +indexMaybe = flip lookup + +class Lookup e c | c -> e where + lookup:: Int -> c -> Maybe e + +instance Lookup e [e] where + lookup = flip (!!?) + +instance Lookup e (Seq e) where + lookup = Seq.lookup + +instance Lookup e (IntMap e) where + lookup = IntMap.lookup diff --git a/hs/src/HelVM/HelMA/Common/Collections/Pop.hs b/hs/src/HelVM/HelMA/Common/Collections/Pop.hs new file mode 100644 index 000000000..b983ec881 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/Pop.hs @@ -0,0 +1,26 @@ +module HelVM.HelMA.Common.Collections.Pop where + +import Data.Sequence (Seq(..)) + +class Pop1 e c | c -> e where + pop1 :: c -> (e , c) + +instance Show e => Pop1 e [e] where + pop1 (e : c) = (e , c) + pop1 c = error $ "Empty " <> show c + +instance Show e => Pop1 e (Seq e) where + pop1 (e :<| c) = (e , c) + pop1 c = error $ "Empty " <> show c + +class Pop2 e c | c -> e where + pop2 :: c -> (e , e , c) + +instance Show e => Pop2 e [e] where + pop2 (e : e' : c) = (e , e', c) + pop2 c = error $ "Empty " <> show c + +instance Show e => Pop2 e (Seq e) where + pop2 (e :<| e' :<| c) = (e , e', c) + pop2 c = error $ "Empty " <> show c + diff --git a/hs/src/HelVM/HelMA/Common/Collections/SplitAt.hs b/hs/src/HelVM/HelMA/Common/Collections/SplitAt.hs new file mode 100644 index 000000000..5be39fe0f --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Collections/SplitAt.hs @@ -0,0 +1,15 @@ +module HelVM.HelMA.Common.Collections.SplitAt where + +import Prelude hiding (splitAt) + +import qualified Data.Sequence as Seq +import qualified Prelude as List (splitAt) + +class SplitAt e c | c -> e where + splitAt :: Int -> c -> (c , c) + +instance SplitAt e [e] where + splitAt i c = List.splitAt i c + +instance SplitAt e (Seq e) where + splitAt i c = Seq.splitAt i c diff --git a/hs/src/HelVM/HelMA/Common/IO/MockIO.hs b/hs/src/HelVM/HelMA/Common/IO/MockIO.hs index 2823b2561..fae989db3 100644 --- a/hs/src/HelVM/HelMA/Common/IO/MockIO.hs +++ b/hs/src/HelVM/HelMA/Common/IO/MockIO.hs @@ -36,7 +36,6 @@ evalMockIO mockIO = getLogged . execState mockIO . createMockIO instance WrapperIO MockIO where wGetChar = mockGetChar - wGetInt = mockGetInt wGetLine = mockGetLine wPutChar = mockPutChar wPutInt = mockPutInt @@ -47,9 +46,6 @@ mockGetChar :: MockIO Char mockGetChar = mockGetChar' =<< get where mockGetChar' mockIO = headOrError mockIO (input mockIO) <$ put mockIO { input = Unsafe.tail $ input mockIO } -mockGetInt :: MockIO Int -mockGetInt = ord <$> mockGetChar - mockGetLine :: MockIO String mockGetLine = mockGetLine' =<< get where mockGetLine' mockIO = line <$ put mockIO { input = input' } where (line , input') = splitStringByEndLine $ input mockIO @@ -90,7 +86,7 @@ data MockIOData = MockIOData , output :: String , logged :: String } - deriving (Eq, Show, Read) + deriving (Eq , Show , Read) ---- diff --git a/hs/src/HelVM/HelMA/Common/IO/WrapperIO.hs b/hs/src/HelVM/HelMA/Common/IO/WrapperIO.hs index 2179bf630..088ab3d15 100644 --- a/hs/src/HelVM/HelMA/Common/IO/WrapperIO.hs +++ b/hs/src/HelVM/HelMA/Common/IO/WrapperIO.hs @@ -6,8 +6,8 @@ module HelVM.HelMA.Common.IO.WrapperIO ( wPutStr, wPutStrLn, wFlush, - wGetInt, wPutInt, + wPutIntegral, wLogStr, wLogStrLn, wLogShow, @@ -16,23 +16,23 @@ module HelVM.HelMA.Common.IO.WrapperIO ( import qualified System.IO as IO class Monad m => WrapperIO m where - wGetChar :: m Char - wPutChar :: Char -> m () - wGetLine :: m String - wPutStr :: String -> m () - wPutStrLn :: String -> m () - wFlush :: m () - wGetInt :: m Int - wPutInt :: Int -> m () - wLogStr :: String -> m () - wLogStrLn :: String -> m () - wLogShow :: Show s => s -> m () - wPutStrLn s = wPutStr $ s <> "\n" - wFlush = pass - wPutInt = wPutChar . chr - wGetInt = ord <$> wGetChar - wLogStrLn s = wLogStr $ s <> "\n" - wLogShow s = wLogStrLn $ show s + wGetChar :: m Char + wPutChar :: Char -> m () + wGetLine :: m String + wPutStr :: String -> m () + wPutStrLn :: String -> m () + wFlush :: m () + wPutInt :: Int -> m () + wPutIntegral :: Integral v => v -> m () + wLogStr :: String -> m () + wLogStrLn :: String -> m () + wLogShow :: Show s => s -> m () + wPutStrLn s = wPutStr $ s <> "\n" + wFlush = pass + wPutInt = wPutChar . chr + wPutIntegral = wPutInt . fromIntegral + wLogStrLn s = wLogStr $ s <> "\n" + wLogShow = wLogStrLn . show instance WrapperIO IO where wGetChar = IO.getChar diff --git a/hs/src/HelVM/HelMA/Common/Memories/RAM.hs b/hs/src/HelVM/HelMA/Common/Memories/RAM.hs index ed8d5172b..3971d6bee 100644 --- a/hs/src/HelVM/HelMA/Common/Memories/RAM.hs +++ b/hs/src/HelVM/HelMA/Common/Memories/RAM.hs @@ -1,50 +1,69 @@ -{-# Language AllowAmbiguousTypes #-}--FIXME module HelVM.HelMA.Common.Memories.RAM ( - RAM, - HelVM.HelMA.Common.Memories.RAM.empty, - HelVM.HelMA.Common.Memories.RAM.fromList, + genericLoad, load, - store + storeChar, + genericStore, + store, + fromList, + empty, + RAM, + intMapFromList ) where import Data.Default -import Data.IntMap as IntMap -import Data.Sequence as Seq +import Data.List.Index +import Data.Sequence ((|>)) +import Prelude hiding (empty , fromList , splitAt) + +import qualified Data.IntMap as IntMap +import qualified Data.Sequence as Seq type Address = Int -load :: (Integral a, RAM s m) => m -> a -> s -load memory address = index' memory (fromIntegral address) ?: def - -store :: (Integral a, RAM s m) => a -> s -> m -> m -store address = insert' (fromIntegral address) - -class Default s => RAM s m where - fromList :: [s] -> m - empty :: m - index' :: m -> Address -> Maybe s - insert' :: Address -> s -> m -> m - -instance Default s => RAM s [s] where - fromList = id - empty = [] - index' = (!!?) - insert' 0 symbol [] = [symbol] - insert' 0 symbol (_:xs) = symbol : xs - insert' address symbol [] = def : insert' (address-1) symbol [] - insert' address symbol (x:xs) = x : insert' (address-1) symbol xs - -instance Default s => RAM s (Seq s) where - fromList = Seq.fromList - empty = Seq.fromList [] - index' = (Seq.!?) - insert' address symbol memory = insert'' (Seq.length memory) where - insert'' l - | address < l = Seq.update address symbol memory - | otherwise = memory <> Seq.replicate (address - l) def |> symbol - -instance Default s => RAM s (IntMap s) where - fromList list = IntMap.fromList $ Prelude.zip [0..] list - empty = IntMap.empty - index' = (IntMap.!?) - insert' = IntMap.insert +genericLoad :: (Integral i , RAM e c) => c -> i -> e +genericLoad c i = load c $ fromIntegral i + +load :: (RAM e c) => c -> Address -> e +load c i = indexMaybe c i ?: def + +storeChar :: (Num e , Integral a , RAM e c) => a -> Char -> c -> c +storeChar a char = genericStore a $ ord char + +genericStore :: (Integral v , Num e , Integral a , RAM e c) => a -> v -> c -> c +genericStore a value = store a $ fromIntegral value + +store :: (Integral a , RAM e c) => a -> e -> c -> c +store = insert . fromIntegral + +class Default e => RAM e c | c -> e where + fromList :: [e] -> c + empty :: c + indexMaybe :: c -> Address -> Maybe e + insert :: Address -> e -> c -> c + +instance Default e => RAM e [e] where + fromList = id + empty = [] + indexMaybe = (!!?) + insert 0 e [] = [e] + insert 0 e (_:xs) = e : xs + insert a e [] = def : insert (a-1) e [] + insert a e (x:xs) = x : insert (a-1) e xs + +instance Default e => RAM e (Seq e) where + fromList = Seq.fromList + empty = Seq.empty + indexMaybe = (Seq.!?) + insert a e c = insert' $ Seq.length c where + insert' l + | a < l = Seq.update a e c + | otherwise = c <> Seq.replicate (a - l) def |> e + +instance Default e => RAM e (IntMap e) where + fromList = intMapFromList + empty = IntMap.empty + indexMaybe = (IntMap.!?) + insert = IntMap.insert + +intMapFromList :: [e] -> IntMap e +intMapFromList = IntMap.fromList . indexed diff --git a/hs/src/HelVM/HelMA/Common/Memories/RAMConst.hs b/hs/src/HelVM/HelMA/Common/Memories/RAMConst.hs new file mode 100644 index 000000000..f2e1e5130 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/RAMConst.hs @@ -0,0 +1,38 @@ +{-#LANGUAGE ConstraintKinds#-} +module HelVM.HelMA.Common.Memories.RAMConst ( + genericLoad, + load, + storeChar, + genericStore, + store, + fromList, + empty, + RAM, + intMapFromList +) where + +import Data.Default +import Prelude hiding (empty , fromList , splitAt) + +import HelVM.HelMA.Common.Collections.FromList +import HelVM.HelMA.Common.Collections.Insert +import HelVM.HelMA.Common.Collections.Lookup + +type Address = Int + +genericLoad :: (Integral i , RAM e c) => c -> i -> e +genericLoad c i = load c $ fromIntegral i + +load :: (RAM e c) => c -> Address -> e +load c i = indexMaybe c i ?: def + +storeChar :: (Num e , Integral a , RAM e c) => a -> Char -> c -> c +storeChar a char = genericStore a $ ord char + +genericStore :: (Integral v , Num e , Integral a , RAM e c) => a -> v -> c -> c +genericStore a value = store a $ fromIntegral value + +store :: (Integral a , RAM e c) => a -> e -> c -> c +store = insert . fromIntegral + +type RAM e c = (Default e , FromList e c , Insert e c , Lookup e c) diff --git a/hs/src/HelVM/HelMA/Common/Memories/RAMImpl.hs b/hs/src/HelVM/HelMA/Common/Memories/RAMImpl.hs new file mode 100644 index 000000000..833cad948 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/RAMImpl.hs @@ -0,0 +1,47 @@ +{-#LANGUAGE UndecidableInstances#-} +module HelVM.HelMA.Common.Memories.RAMImpl ( + genericLoad, + load, + storeChar, + genericStore, + store, + fromList, + empty, + RAM +) where + +import Data.Default +import Prelude hiding (empty , fromList , splitAt) + +import qualified HelVM.HelMA.Common.Collections.FromList as I +import qualified HelVM.HelMA.Common.Collections.Insert as I +import qualified HelVM.HelMA.Common.Collections.Lookup as I + +type Address = Int + +genericLoad :: (Integral i , RAM e c) => c -> i -> e +genericLoad c i = load c $ fromIntegral i + +load :: (RAM e c) => c -> Address -> e +load c i = indexMaybe c i ?: def + +storeChar :: (Num e , Integral a , RAM e c) => a -> Char -> c -> c +storeChar a char = genericStore a $ ord char + +genericStore :: (Integral v , Num e , Integral a , RAM e c) => a -> v -> c -> c +genericStore a value = store a $ fromIntegral value + +store :: (Integral a , RAM e c) => a -> e -> c -> c +store = insert . fromIntegral + +class Default e => RAM e c | c -> e where + fromList :: [e] -> c + empty :: c + indexMaybe :: c -> Address -> Maybe e + insert :: Address -> e -> c -> c + +instance (Default e , I.FromList e c , I.Insert e c , I.Lookup e c) => RAM e c where + fromList = I.fromList + empty = I.empty + indexMaybe = I.indexMaybe + insert = I.insert diff --git a/hs/src/HelVM/HelMA/Common/Memories/RAMUtil.hs b/hs/src/HelVM/HelMA/Common/Memories/RAMUtil.hs new file mode 100644 index 000000000..e5a2a694e --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/RAMUtil.hs @@ -0,0 +1,28 @@ +module HelVM.HelMA.Common.Memories.RAMUtil ( + genericLoad, + load, + storeChar, + genericStore, + store +) where + +import HelVM.HelMA.Common.Collections.Insert +import HelVM.HelMA.Common.Collections.Lookup + +import Data.Default +import Prelude hiding (empty , fromList , splitAt) + +genericLoad :: (Integral i , Default e , Lookup e c) => c -> i -> e +genericLoad c i = load c $ fromIntegral i + +load :: (Default e , Lookup e c) => c -> Int -> e +load c i = indexMaybe c i ?: def + +storeChar :: (Num e , Integral a , Insert e c) => a -> Char -> c -> c +storeChar a v = genericStore a $ ord v + +genericStore :: (Integral v , Num e , Integral a , Insert e c) => a -> v -> c -> c +genericStore a v = store a $ fromIntegral v + +store :: (Integral a , Insert e c) => a -> e -> c -> c +store = insert . fromIntegral diff --git a/hs/src/HelVM/HelMA/Common/Memories/Stack.hs b/hs/src/HelVM/HelMA/Common/Memories/Stack.hs index 9495375dc..ecf492a36 100644 --- a/hs/src/HelVM/HelMA/Common/Memories/Stack.hs +++ b/hs/src/HelVM/HelMA/Common/Memories/Stack.hs @@ -1,57 +1,138 @@ -{-# Language AllowAmbiguousTypes #-}--FIXME module HelVM.HelMA.Common.Memories.Stack ( Index, Stack, - select, - HelVM.HelMA.Common.Memories.Stack.empty, - HelVM.HelMA.Common.Memories.Stack.lookup, - HelVM.HelMA.Common.Memories.Stack.splitAt', - HelVM.HelMA.Common.Memories.Stack.drop', + divMod, + sub, + binaryOp, + binaryOps, + pushChar1, + genericPush1, + halibut, + move, + swap, + discard, + slide, + dup, + copy, + empty, + lookup, + splitAt, + drop, push1, - pop1, push2, + pop1, pop2 ) where -import Data.Sequence as Seq +import HelVM.HelMA.Common.BinaryOperator + +import Data.Sequence (Seq(..)) +import Prelude hiding (divMod , drop , empty , fromList , splitAt , swap) + +import qualified Data.Sequence as Seq +import qualified Prelude as List (drop , splitAt) type Index = Int -select :: Stack s m => Index -> m -> s -select i stack = check $ HelVM.HelMA.Common.Memories.Stack.lookup i stack where - check (Just symbol) = symbol - check Nothing = error $ "Empty stack " <> show stack <> " index " <> show i - -class (Semigroup m, Show m) => Stack s m where - empty :: m - lookup :: Index -> m -> Maybe s - splitAt' :: s -> Index -> m -> (m, m) - drop' :: s -> Index -> m -> m - push1 :: s -> m -> m - pop1 :: m -> (s, m) - push2 :: s -> s -> m -> m - pop2 :: m -> (s, s, m) - -instance Show s => Stack s [s] where - empty = [] - lookup i stack = stack !!? i - splitAt' _ i stack = Prelude.splitAt i stack - drop' _ i stack = Prelude.drop i stack - push1 symbol stack = symbol: stack - pop1 (symbol : stack) = (symbol, stack) - pop1 stack = error $ "Empty stack " <> show stack - push2 symbol symbol' stack = symbol: symbol': stack - pop2 (symbol : symbol' : stack) = (symbol, symbol', stack) - pop2 stack = error $ "Empty stack " <> show stack - -instance Show s => Stack s (Seq s) where - empty = Seq.fromList [] - lookup i stack = Seq.lookup i stack - splitAt' _ i stack = Seq.splitAt i stack - drop' _ i stack = Seq.drop i stack --TODO czy to kur_a dziaΕ‚a? - push1 symbol stack = symbol <| stack - pop1 (symbol :<| stack) = (symbol, stack) - pop1 stack = error $ "Empty stack " <> show stack - push2 symbol symbol' stack = symbol <| symbol' <| stack - pop2 (symbol :<| symbol' :<| stack) = (symbol, symbol', stack) - pop2 stack = error $ "Empty stack " <> show stack +-- Arithmetic + +divMod :: (Integral e , Stack e c) => c -> c +divMod = binaryOps [Mod , Div] + +sub :: (Integral e , Stack e c) => c -> c +sub = binaryOp Sub + +binaryOp :: (Integral e , Stack e c) => BinaryOperator -> c -> c +binaryOp op = binaryOps [op] + +binaryOps :: (Integral e , Stack e c) => [BinaryOperator] -> c -> c +binaryOps ops c = pushList (calculateOps e e' ops) c' where (e , e', c') = pop2 c + +-- Stack instructions + +halibut :: (Integral e , Stack e c) => c -> c +halibut c + | i <= 0 = copy (negate i) c' + | otherwise = move i c' + where + i = fromIntegral e + (e , c') = pop1 c + +move :: Stack e c => Index -> c -> c +move i c = c1 <> c2 <> c3 where + (c1 , c3) = splitAt 1 c' + (c2 , c') = splitAt i c + +swap :: Stack e c => c -> c +swap c = push2 e' e c' where (e , e', c') = pop2 c + +discard :: Stack e c => c -> c +discard = drop 1 + +slide :: Stack e c => Index -> c -> c +slide i c = push1 e (drop i c') where (e , c') = pop1 c + +dup :: Stack e c => c -> c +dup = copy 0 + +copy :: Stack e c => Index -> c -> c +copy i c = push1 (c `index` i) c + +-- Push instructions + +pushChar1 :: (Num e , Stack e c) => Char -> c -> c +pushChar1 = genericPush1 . ord + +genericPush1 :: (Integral v , Num e , Stack e c) => v -> c -> c +genericPush1 = push1 . fromIntegral + +push1 :: Stack e c => e -> c -> c +push1 e = pushList [e] + +push2 :: Stack e c => e -> e -> c -> c +push2 e e' = pushList [e , e'] + +pushList :: Stack e c => [e] -> c -> c +pushList es c = fromList es <> c + +---- + +index :: (Stack e c) => c -> Int -> e +index c i = check (c `indexMaybe` i) where + check (Just e) = e + check Nothing = error $ "Empty stack " <> show c <> " index " <> show i + +class (Semigroup c , Show c) => Stack e c | c -> e where + fromList :: [e] -> c + empty :: c + indexMaybe :: c -> Index -> Maybe e + lookup :: Index -> c -> Maybe e + splitAt :: Index -> c -> (c , c) + drop :: Index -> c -> c + pop1 :: c -> (e , c) + pop2 :: c -> (e , e , c) + empty = fromList [] + indexMaybe = flip lookup + lookup = flip indexMaybe + +instance Show e => Stack e [e] where + fromList = id + empty = [] + lookup i c = c !!? i + splitAt i c = List.splitAt i c + drop i c = List.drop i c + pop1 (e : c) = (e , c) + pop1 c = error $ "Empty c " <> show c + pop2 (e : e' : c) = (e , e', c) + pop2 c = error $ "Empty c " <> show c + +instance Show e => Stack e (Seq e) where + fromList = Seq.fromList + empty = Seq.empty + lookup i c = Seq.lookup i c + splitAt i c = Seq.splitAt i c + drop i c = Seq.drop i c + pop1 (e :<| c) = (e , c) + pop1 c = error $ "Empty c " <> show c + pop2 (e :<| e' :<| c) = (e , e', c) + pop2 c = error $ "Empty c " <> show c diff --git a/hs/src/HelVM/HelMA/Common/Memories/StackConst.hs b/hs/src/HelVM/HelMA/Common/Memories/StackConst.hs new file mode 100644 index 000000000..f70fe6616 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/StackConst.hs @@ -0,0 +1,103 @@ +{-#LANGUAGE ConstraintKinds#-} +module HelVM.HelMA.Common.Memories.StackConst ( + Index, + Stack, + divMod, + sub, + binaryOp, + binaryOps, + halibut, + move, + swap, + discard, + slide, + dup, + copy, + pushChar1, + genericPush1, + push1, + push2, + empty, + lookup, + splitAt, + drop, + pop1, + pop2 +) where + +import HelVM.HelMA.Common.BinaryOperator + +import Prelude hiding (divMod , drop , empty , fromList , splitAt , swap) + +import HelVM.HelMA.Common.Collections.Drop +import HelVM.HelMA.Common.Collections.FromList +import HelVM.HelMA.Common.Collections.Lookup +import HelVM.HelMA.Common.Collections.Pop +import HelVM.HelMA.Common.Collections.SplitAt + +type Index = Int + +-- Arithmetic + +divMod :: (Integral e , Stack e c) => c -> c +divMod = binaryOps [Mod , Div] + +sub :: (Integral e , Stack e c) => c -> c +sub = binaryOp Sub + +binaryOp :: (Integral e , Stack e c) => BinaryOperator -> c -> c +binaryOp op = binaryOps [op] + +binaryOps :: (Integral e , Stack e c) => [BinaryOperator] -> c -> c +binaryOps ops c = pushList (calculateOps e e' ops) c' where (e , e', c') = pop2 c + +-- Stack instructions + +halibut :: (Integral e , Stack e c) => c -> c +halibut c + | i <= 0 = copy (negate i) c' + | otherwise = move i c' + where + i = fromIntegral e + (e , c') = pop1 c + +move :: Stack e c => Index -> c -> c +move i c = c1 <> c2 <> c3 where + (c1 , c3) = splitAt 1 c' + (c2 , c') = splitAt i c + +swap :: Stack e c => c -> c +swap c = push2 e' e c' where (e , e', c') = pop2 c + +discard :: Stack e c => c -> c +discard = drop 1 + +slide :: Stack e c => Index -> c -> c +slide i c = push1 e (drop i c') where (e , c') = pop1 c + +dup :: Stack e c => c -> c +dup = copy 0 + +copy :: Stack e c => Index -> c -> c +copy i c = push1 (c `index` i) c + +-- Push instructions + +pushChar1 :: (Num e , Stack e c) => Char -> c -> c +pushChar1 = genericPush1 . ord + +genericPush1 :: (Integral v , Num e , Stack e c) => v -> c -> c +genericPush1 = push1 . fromIntegral + +push1 :: Stack e c => e -> c -> c +push1 e = pushList [e] + +push2 :: Stack e c => e -> e -> c -> c +push2 e e' = pushList [e , e'] + +pushList :: Stack e c => [e] -> c -> c +pushList es c = fromList es <> c + +---- + +type Stack e c = (Show c , Semigroup c , Drop e c , FromList e c , Lookup e c , SplitAt e c , Pop1 e c , Pop2 e c) diff --git a/hs/src/HelVM/HelMA/Common/Memories/StackImpl.hs b/hs/src/HelVM/HelMA/Common/Memories/StackImpl.hs new file mode 100644 index 000000000..546b4486f --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/StackImpl.hs @@ -0,0 +1,121 @@ +{-#LANGUAGE UndecidableInstances#-} +module HelVM.HelMA.Common.Memories.StackImpl ( + Index, + Stack, + divMod, + sub, + binaryOp, + binaryOps, + halibut, + move, + swap, + discard, + slide, + dup, + copy, + pushChar1, + genericPush1, + push1, + push2, + empty, + lookup, + splitAt, + drop, + pop1, + pop2 +) where + +import HelVM.HelMA.Common.BinaryOperator + +import Prelude hiding (divMod , drop , empty , fromList , splitAt , swap) + +import qualified HelVM.HelMA.Common.Collections.Drop as I +import qualified HelVM.HelMA.Common.Collections.FromList as I +import qualified HelVM.HelMA.Common.Collections.Lookup as I +import qualified HelVM.HelMA.Common.Collections.Pop as I +import qualified HelVM.HelMA.Common.Collections.SplitAt as I + +type Index = Int + +-- Arithmetic + +divMod :: (Integral e , Stack e c) => c -> c +divMod = binaryOps [Mod , Div] + +sub :: (Integral e , Stack e c) => c -> c +sub = binaryOp Sub + +binaryOp :: (Integral e , Stack e c) => BinaryOperator -> c -> c +binaryOp op = binaryOps [op] + +binaryOps :: (Integral e , Stack e c) => [BinaryOperator] -> c -> c +binaryOps ops c = pushList (calculateOps e e' ops) c' where (e , e', c') = pop2 c + +-- Stack instructions + +halibut :: (Integral e , Stack e c) => c -> c +halibut c + | i <= 0 = copy (negate i) c' + | otherwise = move i c' + where + i = fromIntegral e + (e , c') = pop1 c + +move :: Stack e c => Index -> c -> c +move i c = c1 <> c2 <> c3 where + (c1 , c3) = splitAt 1 c' + (c2 , c') = splitAt i c + +swap :: Stack e c => c -> c +swap c = push2 e' e c' where (e , e', c') = pop2 c + +discard :: Stack e c => c -> c +discard = drop 1 + +slide :: Stack e c => Index -> c -> c +slide i c = push1 e (drop i c') where (e , c') = pop1 c + +dup :: Stack e c => c -> c +dup = copy 0 + +copy :: Stack e c => Index -> c -> c +copy i c = push1 (c `index` i) c + +-- Push instructions + +pushChar1 :: (Num e , Stack e c) => Char -> c -> c +pushChar1 = genericPush1 . ord + +genericPush1 :: (Integral v , Num e , Stack e c) => v -> c -> c +genericPush1 = push1 . fromIntegral + +push1 :: Stack e c => e -> c -> c +push1 e = pushList [e] + +push2 :: Stack e c => e -> e -> c -> c +push2 e e' = pushList [e , e'] + +pushList :: Stack e c => [e] -> c -> c +pushList es c = fromList es <> c + +---- + +class (Semigroup c , Show c) => Stack e c | c -> e where + fromList :: [e] -> c + empty :: c + index :: c -> Index -> e + lookup :: Index -> c -> Maybe e + splitAt :: Index -> c -> (c , c) + drop :: Index -> c -> c + pop1 :: c -> (e , c) + pop2 :: c -> (e , e , c) + +instance (Show c , Semigroup c , I.Drop e c , I.FromList e c , I.Lookup e c , I.SplitAt e c , I.Pop1 e c , I.Pop2 e c) => Stack e c where + fromList = I.fromList + empty = I.empty + index = I.index + lookup = I.lookup + splitAt = I.splitAt + drop = I.drop + pop1 = I.pop1 + pop2 = I.pop2 diff --git a/hs/src/HelVM/HelMA/Common/Memories/StackUtil.hs b/hs/src/HelVM/HelMA/Common/Memories/StackUtil.hs new file mode 100644 index 000000000..d93ccdeaf --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Memories/StackUtil.hs @@ -0,0 +1,74 @@ +module HelVM.HelMA.Common.Memories.StackUtil where + +import HelVM.HelMA.Common.BinaryOperator + +import HelVM.HelMA.Common.Collections.Drop +import HelVM.HelMA.Common.Collections.FromList +import HelVM.HelMA.Common.Collections.Lookup +import HelVM.HelMA.Common.Collections.Pop +import HelVM.HelMA.Common.Collections.SplitAt + +import Prelude hiding (divMod , drop , empty , fromList , splitAt , swap) + +type Index = Int + +-- Arithmetic + +divMod :: (Integral e , Semigroup c , FromList e c , Pop2 e c) => c -> c +divMod = binaryOps [Mod , Div] + +sub :: (Integral e , Semigroup c , FromList e c , Pop2 e c) => c -> c +sub = binaryOp Sub + +binaryOp :: (Integral e , Semigroup c , FromList e c , Pop2 e c) => BinaryOperator -> c -> c +binaryOp op = binaryOps [op] + +binaryOps :: (Integral e , Semigroup c , FromList e c , Pop2 e c) => [BinaryOperator] -> c -> c +binaryOps ops c = pushList (calculateOps e e' ops) c' where (e , e', c') = pop2 c + +-- Stack instructions + +halibut :: (Show c , Semigroup c , Integral e , FromList e c , Lookup e c , SplitAt e c , Pop1 e c) => c -> c +halibut c + | i <= 0 = copy (negate i) c' + | otherwise = move i c' + where + i = fromIntegral e + (e , c') = pop1 c + +move :: (Semigroup c , SplitAt e c) => Index -> c -> c +move i c = c1 <> c2 <> c3 where + (c1 , c3) = splitAt 1 c' + (c2 , c') = splitAt i c + +swap :: (Semigroup c , FromList e c , Pop2 e c) => c -> c +swap c = push2 e' e c' where (e , e' , c') = pop2 c + +discard :: Drop e c => c -> c +discard = drop 1 + +slide :: (Semigroup c , Drop e c , FromList e c , Pop1 e c) => Index -> c -> c +slide i c = push1 e (drop i c') where (e , c') = pop1 c + +dup :: (Show c , Semigroup c , FromList e c , Lookup e c) => c -> c +dup = copy 0 + +copy :: (Show c , Semigroup c , FromList e c , Lookup e c) => Index -> c -> c +copy i c = push1 (c `index` i) c + +-- Push instructions + +pushChar1 :: (Num e , Semigroup c , FromList e c) => Char -> c -> c +pushChar1 = genericPush1 . ord + +genericPush1 :: (Integral v , Num e , Semigroup c , FromList e c) => v -> c -> c +genericPush1 = push1 . fromIntegral + +push1 :: (Semigroup c , FromList e c) => e -> c -> c +push1 e = pushList [e] + +push2 :: (Semigroup c , FromList e c) => e -> e -> c -> c +push2 e e' = pushList [e , e'] + +pushList :: (Semigroup c , FromList e c) => [e] -> c -> c +pushList es c = fromList es <> c diff --git a/hs/src/HelVM/HelMA/Common/OrError.hs b/hs/src/HelVM/HelMA/Common/OrError.hs index fb079fb4c..0df0ee798 100644 --- a/hs/src/HelVM/HelMA/Common/OrError.hs +++ b/hs/src/HelVM/HelMA/Common/OrError.hs @@ -11,7 +11,7 @@ infix 9 !!! check (Just result) = result check Nothing = error $ "OnError.!!!" <> show index <> " " <> show list -indexOrError :: (Show m, Show a) => m -> [a] -> Int -> a +indexOrError :: (Show m , Show a) => m -> [a] -> Int -> a indexOrError message list index = check $ list !!? index where check (Just result) = result check Nothing = error $ "OnError.indexOrError\n" <> show index <> "\n" <> show list <> "\n" <> show message diff --git a/hs/src/HelVM/HelMA/Common/Types/CellType.hs b/hs/src/HelVM/HelMA/Common/Types/CellType.hs index e3c767bad..4d20ebad2 100644 --- a/hs/src/HelVM/HelMA/Common/Types/CellType.hs +++ b/hs/src/HelVM/HelMA/Common/Types/CellType.hs @@ -1,6 +1,6 @@ module HelVM.HelMA.Common.Types.CellType where -data CellType = Int8Type | Word8Type | Int16Type | Word16Type | Int32Type | Word32Type | Int64Type | Word64Type deriving (Eq, Read, Show) +data CellType = Int8Type | Word8Type | Int16Type | Word16Type | Int32Type | Word32Type | Int64Type | Word64Type deriving (Eq , Read , Show) cellTypes :: [CellType] cellTypes = [Int8Type , Word8Type , Int16Type , Word16Type , Int32Type , Word32Type , Int64Type , Word64Type] diff --git a/hs/src/HelVM/HelMA/Common/Types/IntCellType.hs b/hs/src/HelVM/HelMA/Common/Types/IntCellType.hs new file mode 100644 index 000000000..2f9c8f8f5 --- /dev/null +++ b/hs/src/HelVM/HelMA/Common/Types/IntCellType.hs @@ -0,0 +1,14 @@ +module HelVM.HelMA.Common.Types.IntCellType where + +data IntCellType = Int8Type | Int16Type | Int32Type | Int64Type | IntegerType deriving (Eq , Read , Show) + +intCellTypes :: [IntCellType] +intCellTypes = [Int8Type , Int16Type , Int32Type , Int64Type , IntegerType] + +defaultIntCellType :: IntCellType +defaultIntCellType = IntegerType + +parseIntCellType :: String -> IntCellType +parseIntCellType raw = valid $ readMaybe raw where + valid (Just value) = value + valid Nothing = error $ "IntCellType '" <> toText raw <> "' is not valid IntCellType. Valid intCellTypes are : " <> show intCellTypes diff --git a/hs/src/HelVM/HelMA/Common/Types/RAMType.hs b/hs/src/HelVM/HelMA/Common/Types/RAMType.hs index cca3a37d6..188c5a7cb 100644 --- a/hs/src/HelVM/HelMA/Common/Types/RAMType.hs +++ b/hs/src/HelVM/HelMA/Common/Types/RAMType.hs @@ -1,9 +1,9 @@ module HelVM.HelMA.Common.Types.RAMType where -data RAMType = ListRAMType | SeqRAMType | IntMapRAMType deriving (Eq, Read, Show) +data RAMType = ListRAMType | SeqRAMType | IntMapRAMType deriving (Eq , Read , Show) ramTypes :: [RAMType] -ramTypes = [ListRAMType, SeqRAMType, IntMapRAMType] +ramTypes = [ListRAMType , SeqRAMType , IntMapRAMType] defaultRAMType :: RAMType defaultRAMType = IntMapRAMType diff --git a/hs/src/HelVM/HelMA/Common/Types/TokenType.hs b/hs/src/HelVM/HelMA/Common/Types/TokenType.hs index 27793725d..7394e7d90 100644 --- a/hs/src/HelVM/HelMA/Common/Types/TokenType.hs +++ b/hs/src/HelVM/HelMA/Common/Types/TokenType.hs @@ -8,11 +8,6 @@ tokenTypes = [VisibleTokenType , WhiteTokenType , BothTokenType] defaultTokenType :: TokenType defaultTokenType = VisibleTokenType ---parseTokenType :: String -> TokenType ---parseTokenType raw = valid $ readMaybe raw where --- valid (Just value) = value --- valid Nothing = error $ "TokenType '" <> toText raw <> "' is not valid TokenType. Valid tokenTypes are : " <> show tokenTypes - parseTokenType :: Bool -> TokenType parseTokenType True = VisibleTokenType parseTokenType _ = WhiteTokenType diff --git a/hs/src/HelVM/HelMA/Common/Util.hs b/hs/src/HelVM/HelMA/Common/Util.hs index f911160ca..5c5cfa44a 100644 --- a/hs/src/HelVM/HelMA/Common/Util.hs +++ b/hs/src/HelVM/HelMA/Common/Util.hs @@ -1,7 +1,6 @@ module HelVM.HelMA.Common.Util where import Data.Char -import Data.List type D a = a -> a @@ -22,33 +21,25 @@ chunksOf n list | n > 0 = take n list : chunksOf n (drop n list) | otherwise = error "Non positive n" -appendToList :: [a] -> a -> [a] -appendToList xs x = x : xs - -splitBySeparator :: Eq a => a -> [a] -> ([a], [a]) -splitBySeparator _ [] = ([], []) -splitBySeparator separator (x:xs) - | separator == x = ([separator], xs) - | otherwise = (x:acc, xs') where (acc, xs') = splitBySeparator separator xs - -splitBy :: Eq a => a -> [a] -> ([a], [a]) -splitBy separator xs = split $ elemIndex separator xs where - split Nothing = (xs, []) - split (Just index) = splitBy' $ splitAt index xs where - splitBy' (acc, _:xs') = (acc, xs') - splitBy' (acc, []) = (acc, []) +splitBy :: Eq a => a -> [a] -> ([a] , [a]) +splitBy separator xs = (acc , drop 1 xs') where (acc , xs') = break (== separator) xs -- StringUtil -splitStringByEndLine :: String -> (String, String) +splitStringByEndLine :: String -> (String , String) splitStringByEndLine = splitBy '\n' toUppers :: String -> String toUppers = map toUpper +-- CharUtil + +genericChr :: Integral a => a -> Char +genericChr = chr . fromIntegral + -- other -mulAndAdd :: (Integral a) => a -> a -> a -> a +mulAndAdd :: Integral a => a -> a -> a -> a mulAndAdd base digit acc = acc * base + digit mul2AndAdd :: (Integral a) => a -> a -> a diff --git a/hs/src/HelVM/HelMA/Common/WrapTokenList.hs b/hs/src/HelVM/HelMA/Common/WrapTokenList.hs index 885f8b021..e7895ca7e 100644 --- a/hs/src/HelVM/HelMA/Common/WrapTokenList.hs +++ b/hs/src/HelVM/HelMA/Common/WrapTokenList.hs @@ -12,4 +12,4 @@ instance Show a => Show (WrapTokenList [a]) where show (WrapTokenList tokens) = show =<< tokens instance Read a => Read (WrapTokenList [a]) where - readsPrec _ source = [( WrapTokenList $ maybeToList . readMaybe . one =<< source, "")] + readsPrec _ source = [( WrapTokenList $ maybeToList . readMaybe . one =<< source , "")] diff --git a/hs/test/HelVM/HelMA/Automata/BrainFuck/EvaluatorSpecData.hs b/hs/test/HelVM/HelMA/Automata/BrainFuck/EvaluatorSpecData.hs index 1e88ad162..478704e91 100644 --- a/hs/test/HelVM/HelMA/Automata/BrainFuck/EvaluatorSpecData.hs +++ b/hs/test/HelVM/HelMA/Automata/BrainFuck/EvaluatorSpecData.hs @@ -9,4 +9,4 @@ helloWorldExpected :: Output helloWorldExpected = "Hello World!\n" hello_WorldExpected :: Output -hello_WorldExpected = "Hello, World!" +hello_WorldExpected = "Hello , World!" diff --git a/hs/test/HelVM/HelMA/Automata/CartesianProduct.hs b/hs/test/HelVM/HelMA/Automata/CartesianProduct.hs index 94519ae27..272445e3f 100644 --- a/hs/test/HelVM/HelMA/Automata/CartesianProduct.hs +++ b/hs/test/HelVM/HelMA/Automata/CartesianProduct.hs @@ -17,8 +17,8 @@ infixr 9 >><< (>><<) = liftA2 (\(a1 , a2) (b1 , b2) -> (a1 , a2 , b1 , b2)) infixr 9 >>><< -(>>><<) :: [(a1 , a2 , a3)] -> [(b1 , b2)] -> [(a1 , a2 , a3, b1 , b2)] -(>>><<) = liftA2 (\(a1 , a2 , a3) (b1 , b2) -> (a1 , a2 , a3, b1 , b2)) +(>>><<) :: [(a1 , a2 , a3)] -> [(b1 , b2)] -> [(a1 , a2 , a3 , b1 , b2)] +(>>><<) = liftA2 (\(a1 , a2 , a3) (b1 , b2) -> (a1 , a2 , a3 , b1 , b2)) infixr 9 >><<< (>><<<) :: [(a1 , a2)] -> [(b1 , b2 , b3)] -> [(a1 , a2 , b1 , b2 , b3)] diff --git a/hs/test/HelVM/HelMA/Automata/Cat/EvaluatorSpec.hs b/hs/test/HelVM/HelMA/Automata/Cat/EvaluatorSpec.hs index 5ed0a1551..e750f4966 100644 --- a/hs/test/HelVM/HelMA/Automata/Cat/EvaluatorSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/Cat/EvaluatorSpec.hs @@ -10,10 +10,10 @@ import Test.Hspec spec :: Spec spec = do describe "interact" $ do - it "Hello, world!" $ do batchEval hw `shouldBe` hw + it "Hello , world!" $ do batchEval hw `shouldBe` hw describe "monadic" $ do - it "Hello, world!" $ do (batchExecMockIO . eval) hw `shouldBe` hw + it "Hello , world!" $ do (batchExecMockIO . eval) hw `shouldBe` hw hw :: Source -hw = "#!/bin/cat\nHello, world!\n" \ No newline at end of file +hw = "#!/bin/cat\nHello , world!\n" \ No newline at end of file diff --git a/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorSpec.hs b/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorSpec.hs index ad60788c9..03315a9b0 100644 --- a/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorSpec.hs @@ -63,7 +63,7 @@ spec = do , ("bottles" , "" ) , ("crlf" , "" ) ] >><| stackTypes - ) $ \(fileName , input, stackType) -> do + ) $ \(fileName , input , stackType) -> do let minorPath = show stackType fileName <> input let params = ( , stackType) <$> readEtaFile ("original" fileName) describe minorPath $ do diff --git a/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorUtilSpec.hs b/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorUtilSpec.hs index b693ba4e1..400ab09f4 100644 --- a/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorUtilSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/ETA/EvaluatorUtilSpec.hs @@ -10,20 +10,20 @@ spec :: Spec spec = do describe "parseInteger" $ do it "[E]" $ do parseInteger [E] `shouldBe` 0 - it "[S, E]" $ do parseInteger [S, E] `shouldBe` 6 - it "[T, E]" $ do parseInteger [T, E] `shouldBe` 1 - it "[S, S, E]" $ do parseInteger [S, S, E] `shouldBe` 48 - it "[S, T, E]" $ do parseInteger [S, T, E] `shouldBe` 43 - it "[T, S, E]" $ do parseInteger [T, S, E] `shouldBe` 13 - it "[T, T, E]" $ do parseInteger [T, T, E] `shouldBe` 8 - it "[S, S, S, E]" $ do parseInteger [S, S, S, E] `shouldBe` 342 - it "[S, S, T, E]" $ do parseInteger [S, S, T, E] `shouldBe` 337 - it "[S, T, S, E]" $ do parseInteger [S, T, S, E] `shouldBe` 307 - it "[S, T, T, E]" $ do parseInteger [S, T, T, E] `shouldBe` 302 - it "[T, S, S, E]" $ do parseInteger [T, S, S, E] `shouldBe` 97 - it "[T, S, T, E]" $ do parseInteger [T, S, T, E] `shouldBe` 92 - it "[T, T, S, E]" $ do parseInteger [T, T, S, E] `shouldBe` 62 - it "[T, T, T, E]" $ do parseInteger [T, T, T, E] `shouldBe` 57 + it "[S , E]" $ do parseInteger [S , E] `shouldBe` 6 + it "[T , E]" $ do parseInteger [T , E] `shouldBe` 1 + it "[S , S , E]" $ do parseInteger [S , S , E] `shouldBe` 48 + it "[S , T , E]" $ do parseInteger [S , T , E] `shouldBe` 43 + it "[T , S , E]" $ do parseInteger [T , S , E] `shouldBe` 13 + it "[T , T , E]" $ do parseInteger [T , T , E] `shouldBe` 8 + it "[S , S , S , E]" $ do parseInteger [S , S , S , E] `shouldBe` 342 + it "[S , S , T , E]" $ do parseInteger [S , S , T , E] `shouldBe` 337 + it "[S , T , S , E]" $ do parseInteger [S , T , S , E] `shouldBe` 307 + it "[S , T , T , E]" $ do parseInteger [S , T , T , E] `shouldBe` 302 + it "[T , S , S , E]" $ do parseInteger [T , S , S , E] `shouldBe` 97 + it "[T , S , T , E]" $ do parseInteger [T , S , T , E] `shouldBe` 92 + it "[T , T , S , E]" $ do parseInteger [T , T , S , E] `shouldBe` 62 + it "[T , T , T , E]" $ do parseInteger [T , T , T , E] `shouldBe` 57 describe "findAddress ertrar" $ do it "1" $ do findAddress ertrar 1 `shouldBe` 0 @@ -64,17 +64,19 @@ spec = do it "5" $ do findAddress hello2TL 5 `shouldBe` 123 describe "nextLabel hello2TL" $ do - it "38" $ do nextLabel hello2TL 38 `shouldBe` 2 - it "76" $ do nextLabel hello2TL 76 `shouldBe` 3 - it "78" $ do nextLabel hello2TL 78 `shouldBe` 4 - it "106" $ do nextLabel hello2TL 106 `shouldBe` 5 - it "123" $ do nextLabel hello2TL 123 `shouldBe` 6 + forM_ [ (38 , 2) + , (76 , 3) + , (78 , 4) + , (106 , 5) + , (123 , 6) + ] $ \(input , output) -> do + it (show input) $ do nextLabel hello2TL input `shouldBe` output parseInteger :: TokenList -> Integer parseInteger tl = fst $ parseNumber $ IU tl 0 ertrar :: TokenList -ertrar = [E, R, T, R, A, R] +ertrar = [E , R , T , R , A , R] etaretaretar :: TokenList -etaretaretar = [E, T, A, R, E, T, A, R, E, T, A, R] +etaretaretar = [E , T , A , R , E , T , A , R , E , T , A , R] diff --git a/hs/test/HelVM/HelMA/Automata/Expectations.hs b/hs/test/HelVM/HelMA/Automata/Expectations.hs index 22d6087a8..f0ef621a8 100644 --- a/hs/test/HelVM/HelMA/Automata/Expectations.hs +++ b/hs/test/HelVM/HelMA/Automata/Expectations.hs @@ -27,11 +27,11 @@ goldenShouldBe actualOutput fileName = } infix 1 `ioShouldBe` -ioShouldBe :: (HasCallStack, Show a, Eq a) => IO a -> IO a -> Expectation +ioShouldBe :: (HasCallStack , Show a , Eq a) => IO a -> IO a -> Expectation ioShouldBe action expected = join $ liftA2 shouldBe action expected infix 1 `shouldBeDo` -shouldBeDo :: (HasCallStack, Show a, Eq a) => a -> IO a -> Expectation +shouldBeDo :: (HasCallStack , Show a , Eq a) => a -> IO a -> Expectation shouldBeDo action expected = shouldBe action =<< expected ---- diff --git a/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpec.hs b/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpec.hs index ee9accbd1..279f970e9 100644 --- a/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpec.hs @@ -21,6 +21,7 @@ spec = do describe fileName $ do it "interact" $ do batchSimpleEvalIL il `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalIL" "interact" fileName) it "monadic" $ do (batchExecMockIO . simpleEvalIL) il `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalIL" "monadic" fileName) + it "monadic" $ do (batchEvalMockIO . simpleEvalIL) il `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalIL" "logging" fileName) describe "simpleEval" $ do forM_ [ ("hello" , "" ) @@ -30,3 +31,4 @@ spec = do describe fileName $ do it "interact" $ do flipSimpleEval input <$> params `goldenShouldReturn` buildAbsoluteOutFileName ("simpleEval" "interact" fileName) it "monadic" $ do flipExecMockIO input . simpleEval <$> params `goldenShouldReturn` buildAbsoluteOutFileName ("simpleEval" "monadic" fileName) + it "logging" $ do flipEvalMockIO input . simpleEval <$> params `goldenShouldReturn` buildAbsoluteOutFileName ("simpleEval" "logging" fileName) diff --git a/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpecData.hs b/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpecData.hs index 14a3fd831..9be6edb29 100644 --- a/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpecData.hs +++ b/hs/test/HelVM/HelMA/Automata/SubLeq/EvaluatorSpecData.hs @@ -1,4 +1,4 @@ module HelVM.HelMA.Automata.SubLeq.EvaluatorSpecData where helloSQIL :: Integral i => [i] -helloSQIL = [15, 17, -1, 17, -1, -1, 16, 1, -1, 16, 3, -1, 15, 15, 0, 0, -1, 72, 101, 108, 108, 111, 44, 32, 119, 111, 114, 108, 100, 33, 10, 0] +helloSQIL = [15 , 17 , -1 , 17 , -1 , -1 , 16 , 1 , -1 , 16 , 3 , -1 , 15 , 15 , 0 , 0 , -1 , 72 , 101 , 108 , 108 , 111 , 44 , 32 , 119 , 111 , 114 , 108 , 100 , 33 , 10 , 0] diff --git a/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpec.hs b/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpec.hs index 58e1e99c7..a21825f36 100644 --- a/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpec.hs @@ -96,7 +96,7 @@ spec = do , ("locTestTL" , locTestTL , "1\n2\n" ) , ("nameTL" , nameTL , "WriteOnly\n") , ("truthMachineTL" , truthMachineTL , "0\n" ) - ] $ \(fileName , tl, input) -> do + ] $ \(fileName , tl , input) -> do describe fileName $ do it ("interact" fileName) $ do flipSimpleEvalTL input tl `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalTL" "interact" fileName) @@ -106,9 +106,9 @@ spec = do (flipEvalMockIO input . simpleEvalTL) tl `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalTL" "logging" fileName) describe "simpleEvalIL" $ do - forM_ [ ("call" , [Call "A", End, Mark "A", Return] , "") - , ("push-pop" , [Liter 0 , Discard, End] , "") - , ("pop" , [Discard, End] , "") - ] $ \(fileName , il, input) -> do + forM_ [ ("call" , [Call "A", End , Mark "A", Return] , "") + , ("push-pop" , [Liter 0 , Discard , End] , "") + , ("pop" , [Discard , End] , "") + ] $ \(fileName , il , input) -> do it fileName $ do flipEvalMockIO input (evalIL il SeqStackType IntMapRAMType) `goldenShouldBe` buildAbsoluteOutFileName ("simpleEvalIL" "logging" fileName) diff --git a/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpecData.hs b/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpecData.hs index 6a01e23cf..ff007f5ef 100644 --- a/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpecData.hs +++ b/hs/test/HelVM/HelMA/Automata/WhiteSpace/EvaluatorSpecData.hs @@ -97,8 +97,8 @@ truthMachineTL = catIL :: InstructionList catIL = [ Mark "0" - , Liter 1, InputChar - , Liter 1, Load, OutputChar + , Liter 1 , InputChar + , Liter 1 , Load , OutputChar , Liter 1 , Branch EZ "1" , Jump "0" @@ -109,18 +109,18 @@ catIL = helloWorldIL :: InstructionList helloWorldIL = - [ Liter 72, OutputChar - , Liter 101, OutputChar - , Liter 108, OutputChar - , Liter 108, OutputChar + [ Liter 72 , OutputChar + , Liter 101 , OutputChar + , Liter 108 , OutputChar + , Liter 108 , OutputChar , Liter 111,OutputChar - , Liter 44, OutputChar - , Liter 32, OutputChar - , Liter 119, OutputChar - , Liter 111, OutputChar - , Liter 114, OutputChar - , Liter 108, OutputChar - , Liter 100, OutputChar + , Liter 44 , OutputChar + , Liter 32 , OutputChar + , Liter 119 , OutputChar + , Liter 111 , OutputChar + , Liter 114 , OutputChar + , Liter 108 , OutputChar + , Liter 100 , OutputChar , End ] @@ -133,10 +133,10 @@ truthMachineIL = , Branch EZ "0" , Mark "1" - , Liter 1, OutputNum + , Liter 1 , OutputNum , Jump "1" , Mark "0" - , Liter 0, OutputNum + , Liter 0 , OutputNum , End ] diff --git a/hs/test/HelVM/HelMA/Automata/WhiteSpace/OperandParsersSpec.hs b/hs/test/HelVM/HelMA/Automata/WhiteSpace/OperandParsersSpec.hs index 3d49f8e7a..566c8b833 100644 --- a/hs/test/HelVM/HelMA/Automata/WhiteSpace/OperandParsersSpec.hs +++ b/hs/test/HelVM/HelMA/Automata/WhiteSpace/OperandParsersSpec.hs @@ -9,44 +9,44 @@ spec :: Spec spec = do describe "(fst . parseNatural)" $ do it "[N]" $ do (fst . parseNatural) [N] `shouldBe` 0 - it "[S, N]" $ do (fst . parseNatural) [S, N] `shouldBe` 0 - it "[T, N]" $ do (fst . parseNatural) [T, N] `shouldBe` 1 - it "[S, S, N]" $ do (fst . parseNatural) [S, S, N] `shouldBe` 0 - it "[S, T, N]" $ do (fst . parseNatural) [S, T, N] `shouldBe` 1 - it "[T, S, N]" $ do (fst . parseNatural) [T, S, N] `shouldBe` 2 - it "[T, T, N]" $ do (fst . parseNatural) [T, T, N] `shouldBe` 3 - it "[S, S, S, N]" $ do (fst . parseNatural) [S, S, S, N] `shouldBe` 0 - it "[S, S, T, N]" $ do (fst . parseNatural) [S, S, T, N] `shouldBe` 1 - it "[S, T, S, N]" $ do (fst . parseNatural) [S, T, S, N] `shouldBe` 2 - it "[S, T, T, N]" $ do (fst . parseNatural) [S, T, T, N] `shouldBe` 3 - it "[T, S, S, N]" $ do (fst . parseNatural) [T, S, S, N] `shouldBe` 4 - it "[T, S, T, N]" $ do (fst . parseNatural) [T, S, T, N] `shouldBe` 5 - it "[T, T, S, N]" $ do (fst . parseNatural) [T, T, S, N] `shouldBe` 6 - it "[T, T, T, N]" $ do (fst . parseNatural) [T, T, T, N] `shouldBe` 7 + it "[S , N]" $ do (fst . parseNatural) [S , N] `shouldBe` 0 + it "[T , N]" $ do (fst . parseNatural) [T , N] `shouldBe` 1 + it "[S , S , N]" $ do (fst . parseNatural) [S , S , N] `shouldBe` 0 + it "[S , T , N]" $ do (fst . parseNatural) [S , T , N] `shouldBe` 1 + it "[T , S , N]" $ do (fst . parseNatural) [T , S , N] `shouldBe` 2 + it "[T , T , N]" $ do (fst . parseNatural) [T , T , N] `shouldBe` 3 + it "[S , S , S , N]" $ do (fst . parseNatural) [S , S , S , N] `shouldBe` 0 + it "[S , S , T , N]" $ do (fst . parseNatural) [S , S , T , N] `shouldBe` 1 + it "[S , T , S , N]" $ do (fst . parseNatural) [S , T , S , N] `shouldBe` 2 + it "[S , T , T , N]" $ do (fst . parseNatural) [S , T , T , N] `shouldBe` 3 + it "[T , S , S , N]" $ do (fst . parseNatural) [T , S , S , N] `shouldBe` 4 + it "[T , S , T , N]" $ do (fst . parseNatural) [T , S , T , N] `shouldBe` 5 + it "[T , T , S , N]" $ do (fst . parseNatural) [T , T , S , N] `shouldBe` 6 + it "[T , T , T , N]" $ do (fst . parseNatural) [T , T , T , N] `shouldBe` 7 describe "(fst . parseInteger)" $ do it "[N]" $ do (fst . parseInteger) [N] `shouldBe` 0 - it "[S, N]" $ do (fst . parseInteger) [S, N] `shouldBe` 0 - it "[T, N]" $ do (fst . parseInteger) [T, N] `shouldBe` 0 - it "[S, S, N]" $ do (fst . parseInteger) [S, S, N] `shouldBe` 0 - it "[S, T, N]" $ do (fst . parseInteger) [S, T, N] `shouldBe` 1 - it "[T, S, N]" $ do (fst . parseInteger) [T, S, N] `shouldBe` 0 - it "[T, T, N]" $ do (fst . parseInteger) [T, T, N] `shouldBe` (-1) - it "[S, S, S, N]" $ do (fst . parseInteger) [S, S, S, N] `shouldBe` 0 - it "[S, S, T, N]" $ do (fst . parseInteger) [S, S, T, N] `shouldBe` 1 - it "[S, T, S, N]" $ do (fst . parseInteger) [S, T, S, N] `shouldBe` 2 - it "[S, T, T, N]" $ do (fst . parseInteger) [S, T, T, N] `shouldBe` 3 - it "[T, S, S, N]" $ do (fst . parseInteger) [T, S, S, N] `shouldBe` 0 - it "[T, S, T, N]" $ do (fst . parseInteger) [T, S, T, N] `shouldBe` (-1) - it "[T, T, S, N]" $ do (fst . parseInteger) [T, T, S, N] `shouldBe` (-2) - it "[T, T, T, N]" $ do (fst . parseInteger) [T, T, T, N] `shouldBe` (-3) + it "[S , N]" $ do (fst . parseInteger) [S , N] `shouldBe` 0 + it "[T , N]" $ do (fst . parseInteger) [T , N] `shouldBe` 0 + it "[S , S , N]" $ do (fst . parseInteger) [S , S , N] `shouldBe` 0 + it "[S , T , N]" $ do (fst . parseInteger) [S , T , N] `shouldBe` 1 + it "[T , S , N]" $ do (fst . parseInteger) [T , S , N] `shouldBe` 0 + it "[T , T , N]" $ do (fst . parseInteger) [T , T , N] `shouldBe` (-1) + it "[S , S , S , N]" $ do (fst . parseInteger) [S , S , S , N] `shouldBe` 0 + it "[S , S , T , N]" $ do (fst . parseInteger) [S , S , T , N] `shouldBe` 1 + it "[S , T , S , N]" $ do (fst . parseInteger) [S , T , S , N] `shouldBe` 2 + it "[S , T , T , N]" $ do (fst . parseInteger) [S , T , T , N] `shouldBe` 3 + it "[T , S , S , N]" $ do (fst . parseInteger) [T , S , S , N] `shouldBe` 0 + it "[T , S , T , N]" $ do (fst . parseInteger) [T , S , T , N] `shouldBe` (-1) + it "[T , T , S , N]" $ do (fst . parseInteger) [T , T , S , N] `shouldBe` (-2) + it "[T , T , T , N]" $ do (fst . parseInteger) [T , T , T , N] `shouldBe` (-3) describe "(fst . parseBitString)" $ do - it "[S, S, S, N]" $ do (fst . parseBitString) [S, S, S, N] `shouldBe` "000" - it "[S, S, T, N]" $ do (fst . parseBitString) [S, S, T, N] `shouldBe` "001" - it "[S, T, S, N]" $ do (fst . parseBitString) [S, T, S, N] `shouldBe` "010" - it "[S, T, T, N]" $ do (fst . parseBitString) [S, T, T, N] `shouldBe` "011" - it "[T, S, S, N]" $ do (fst . parseBitString) [T, S, S, N] `shouldBe` "100" - it "[T, S, T, N]" $ do (fst . parseBitString) [T, S, T, N] `shouldBe` "101" - it "[T, T, S, N]" $ do (fst . parseBitString) [T, T, S, N] `shouldBe` "110" - it "[T, T, T, N]" $ do (fst . parseBitString) [T, T, T, N] `shouldBe` "111" + it "[S , S , S , N]" $ do (fst . parseBitString) [S , S , S , N] `shouldBe` "000" + it "[S , S , T , N]" $ do (fst . parseBitString) [S , S , T , N] `shouldBe` "001" + it "[S , T , S , N]" $ do (fst . parseBitString) [S , T , S , N] `shouldBe` "010" + it "[S , T , T , N]" $ do (fst . parseBitString) [S , T , T , N] `shouldBe` "011" + it "[T , S , S , N]" $ do (fst . parseBitString) [T , S , S , N] `shouldBe` "100" + it "[T , S , T , N]" $ do (fst . parseBitString) [T , S , T , N] `shouldBe` "101" + it "[T , T , S , N]" $ do (fst . parseBitString) [T , T , S , N] `shouldBe` "110" + it "[T , T , T , N]" $ do (fst . parseBitString) [T , T , T , N] `shouldBe` "111" diff --git a/hs/test/HelVM/HelMA/Common/UtilSpec.hs b/hs/test/HelVM/HelMA/Common/UtilSpec.hs new file mode 100644 index 000000000..ae699f2bf --- /dev/null +++ b/hs/test/HelVM/HelMA/Common/UtilSpec.hs @@ -0,0 +1,12 @@ +module HelVM.HelMA.Common.UtilSpec (spec) where + +import HelVM.HelMA.Common.Util + +import Test.Hspec + +spec :: Spec +spec = do + describe "Test WFilter0" $ do + it "(3) [1,2,3,4,1,2,3,4]" $ do splitBy (3 :: Integer) [1,2,3,4,1,2,3,4] `shouldBe` ([1,2] , [4,1,2,3,4]) + it "(9) [1,2,3]" $ do splitBy (9 :: Integer) [1,2,3] `shouldBe` ([1,2,3] , []) + it "(0) [1,2,3]" $ do splitBy (9 :: Integer) [1,2,3] `shouldBe` ([1,2,3] , [])