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

feature(call compiler): link parsing -> ast -> optimizing ast -> comp… #54

Merged
merged 5 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
53 changes: 31 additions & 22 deletions LobsterLang/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ import System.IO (isEOF)
import System.Exit (exitWith, ExitCode (ExitFailure))
import System.Environment (getArgs)
import qualified AstEval
import qualified AstOptimizer
import qualified Compiler
import Control.Exception
import qualified AST
-- import Compiler
import AstOptimizer (optimizeAst)


lobsterNotHappy :: String -> String -> String -> String
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)
interpretateLisp :: AST.Ast -> [Scope.ScopeMb] -> Either String (Maybe AST.Ast, [Scope.ScopeMb])
interpretateLisp value stack = case AstEval.evalAst stack value of
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')

Expand All @@ -29,40 +35,43 @@ 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 ("\ESC[34m\ESC[1mThe lobster is angry: " ++ err ++ "\ESC[0m") >> inputLoop stack
Left err -> putStrLn (lobsterNotHappy "34" "angry" err) >> inputLoop stack
Right (res, [], _) -> interpretateInfo res stack
Right (_, _, pos) -> putStrLn ("\ESC[34m\ESC[1mThe lobster is angry: " ++ errorParsing pos ++ "\ESC[0m") >> 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 interpretateLisp x stack of
Left err -> putStrLn ("\ESC[31m\ESC[1mThe lobster is angry: " ++ err ++ "\ESC[0m") >> 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'

compileInfo :: [AST.Ast] -> [Scope.ScopeMb] -> IO ()
compileInfo [] _ = putStr ""
compileInfo (x:xs) stack = case interpretateLisp x stack of
Left err -> putStrLn ("\ESC[31m\ESC[1mThe lobster is angry: " ++ err ++ "\ESC[0m") >> exitWith (ExitFailure 84)
Right (res, stack') -> case res of
Nothing -> compileInfo xs stack'
Just value -> print value >> compileInfo xs stack'
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])

compileFile :: String -> IO ()
compileFile s = case runParser parseLobster (0, 0) s of
Left err -> print err >> exitWith (ExitFailure 84)
Right (res, [], _) -> print res >> compileInfo res []
Right (_, _, (row, col)) -> print ("Error on parsing on '" ++ show row ++ "' '" ++ show col)
-- (Right (Just res), stack') -> let instructions = (astToInstructions (AST.Cond (Boolean True) (Value 1) (Just (AST.Call "CallHere" [(Value 0)])))) in showInstructions instructions >> writeCompiledInstructionsToFile "output" (compileInstructions instructions)
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

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))

checkArgs :: [String] -> IO ()
checkArgs [] = print "Launch Interpreter" >> inputLoop []
checkArgs (file:_) = either
(\_ -> print "File doesn't exist" >> exitWith (ExitFailure 84))
compileFile
=<< (try (readFile file) :: IO (Either SomeException String))
(compileFile file)
=<< (try (readFile file) :: IO (Either SomeException String))

-- | Main
main :: IO ()
Expand Down
8 changes: 7 additions & 1 deletion LobsterLang/src/AstOptimizer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

module AstOptimizer
( optimizeAst,
fromOptimised,
AstError (..),
AstOptimised (..),
)
Expand Down Expand Up @@ -55,7 +56,12 @@ optimizeAst stack ((Define n ast) : xs) inFunc = case optimizeAst stack [ast] in
| inFunc -> Right (Result (Define n opAst)) : optimizeAst stack xs inFunc
| otherwise -> Left (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') (Define n opAst)) : optimizeAst stack xs inFunc
(Left err, _) -> Left (Error err (Define n opAst)) : optimizeAst stack xs inFunc
[Right (Warning mes opAst)] -> Right (Warning mes (Define n opAst)) : optimizeAst stack xs inFunc
[Right (Warning mes opAst)] -> case evalAst stack (Define n opAst) of
(Right _, stack') -> Right (Warning mes (Define n opAst)) : optimizeAst stack' xs inFunc
(Left ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs'), _)
AxelHumeau marked this conversation as resolved.
Show resolved Hide resolved
| inFunc -> Right (Result (Define n opAst)) : optimizeAst stack xs inFunc
| otherwise -> Left (Error ('S' : 'y' : 'm' : 'b' : 'o' : 'l' : ' ' : '\'' : xs') (Define n opAst)) : optimizeAst stack xs inFunc
(Left err, _) -> Left (Error err (Define n opAst)) : optimizeAst stack xs inFunc
_ -> shouldntHappen stack (Define n ast : xs) inFunc
optimizeAst stack ((Symbol s Nothing) : xs) inFunc
| inFunc = Right (Result (Symbol s Nothing)) : optimizeAst stack xs inFunc
Expand Down
2 changes: 1 addition & 1 deletion LobsterLang/test/AstOptimizerSpec.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-

Check warning on line 1 in LobsterLang/test/AstOptimizerSpec.hs

View workflow job for this annotation

GitHub Actions / run_tests

The export item ‘module AstOptimizerSpec’ is missing an export list
-- EPITECH PROJECT, 2024
-- GLaDOS
-- File description:
Expand Down Expand Up @@ -162,4 +162,4 @@
it "Infinite recursion" $ do
optimizeAst [Variable "eh" (FunctionValue ["x"] (Symbol "eh" (Just [Symbol "x" Nothing])) Nothing) 0] [Symbol "eh" (Just [AST.Value 1])] False `shouldBe` [Right (Warning "Possible infinite recursion" (Symbol "eh" (Just [AST.Value 1])))]
it "Infinite recursion in define" $ do
optimizeAst [Variable "eh" (FunctionValue ["x"] (Symbol "eh" (Just [Symbol "x" Nothing])) Nothing) 0] [Define "a" (Symbol "eh" (Just [AST.Value 1]))] False `shouldBe` [Right (Warning "Possible infinite recursion" (Define "a" (Symbol "eh" (Just [AST.Value 1]))))]
optimizeAst [Variable "eh" (FunctionValue ["x"] (Symbol "eh" (Just [Symbol "x" Nothing])) Nothing) 0] [Define "a" (Symbol "eh" (Just [AST.Value 1]))] False `shouldBe` [Left (Error "Recursion limit reached" (Define "a" (Symbol "eh" (Just [Value 1]))))]
AxelHumeau marked this conversation as resolved.
Show resolved Hide resolved
127 changes: 0 additions & 127 deletions ParseSpec.hs

This file was deleted.

10 changes: 5 additions & 5 deletions exemple/Factorial.lob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fn factorial(| x |) {
if x == 0 {
fn factorial(| x |) {|
if x == 0 {|
1
} else {
|} else {|
x * factorial(| x - 1 |)
}
}
|}
|}
12 changes: 6 additions & 6 deletions exemple/Fibonacci.lob
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
fn fibonacci(| x |) {
if x == 0 {
fn fibonacci(| x |) {|
if true {|
0
} else if x == 1 {
|} else if x == 1 {|
1
} else {
|} else {|
fibonacci(| x - 1 |) + fibonacci(| x - 2 |)
}
}
|}
|}
14 changes: 7 additions & 7 deletions exemple/Lambda.lob
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
sqrt = λ (| x |) { x * x }
sqrt = λ (| x |) {| x * x |}

add = λ (| a, b |) { a + b }
add = λ (| a, b |) {| a + b |}

sqrt(| 5 |)

add(| 2, 9 |)

abs = λ (| x |) {
if x < 0 {
abs = λ (| x |) {|
if x < 0 {|
x * -1
} else {
|} else {|
x
}
}
|}
|}

abs(| -543 |)
4 changes: 2 additions & 2 deletions exemple/Neg.lob
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn neg(| x |) {
fn neg(| x |) {|
0 - x
}
|}
10 changes: 5 additions & 5 deletions exemple/Power.lob
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
fn power(| a, pow |) {
if pow == 0 {
fn power(| a, pow |) {|
if pow == 0 {|
1
} else {
|} else {|
a * power(| a, pow - 1 |)
}
}
|}
|}

power(| 5, 5 |)
10 changes: 5 additions & 5 deletions exemple/RangeToStr.lob
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
fn rangeToStr(| a, b |) {
if a >= b {
fn rangeToStr(| a, b |) {|
if a >= b {|
@ b
} else {
|} else {|
@ a + rangeToStr(| a + 1, b |)
}
}
|}
|}
Loading