From 494078074e5f620f11f72e48d0fc44cff73faaf2 Mon Sep 17 00:00:00 2001 From: Akshay Date: Fri, 23 Oct 2020 18:03:31 +0530 Subject: refactor internal datatypes to Base - avoids cyclic module dependencies - cleaner exports to Main module --- bin/Main.hs | 8 ++++++-- lisk.cabal | 1 + src/Environment.hs | 4 +--- src/Error/Base.hs | 2 +- src/Evaluator.hs | 3 ++- src/Operators.hs | 2 +- src/Parser.hs | 29 +---------------------------- 7 files changed, 13 insertions(+), 36 deletions(-) diff --git a/bin/Main.hs b/bin/Main.hs index 18e1c53..3d9fad4 100644 --- a/bin/Main.hs +++ b/bin/Main.hs @@ -1,5 +1,6 @@ module Main where +import Base (Expr (..)) import Control.Monad (liftM) import Control.Monad.Except (liftIO, runExceptT, throwError) import Environment @@ -7,7 +8,7 @@ import Error.Base (LispError (..), LispResult (..), unwrap) import Error.Pretty (defaults, showError) import Evaluator (eval) -import Parser (Expr (..), parseLispValue) +import Parser (parseLispValue) import System.Console.Readline import System.Environment (getArgs) import Text.ParserCombinators.Parsec @@ -29,7 +30,10 @@ repl env = do case inp of Nothing -> return () Just ",q" -> return () - Just i -> evalExpr env i >>= either (putStrLn . pp i) putStrLn >> repl env + Just i -> do + addHistory i + evalExpr env i >>= either (putStrLn . pp i) putStrLn + repl env main :: IO () diff --git a/lisk.cabal b/lisk.cabal index 6c2bdd4..47e111b 100644 --- a/lisk.cabal +++ b/lisk.cabal @@ -24,6 +24,7 @@ library parsec == 3.*, mtl >= 2.1 exposed-modules: + Base, Parser, Evaluator, Operators, diff --git a/src/Environment.hs b/src/Environment.hs index 4c444b6..b7b7ee6 100644 --- a/src/Environment.hs +++ b/src/Environment.hs @@ -8,15 +8,13 @@ module Environment ( Env , IOResult ) where +import Base (Env (..), Expr (..)) import Control.Applicative ((<$>)) import Control.Monad (mapM) import Control.Monad.Except import Data.IORef import Data.Maybe (isJust) import Error.Base (LispError (..), LispResult (..), unwrap) -import Parser (Expr (..)) - -type Env = IORef [(String, IORef Expr)] newEnv :: IO Env newEnv = newIORef [] diff --git a/src/Error/Base.hs b/src/Error/Base.hs index 747904a..008a2fc 100644 --- a/src/Error/Base.hs +++ b/src/Error/Base.hs @@ -3,8 +3,8 @@ module Error.Base ( LispError (..) , unwrap ) where +import Base (Expr (..)) import Control.Monad.Except -import Parser import Text.Parsec import Text.Parsec.Error import Text.ParserCombinators.Parsec diff --git a/src/Evaluator.hs b/src/Evaluator.hs index 9e6632e..3bc1e09 100644 --- a/src/Evaluator.hs +++ b/src/Evaluator.hs @@ -1,5 +1,6 @@ module Evaluator (eval) where +import Base import Control.Applicative ((*>)) import Control.Arrow ((&&&)) import Control.Monad.Except @@ -7,7 +8,6 @@ import Environment import Error.Base (LispError (..), LispResult (..), unwrap) import Operators -import Parser import Text.ParserCombinators.Parsec apply :: String -> [Expr] -> LispResult Expr @@ -20,6 +20,7 @@ evalUnquoteSplicing :: Env -> Expr -> IOResult Expr evalUnquoteSplicing env (List xs) = List <$> mapM (eval env) xs evalUnquoteSplicing env literal = return literal +-- might be worth including unquote and unquote-splicing in lisk's prelude evalUnquote :: Env -> Expr -> IOResult Expr evalUnquote env (DottedList h t) = List . (:[]) <$> liftM2 DottedList (mapM (evalUnquote env) h) (evalUnquote env t) evalUnquote env (Vector vs) = List . (:[]) . Vector <$> mapM (evalUnquote env) vs diff --git a/src/Operators.hs b/src/Operators.hs index fa39e23..bab888d 100644 --- a/src/Operators.hs +++ b/src/Operators.hs @@ -1,8 +1,8 @@ module Operators (primitives) where +import Base import Control.Monad.Except import Error.Base (LispError (..), LispResult (..)) -import Parser primitives :: [(String, [Expr] -> LispResult Expr)] primitives = map (\(n, f) -> (n, f n)) diff --git a/src/Parser.hs b/src/Parser.hs index f83f4cc..94de680 100644 --- a/src/Parser.hs +++ b/src/Parser.hs @@ -1,5 +1,4 @@ module Parser ( parseLispValue - , Expr(..) , parseString , parseInt , parseFloat @@ -7,22 +6,10 @@ module Parser ( parseLispValue , parseQuote ) where +import Base (Expr (..), Function) import Control.Applicative ((<$>)) import Text.ParserCombinators.Parsec --- TODO: use LispNumber (src/Operators.hs) here instead of IntLiteral and FloatLiteral --- TODO: add character literals: \#a \#b \#c \#space \#newline --- TODO: add support for complex numbers, oct and hex numbers -data Expr = List [Expr] - | Vector [Expr] - | DottedList [Expr] Expr - | StringLiteral String - | IntLiteral Integer - | FloatLiteral Double - | BoolLiteral Bool - | Id String - deriving (Eq) - -- backslash double quote escapes a quote inside strings quotedChar = noneOf ['\"'] <|> try (string "\\\"" >> return '"') @@ -92,7 +79,6 @@ parseQuote = parseModifier "'" "quote" parseQuasiquote = parseModifier "`" "quasiquote" parseUnquote = parseModifier "," "unquote" parseUnquoteSplicing = parseModifier ",@" "unquote-splicing" --- TODO: add modifier for unquote splicing: ,@ parseLispValue :: Parser Expr parseLispValue = @@ -114,16 +100,3 @@ parseLispValue = return $ maybe (List x) (DottedList x) t "lisp value" -showLispList :: [Expr] -> String -showLispList = unwords . map show - -instance Show Expr where - show (DottedList xs x) = "(" ++ showLispList xs ++ " . " ++ show x ++ ")" - show (List xs) = "(" ++ showLispList xs ++ ")" - show (Vector xs) = "#(" ++ showLispList xs ++ ")" - show (StringLiteral s) = "\"" ++ s ++ "\"" - show (IntLiteral n) = show n - show (FloatLiteral n) = show n - show (BoolLiteral True) = "#t" - show (BoolLiteral False) = "#f" - show (Id i) = i -- cgit v1.2.3