diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.hs | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/main.hs b/src/main.hs index 90de59e..fc5d60c 100644 --- a/src/main.hs +++ b/src/main.hs @@ -1,6 +1,9 @@ module Main where import Data.Char +import Data.List (isPrefixOf) +import Data.Map (Map, (!)) +import qualified Data.Map as M import System.Environment (getArgs) import Utils @@ -10,30 +13,43 @@ getFilename (f : fs) = f data LWord = LSymbol String | LInteger Integer + | LVariable String deriving (Show) reprWord (LSymbol a) = a reprWord (LInteger a) = show a +reprWord (LVariable a) = a parseWord rawStr | all isDigit rawStr = LInteger (read rawStr) + | "$" `isPrefixOf` rawStr = LVariable $ tail rawStr | otherwise = LSymbol rawStr parseSource source = source $> words .> map parseWord -interpretSource :: [LWord] -> [LWord] -> IO () -interpretSource _ [] = putStrLn "done" -interpretSource stack (word : rest) = do - newStack <- interpretWord stack word - interpretSource newStack rest +interpretSource _ _ [] = putStrLn "done" +interpretSource stack dict (word : rest) = do + (newStack, newDict) <- interpretWord stack dict word + interpretSource newStack newDict rest -interpretWord :: [LWord] -> LWord -> IO [LWord] -interpretWord stack word@(LInteger value) = pure $ word : stack -interpretWord (a : stack) word@(LSymbol ".") = do +-- no ops +interpretWord stack dict word@(LInteger value) = pure (word : stack, dict) +interpretWord stack dict word@(LVariable value) = pure (word : stack, dict) +-- variables & printing +interpretWord ((LVariable a) : b : stack) dict word@(LSymbol "!") = + let newDict = M.insert a b dict + in pure (stack, newDict) +interpretWord ((LVariable a) : stack) dict word@(LSymbol "@") = + let lookupWord = dict ! a + newDict = M.delete a dict + in pure (lookupWord : stack, newDict) +interpretWord (a : stack) dict word@(LSymbol ".") = do putStrLn $ reprWord a - pure stack -interpretWord ((LInteger a) : (LInteger b) : stack) word@(LSymbol "+") = pure $ LInteger (a + b) : stack -interpretWord _ other = error $ "[error] runtime error at " ++ show other + pure (stack, dict) +-- math +interpretWord ((LInteger a) : (LInteger b) : stack) dict word@(LSymbol "+") = pure $ (LInteger (a + b) : stack, dict) +-- error +interpretWord stack _ other = error $ "[error] runtime error at " ++ show other ++ "\nstack at time of error:\n" ++ show stack main :: IO () main = do @@ -45,4 +61,4 @@ main = do let parsed = parseSource source putStrLn $ "[info] parsed words:\n" ++ show parsed putStrLn "[info] interpreter output:" - interpretSource [] parsed + interpretSource [] M.empty parsed |
