diff options
| author | Matthew Hall <hallmatthew314@gmail.com> | 2023-02-14 11:29:11 +1300 |
|---|---|---|
| committer | Matthew Hall <hallmatthew314@gmail.com> | 2023-02-14 11:29:11 +1300 |
| commit | 7e59323e865f86f1e67821a3ff96efc8e5822dff (patch) | |
| tree | 76c1213576e295a38171c9ade46db3ee21460a77 /DSL.hs | |
| parent | a17f9ba31d682f18c5e25d07bd94d2ccfb6de6d0 (diff) | |
Very basic interpretations
Diffstat (limited to 'DSL.hs')
| -rw-r--r-- | DSL.hs | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -1,6 +1,7 @@ module DSL where import Data.Char (isDigit, isSpace) +import Data.Foldable (foldlM) import Parsers @@ -30,6 +31,10 @@ data Operation type Program = [Operation] +data Machine = Machine { ok :: Bool + , stack :: Stack + } + data TokenData = T_WHITESPACE | T_INT_LITERAL Integer @@ -118,3 +123,53 @@ stringToProgram str = do (_, program) <- parse programP tokens return program +------------------------------------------------------------------------------ +-- Intrinsics +------------------------------------------------------------------------------ + +dump :: Machine -> IO Machine +dump m = case stack m of + [] -> hcf m "DUMP: stack underflow" + x:xs -> putStrLn (show x) >> return m{ stack=xs } + +------------------------------------------------------------------------------ +-- Core operations +------------------------------------------------------------------------------ + +-- "halt and catch fire" +hcf :: Machine -> String -> IO Machine +hcf m msg = putStrLn msg >> return m{ ok=False } + +pushData :: Machine -> StackData -> Machine +pushData m@Machine{ stack=xs } x = m{ stack=x:xs } + +applyIntrinsic :: Machine -> Intrinsic -> IO Machine +applyIntrinsic m I_DUMP = dump m + +------------------------------------------------------------------------------ +-- Interpretation +------------------------------------------------------------------------------ + +newMachine :: Machine +newMachine = Machine { ok=True, stack=[] } + +applyOperation :: Machine -> Operation -> IO Machine +-- take no action if a previous step failed +applyOperation m@Machine{ ok=False } _ = return m +applyOperation m (OpPushData x) = return $ pushData m x +applyOperation m (OpIntrinsic i) = applyIntrinsic m i + +applyLinear :: Machine -> [Operation] -> IO Machine +applyLinear = foldlM applyOperation + +interpret :: Program -> IO () +interpret p = applyLinear newMachine p >> return () + +interpretFromString :: String -> IO () +interpretFromString = maybe err interpret . stringToProgram + where + err = putStrLn "Unable to parse program" + +interpretFromFile :: FilePath -> IO () +interpretFromFile path = readFile path >>= interpretFromString + |
