diff options
| author | Jan Tuomi <jan.tuomi@valuemotive.com> | 2022-09-23 10:38:03 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2022-12-05 14:21:52 +0200 |
| commit | fd39958d20554fdc19611c5f23d32c8493ad655e (patch) | |
| tree | 4ce19fa2e89e106e58f207029942cb427ba7e779 /src | |
| parent | 12ac2354ffca7a221cb4535354eb86907bfceea7 (diff) | |
Add exceptions, global config
Diffstat (limited to 'src')
| -rw-r--r-- | src/Lib.hs | 62 | ||||
| -rw-r--r-- | src/Types.hs | 13 | ||||
| -rw-r--r-- | src/Utils.hs | 6 |
3 files changed, 63 insertions, 18 deletions
@@ -1,10 +1,16 @@ -module Lib - ( runScriptFile - ) where +module Lib ( + runScriptFile, + LContext +) where import qualified Data.Map as M import qualified Data.Bifunctor as B +import Control.Monad.Except +import Control.Monad.Reader +import Data.List import Debug.Trace +import Types +import Utils data AST = ASTNumber Double @@ -15,25 +21,40 @@ data AST | ASTHashMap (M.Map AST AST) | ASTFunction (AST -> AST) -_tokenize :: [String] -> String -> String -> [String] +instance (Show AST) where + show (ASTNumber n) = show n + show (ASTSymbol s) = show s + show (ASTBoolean b) = show b + show (ASTString s) = show s + show (ASTVector v) = "[" ++ intercalate " " (map show v) ++ "]" + show (ASTHashMap m) = + let flattenMap = M.assocs .> map (\(k, v) -> [k, v]) .> concat + in "[" ++ intercalate " " (map show $ flattenMap m) ++ "]" + show (ASTFunction _) = "<fn>" + +_tokenize :: [String] -> String -> String -> LContext [String] _tokenize acc current src = case src of - "" -> reverse current : acc + "" -> return $ reverse current : acc (x:xs) | x == ';' -> let commentDropped = dropWhile (\c -> c /= '\n') xs in _tokenize (reverse current : acc) "" commentDropped | x == '"' -> - let consume :: String -> (String, Int) + -- String length -1 signals an unbalanced error + let inc k n = if n == -1 then -1 else n + k + consume :: String -> (String, Int) consume str = case str of - ('\\':'"':rest) -> B.bimap ('\"' :) (+ 2) (consume rest) - ('\\':'n':rest) -> B.bimap ('\n' :) (+ 2) (consume rest) - ('\\':'t':rest) -> B.bimap ('\t' :) (+ 2) (consume rest) + ('\\':'"':rest) -> B.bimap ('\"' :) (inc 2) (consume rest) + ('\\':'n':rest) -> B.bimap ('\n' :) (inc 2) (consume rest) + ('\\':'t':rest) -> B.bimap ('\t' :) (inc 2) (consume rest) ('"':_) -> ("", 1) - (c:rest) -> B.bimap (c :) (+ 1) (consume rest) - [] -> error "Unbalanced string literal" + (c:rest) -> B.bimap (c :) (inc 1) (consume rest) + [] -> ("", -1) (string, stringLength) = consume xs stringDropped = drop (stringLength) xs - in _tokenize (string : acc) "" stringDropped + in do + when (stringLength == -1) $ throwError (LException "Unbalanced string literal") + _tokenize (string : acc) "" stringDropped | x `elem` [' ', '\n', '\t', '\r'] -> _tokenize (reverse current : acc) "" xs | x `elem` ['(', ')', '[', ']', '{', '}', '\\'] -> @@ -41,16 +62,21 @@ _tokenize acc current src = case src of | otherwise -> _tokenize acc (x : current) xs -tokenize :: String -> [String] -tokenize = filter (\t -> length t > 0) . reverse . _tokenize [] "" +tokenize :: String -> LContext [String] +tokenize src = do + tokens <- _tokenize [] "" src + return $ tokens + $> reverse + .> filter (\s -> length s > 0) parse :: [String] -> [AST] parse src = [] -runScriptFile :: String -> IO () +runScriptFile :: String -> LContext () runScriptFile fileName = do - src <- readFile fileName - let tokenized = tokenize src - putStrLn $ "tokenized:\t\t" ++ show tokenized + src <- liftIO $ readFile fileName + tokenized <- tokenize src + config <- ask + when (configVerboseMode config) $ liftIO $ putStrLn $ "tokenized:\t\t" ++ show tokenized let parsed = parse tokenized return () diff --git a/src/Types.hs b/src/Types.hs new file mode 100644 index 0000000..94428b6 --- /dev/null +++ b/src/Types.hs @@ -0,0 +1,13 @@ +module Types where + +import Control.Monad.Except +import Control.Monad.Reader + +newtype LException = LException String +data Config = Config { + configScriptFileName :: Maybe String, + configVerboseMode :: Bool, + configShowHelp :: Bool +} + +type LContext a = ReaderT Config (ExceptT LException IO) a diff --git a/src/Utils.hs b/src/Utils.hs new file mode 100644 index 0000000..2497c9f --- /dev/null +++ b/src/Utils.hs @@ -0,0 +1,6 @@ +module Utils where + +(.>) = flip (.) +($>) = flip ($) + +infixr 6 $> |
