diff --git a/lvtc/app/Main.hs b/lvtc/app/Main.hs index 97f8458..41f8713 100644 --- a/lvtc/app/Main.hs +++ b/lvtc/app/Main.hs @@ -7,11 +7,16 @@ module Main (main) where -import Expression -import Parser +import Expression (parseAllExpression) +import Parser (runParser) +import Alias (proceedAlias) + +text :: String +text = aliasInt ++ aliasRetValue ++ funcMain + where + aliasInt = "alias int Int;\n" + aliasRetValue = "alias retValue 0;\n" + funcMain = "fn main () -> int \n{\n <- retValue;\n};\n" main :: IO () -main = print $ runParser (parseExpresion) - "fn main () -> Int \n{\n <- 0;\n};\n" --- main = print $ runParser (parseExpresion) "alias abc def;\n" --- main = print $ runParser (parseExpresion) "// this is a comment\n" +main = print $ runParser (proceedAlias <$> parseAllExpression) text diff --git a/lvtc/lvtc.cabal b/lvtc/lvtc.cabal index 2f3ff1c..76130c0 100644 --- a/lvtc/lvtc.cabal +++ b/lvtc/lvtc.cabal @@ -25,6 +25,7 @@ source-repository head library exposed-modules: + Alias Expression Lib Parser diff --git a/lvtc/src/Alias.hs b/lvtc/src/Alias.hs new file mode 100644 index 0000000..fafd5f2 --- /dev/null +++ b/lvtc/src/Alias.hs @@ -0,0 +1,80 @@ +{- +-- EPITECH PROJECT, 2023 +-- Leviator compiler +-- File description: +-- Alias +-} + +module Alias ( + proceedAlias, +) where + +import Expression +import Parser +import ParseUtil +import Control.Applicative + +data Alias = Alias String String + +instance Show Alias.Alias where + show (Alias.Alias str1 str2) = "ALIAS `" ++ str1 ++ "`:`" ++ str2 ++ "`" + +parseAliasKeyword :: Parser String +parseAliasKeyword = parseString "alias " + +parseAliasName :: Parser String +parseAliasName = parseAllCharUntil " " + +parseAliasValue :: Parser String +parseAliasValue = parseAllCharUntil ";\n" + +parseAlias' :: Parser String +parseAlias' = (parseAliasKeyword *> parseAliasName <* many (parseChar ' ')) + +parseAlias :: Parser Alias.Alias +parseAlias = Parser f + where + f str = case runParser parseAlias' str of + Nothing -> Nothing + Just (key, xs) -> case runParser parseAliasValue xs of + Nothing -> Nothing + Just (value, ys) -> Just (Alias.Alias key value, ys) + +replaceAliasInString :: Alias.Alias -> String -> String +replaceAliasInString _ [] = [] +replaceAliasInString (Alias.Alias key value) (x:xs) + | take (length key) (x:xs) == key = + value ++ replaceAliasInString + (Alias.Alias key value) + (drop (length key) (x:xs)) + | otherwise = x : replaceAliasInString (Alias.Alias key value) xs + +replaceAlias :: Alias -> [Expression] -> [Expression] +replaceAlias _ [] = [] +replaceAlias alias ((Expression.Alias _):xs) = + replaceAlias alias xs +replaceAlias (Alias.Alias key value) ((Expression.Function str):xs) = + (Expression.Function (replaceAliasInString (Alias.Alias key value) str)) + : (replaceAlias (Alias.Alias key value) xs) +replaceAlias (Alias.Alias key value) ((Expression.Comment str):xs) = + (Expression.Comment (replaceAliasInString (Alias.Alias key value) str)) + : (replaceAlias (Alias.Alias key value) xs) + +replaceAllAlias :: [Alias] -> [Expression] -> [Expression] +replaceAllAlias [] exprs = exprs +replaceAllAlias _ [] = [] +replaceAllAlias (x:xs) exprs = replaceAllAlias xs newExprs + where + newExprs = replaceAlias x exprs + +getListAlias :: [Expression] -> [Alias] +getListAlias [] = [] +getListAlias ((Expression.Alias str):xs) = case runParser parseAlias str of + Just (alias, _) -> alias : getListAlias xs + Nothing -> getListAlias xs +getListAlias (_:xs) = getListAlias xs + +proceedAlias :: [Expression] -> [Expression] +proceedAlias exprs = replaceAllAlias lstAlias exprs + where + lstAlias = getListAlias exprs diff --git a/lvtc/src/Expression.hs b/lvtc/src/Expression.hs index db13e4e..370c4c4 100644 --- a/lvtc/src/Expression.hs +++ b/lvtc/src/Expression.hs @@ -39,7 +39,7 @@ countBracketsForFunction n ('\\':_:xs) = countBracketsForFunction n xs countBracketsForFunction n (_:xs) = countBracketsForFunction n xs parseFunction' :: Parser Expression -parseFunction' = Function <$> ((++) <$> +parseFunction' = (\x -> Function (x ++ "\n};\n")) <$> ((++) <$> (parseString "fn " <|> parseString "export fn") <*> parseAllCharUntil "\n};\n") @@ -55,11 +55,13 @@ parseFunction = Parser f parseAlias :: Parser Expression parseAlias = - Alias <$> ((++) <$> parseString "alias " <*> parseAllCharUntil ";\n") + (\x -> Alias (x ++ ";\n")) <$> + ((++) <$> parseString "alias " <*> parseAllCharUntil ";\n") parseComment :: Parser Expression parseComment = - Comment <$> ((++) <$> parseString "//" <*> parseAllCharUntil "\n") + (\x -> Comment (x ++ "\n")) <$> + ((++) <$> parseString "//" <*> parseAllCharUntil "\n") parseExpresion :: Parser Expression parseExpresion = parseAlias <|> parseFunction <|> parseComment diff --git a/lvtc/src/ParseUtil.hs b/lvtc/src/ParseUtil.hs index 11c2a40..20f020c 100644 --- a/lvtc/src/ParseUtil.hs +++ b/lvtc/src/ParseUtil.hs @@ -70,4 +70,4 @@ parseAllCharUntil str = Parser f f [] = empty f (x:xs) = case runParser (parseString str) (x:xs) of Nothing -> runParser ((x :) <$> parseAllCharUntil str) xs - Just (y, ys) -> Just (y, ys) + Just (_, ys) -> Just ([], ys) diff --git a/lvtc/test/Spec.hs b/lvtc/test/Spec.hs index 4b717e0..4c9879c 100644 --- a/lvtc/test/Spec.hs +++ b/lvtc/test/Spec.hs @@ -10,6 +10,7 @@ import Test.Tasty.HUnit import Expression import Parser +import Alias main :: IO () main = defaultMain tests @@ -18,7 +19,8 @@ tests :: TestTree tests = testGroup "Leviator Tests - Compiler" [ utParserExpression, - utParserExpressions + utParserExpressions, + utAlias ] testParserHelper :: String -> String -> Expression -> IO () @@ -61,7 +63,7 @@ utParserExpression = testGroup "Parse Expression" testParserHelper "alias abc def;\n" "" - (Alias "alias abc def;\n") + (Expression.Alias "alias abc def;\n") , testCase "alias bad formated (no end `\\n`)" $ testParserHelperFail "alias abc def;" @@ -125,16 +127,42 @@ utParserExpressions = testGroup "Parse Expressions" testParserHelpers "alias abc def;\nalias def def;\n" "" - [Alias "alias abc def;\n", Alias "alias def def;\n"] + [Expression.Alias "alias abc def;\n", Expression.Alias "alias def def;\n"] , testCase "alias multiline" $ testParserHelpers "alias abc def\nefg hij;\n" "" - [Alias "alias abc def\nefg hij;\n"] + [Expression.Alias "alias abc def\nefg hij;\n"] -- comment , testCase "comment" $ testParserHelpers "// this is a comment\nalias abc def;\n" "" - [Comment "// this is a comment\n", Alias "alias abc def;\n"] + [Comment "// this is a comment\n", Expression.Alias "alias abc def;\n"] + ] + +utAlias :: TestTree +utAlias = testGroup "Alias" + [ + testCase "alias" $ + assertEqual "alias" + [ + Expression.Function "fn main() -> Int \n{\n <- 0;\n};" + ] + (proceedAlias [ + Expression.Alias "alias int Int;\n", + Expression.Alias "alias retValue 0;\n", + Expression.Function "fn main() -> int \n{\n <- retValue;\n};" + ]) + , testCase "nested alias" $ + assertEqual "alias nested" + [ + Expression.Function "fn main() -> Int \n{\n <- 0;\n};" + ] + (proceedAlias [ + Expression.Alias "alias int INT;\n", + Expression.Alias "alias retValue 0;\n", + Expression.Alias "alias INT Int;\n", + Expression.Function "fn main() -> int \n{\n <- retValue;\n};" + ]) ]