Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean code #60

Merged
merged 16 commits into from
Feb 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 82 additions & 46 deletions LobsterLang/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,82 +7,118 @@

module Main (main) where

import Parse
import Scope
import System.IO (isEOF)
import System.Exit (exitWith, ExitCode (ExitFailure))
import System.Environment (getArgs)
import qualified AST
import qualified AstEval
import AstOptimizer (optimizeAst)
import qualified AstOptimizer
import qualified Compiler
import qualified CompiletoVm
import Control.Exception
import qualified AST
import AstOptimizer (optimizeAst)
import Parse
import Scope
import System.Environment (getArgs)
import System.Exit (ExitCode (ExitFailure), exitWith)
import System.IO (isEOF)
import Vm

lobsterNotHappy :: String -> String -> String -> String
lobsterNotHappy color state str = "\ESC[" ++ color ++ "m\ESC[1mThe lobster is " ++ state ++ ": " ++ str ++ "\ESC[0m"
lobsterNotHappy color state str =
"\ESC["
++ color
++ "m\ESC[1mThe lobster is "
++ state
++ ": "
++ str
++ "\ESC[0m"

-- | Return a Result that contain the evaluation of our Lisp String
-- Takes as parameter the string that need to be evaluated and the Stack (Environment)
interpretateLobster :: AST.Ast -> [Scope.ScopeMb] -> Either String (Maybe AST.Ast, [Scope.ScopeMb])
-- Takes as parameter the string that need to be evaluated
-- and the Stack (Environment)
interpretateLobster ::
AST.Ast ->
[Scope.ScopeMb] ->
Either String (Maybe AST.Ast, [Scope.ScopeMb])
interpretateLobster value stack = case AstEval.evalAst stack value of
(Left err, _) -> Left err
(Right res', stack') -> Right (res', stack')
(Left err, _) -> Left err
(Right res', stack') -> Right (res', stack')

-- | Infinite loop until EOF from the user
inputLoop :: [Scope.ScopeMb] -> IO ()
-- inputLoop = print
inputLoop stack = isEOF >>= \end -> if end then print "End of Interpretation GLaDOS" else
getLine >>= \line -> case runParser parseLobster (0, 0) line of
Left err -> putStrLn (lobsterNotHappy "34" "angry" err) >> inputLoop stack
inputLoop stack =
isEOF >>= \end ->
if end then print "End of Interpretation GLaDOS" else
getLine >>= \line -> case runParser parseLobster (0, 0) line of
Left err ->
putStrLn (lobsterNotHappy "34" "angry" err) >> inputLoop stack
Right (res, [], _) -> interpretateInfo res stack
Right (_, _, pos) -> putStrLn (lobsterNotHappy "31" "angry" (errorParsing pos)) >> inputLoop stack
Right (_, _, pos) ->
putStrLn (lobsterNotHappy "31" "angry"
(errorParsing pos)) >> inputLoop stack

interpretateInfo :: [AST.Ast] -> [Scope.ScopeMb] -> IO ()
interpretateInfo [] stack = inputLoop stack
interpretateInfo (x:xs) stack = case interpretateLobster x stack of
Left err -> putStrLn (lobsterNotHappy "31" "angry" err) >> inputLoop stack
Right (res, stack') -> case res of
Nothing -> interpretateInfo xs stack'
Just value -> print value >> interpretateInfo xs stack'
interpretateInfo (x : xs) stack = case interpretateLobster x stack of
Left err ->
putStrLn (lobsterNotHappy "31" "angry" err)
>> inputLoop stack
Right (res, stack') -> case res of
Nothing -> interpretateInfo xs stack'
Just value -> print value >> interpretateInfo xs stack'

checkCompileInfo :: [Either AstOptimizer.AstError AstOptimizer.AstOptimised] -> [Either AstOptimizer.AstError AstOptimizer.AstOptimised] -> IO [Either AstOptimizer.AstError AstOptimizer.AstOptimised]
checkCompileInfo ::
[Either AstOptimizer.AstError AstOptimizer.AstOptimised] ->
[Either AstOptimizer.AstError AstOptimizer.AstOptimised] ->
IO [Either AstOptimizer.AstError AstOptimizer.AstOptimised]
checkCompileInfo [] list = return list
checkCompileInfo (x:xs) list = case x of
Left (AstOptimizer.Error err ast) -> putStrLn (lobsterNotHappy "31" "angry" (err ++ " caused by: " ++ show ast)) >> checkCompileInfo xs (list ++ [x])
Right (AstOptimizer.Result _) -> checkCompileInfo xs (list ++ [x])
Right (AstOptimizer.Warning warning ast) -> putStrLn (lobsterNotHappy "33" "worried" (warning ++ " optimize to" ++ show ast)) >> checkCompileInfo xs (list ++ [x])
checkCompileInfo (x : xs) list = case x of
Left (AstOptimizer.Error err ast) ->
putStrLn
(lobsterNotHappy "31" "angry" (err ++ " caused by: " ++ show ast))
>> checkCompileInfo xs (list ++ [x])
Right (AstOptimizer.Result _) -> checkCompileInfo xs (list ++ [x])
Right (AstOptimizer.Warning warning ast) ->
putStrLn
(lobsterNotHappy "33" "worried" (warning ++ " optimize to" ++ show ast))
>> checkCompileInfo xs (list ++ [x])

compileInfo :: String -> [AST.Ast] -> [Scope.ScopeMb] -> IO ()
compileInfo _ [] _ = putStr ""
compileInfo filename list stack = checkCompileInfo (optimizeAst stack list False) [] >>= \res -> case sequence res of
Left _ -> exitWith (ExitFailure 84)
Right value -> Compiler.compile (map AstOptimizer.fromOptimised value) (filename ++ "o") True
compileInfo filename list stack = checkCompileInfo
(optimizeAst stack list False) [] >>= \res ->
case sequence res of
Left _ -> exitWith (ExitFailure 84)
Right value ->
Compiler.compile
(map AstOptimizer.fromOpti value)
(filename ++ "o")
True

compileFile :: String -> String -> IO ()
compileFile file s = case runParser parseLobster (0, 0) s of
Left err -> print err >> exitWith (ExitFailure 84)
Right (res, [], _) -> compileInfo file res []
Right (_, _, pos) -> putStrLn (lobsterNotHappy "34" "angry" (errorParsing pos))
Left err -> print err >> exitWith (ExitFailure 84)
Right (res, [], _) -> compileInfo file res []
Right (_, _, pos) ->
putStrLn
(lobsterNotHappy "34" "angry" (errorParsing pos))

checkArgs :: [String] -> IO ()
checkArgs [] = print "Launch Interpreter" >> inputLoop []
checkArgs ("-e":file:_) = putStr "Result: " >> CompiletoVm.makeConvert file
>>= \instructions -> case fst (Vm.exec 0 [] [] instructions []) of
Left err -> print err
Right (IntVal res) -> print res
Right (BoolVal res) -> print res
Right (CharVal res) -> print res
Right (StringVal res) -> print res
Right (ListVal res) -> print res
Right (Op res) -> print res
Right (Function res _) -> print res
checkArgs (file:_) = either
(\_ -> print "File doesn't exist" >> exitWith (ExitFailure 84))
(compileFile file)
=<< (try (readFile file) :: IO (Either SomeException String))
checkArgs ("-e" : file : _) = putStr "Result: " >> CompiletoVm.makeConvert file
>>= \instructions -> case fst (Vm.exec 0 [] [] instructions []) of
Left err -> print err
Right (IntVal res) -> print res
Right (BoolVal res) -> print res
Right (CharVal res) -> print res
Right (StringVal res) -> print res
Right (ListVal res) -> print res
Right (Op res) -> print res
Right (Function res _) -> print res
checkArgs (file : _) =
either
(\_ -> print "File doesn't exist" >> exitWith (ExitFailure 84))
(compileFile file)
=<< (try (readFile file) :: IO (Either SomeException String))

-- | Main
main :: IO ()
Expand Down
Binary file removed LobsterLang/fnv
Binary file not shown.
Loading
Loading