mirror of
https://github.com/zoriya/HAL.git
synced 2025-12-06 06:36:09 +00:00
Handling arguments
This commit is contained in:
46
app/Main.hs
46
app/Main.hs
@@ -7,9 +7,12 @@ import LispParser
|
||||
import Evaluator
|
||||
import LispEnv
|
||||
import Expressions
|
||||
import System.Environment (getArgs)
|
||||
import System.Exit (exitSuccess, exitFailure, exitWith, ExitCode (ExitFailure))
|
||||
import Control.Exception (IOException, catch)
|
||||
|
||||
main :: IO ()
|
||||
main = runInputT defaultSettings (loop defaultEnv)
|
||||
runRepl :: LispEnv -> IO ()
|
||||
runRepl env = runInputT defaultSettings (loop env)
|
||||
where
|
||||
loop :: LispEnv -> InputT IO ()
|
||||
loop env = do
|
||||
@@ -30,3 +33,42 @@ main = runInputT defaultSettings (loop defaultEnv)
|
||||
(Left err) -> outputStrLn err >> return env
|
||||
(_, lo) -> outputStrLn ("**Error: Invalid syntax near: " ++ lo ++ "**")
|
||||
>> return env
|
||||
|
||||
evalFiles :: [String] -> LispEnv -> Either String (Atom, LispEnv)
|
||||
evalFiles [x] env = evalFile x env
|
||||
evalFiles (x:xs) env = do
|
||||
(ret, nEnv) <- evalFile x env
|
||||
evalFiles xs nEnv
|
||||
evalFiles [] env = undefined
|
||||
|
||||
evalFile :: String -> LispEnv -> Either String (Atom, LispEnv)
|
||||
evalFile file env =
|
||||
case parse pLisp file of
|
||||
(Just statements, []) -> evalStatements statements env
|
||||
(_, lo) -> Left $ "**Parse error near " ++ lo ++ "**"
|
||||
|
||||
evalStatements :: [Statement] -> LispEnv -> Either String (Atom, LispEnv)
|
||||
evalStatements [x] env = eval x env
|
||||
evalStatements (x:xs) env = do
|
||||
(ret, nEnv) <- eval x env
|
||||
evalStatements xs nEnv
|
||||
evalStatements [] env = Right (ANothing, env)
|
||||
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
(args, repl) <- parseArgs <$> getArgs
|
||||
files <- catch (sequence $ readFile <$> args) handler
|
||||
case evalFiles files defaultEnv of
|
||||
Right (ret, env) -> if repl then runRepl env else print ret
|
||||
Left err -> putStrLn err >> exitWith (ExitFailure 84)
|
||||
where
|
||||
handler :: IOException -> IO [String]
|
||||
handler e = putStrLn ("Error: " ++ show e) >> exitWith (ExitFailure 84)
|
||||
|
||||
parseArgs :: [String] -> ([String], Bool)
|
||||
parseArgs ("-i":xs) = let (files, _) = parseArgs xs
|
||||
in (files, True)
|
||||
parseArgs (x:xs) = let (files, repl) = parseArgs xs
|
||||
in (x:files, repl)
|
||||
parseArgs [] = ([], False)
|
||||
3
example/fact.lisp
Normal file
3
example/fact.lisp
Normal file
@@ -0,0 +1,3 @@
|
||||
(define (fact x)
|
||||
(cond ((eq? x 1) 1)
|
||||
(#t (* x (fact (- x 1))))))
|
||||
@@ -3,7 +3,7 @@ module LispParser where
|
||||
import BasicParser
|
||||
( Parser, pCharIf, pUntil, pInt, pFloat, tokenify, pToken, pString )
|
||||
import Expressions ( SExpr(..), Atom(..), Statement(..) )
|
||||
import Control.Applicative ( Alternative(some, (<|>)) )
|
||||
import Control.Applicative ( Alternative(some, many, (<|>)) )
|
||||
|
||||
_pAtom :: Parser Atom
|
||||
_pAtom = AInt <$> pInt
|
||||
@@ -64,4 +64,4 @@ pStatement = pCharIf (== '(')
|
||||
<|> Atom <$> pAtom
|
||||
|
||||
pLisp :: Parser [Statement]
|
||||
pLisp = some $ tokenify pStatement
|
||||
pLisp = many $ tokenify pStatement
|
||||
|
||||
@@ -51,7 +51,7 @@ evalMult [] env = Right (AInt 1, env)
|
||||
evalDiv :: [Statement] -> LispEnv -> Either String (Atom, LispEnv)
|
||||
evalDiv [_, Atom (AInt 0)] env = Left "**Error: Division by 0 is undefined.**"
|
||||
evalDiv [_, Atom (AFloat 0)] env = Left "**Error: Division by 0 is undefined.**"
|
||||
evalDiv [Atom (AInt f), Atom (AInt s)] env = Right (AInt (f `div` s), env)
|
||||
evalDiv [Atom (AInt f), Atom (AInt s)] env = Right (AInt (f `quot` s), env)
|
||||
evalDiv [Atom (AFloat f), Atom (AFloat s)] env = Right (AFloat (f / s), env)
|
||||
evalDiv [Atom (AFloat f), Atom (AInt s)] env = Right (AFloat (f / fromIntegral s), env)
|
||||
evalDiv [Atom (AInt f), Atom (AFloat s)] env = Right (AFloat (fromIntegral f / s), env)
|
||||
|
||||
Reference in New Issue
Block a user