Skip to content

Commit

Permalink
Add lexeme
Browse files Browse the repository at this point in the history
  • Loading branch information
Saverio976 committed Jan 14, 2024
1 parent e62a710 commit 5587c49
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 56 deletions.
2 changes: 2 additions & 0 deletions lvtc/lvtc.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ library
Builtins
Expression
Leb128Encode
Lexeme
Lib
LvtLibVersion
ParseLvt
Expand Down Expand Up @@ -78,6 +79,7 @@ test-suite lvtc-test
type: exitcode-stdio-1.0
main-is: Spec.hs
other-modules:
UTLexeme
UTParseLvt
UTShuntingYard
UTWasm
Expand Down
80 changes: 80 additions & 0 deletions lvtc/src/Lexeme.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{-
-- EPITECH PROJECT, 2023
-- Leviator compiler
-- File description:
-- ParseLvt
-}

module Lexeme
(
lexeme1
) where

replaceN :: Int -> String -> String
replaceN _ [] = []
replaceN 0 ('"':xs) = '"' : replaceN 1 xs
replaceN 1 ('\\':'n':xs) = '\n' : replaceN 1 xs
replaceN 1 ('\\':'t':xs) = '\t' : replaceN 1 xs
replaceN 1 ('\\':'v':xs) = '\v' : replaceN 1 xs
replaceN 1 ('\\':'a':xs) = '\a' : replaceN 1 xs
replaceN 1 ('\\':'f':xs) = '\f' : replaceN 1 xs
replaceN 1 ('\\':'r':xs) = '\r' : replaceN 1 xs
replaceN 1 ('\\':x:xs) = '\\':x : replaceN 1 xs
replaceN 1 ('"':xs) = '"' : replaceN 0 xs
replaceN 0 ('\n':xs) = ' ' : replaceN 0 xs
replaceN n (x:xs) = x : replaceN n xs

lexeme :: Int -> String -> String
lexeme _ [] = []
lexeme 0 (' ':')':xs) = lexeme 0 (')':xs)
lexeme 0 (' ':'(':xs) = lexeme 0 ('(':xs)
lexeme 0 (' ':'}':xs) = lexeme 0 ('}':xs)
lexeme 0 (' ':'{':xs) = lexeme 0 ('{':xs)
lexeme 0 (' ':']':xs) = lexeme 0 (']':xs)
lexeme 0 (' ':'[':xs) = lexeme 0 ('[':xs)
lexeme 0 (' ':'+':xs) = lexeme 0 ('+':xs)
lexeme 0 (' ':'-':xs) = lexeme 0 ('-':xs)
lexeme 0 (' ':'*':xs) = lexeme 0 ('*':xs)
lexeme 0 (' ':'/':xs) = lexeme 0 ('/':xs)
lexeme 0 (' ':'<':xs) = lexeme 0 ('<':xs)
lexeme 0 (' ':'>':xs) = lexeme 0 ('>':xs)
lexeme 0 (' ':'=':xs) = lexeme 0 ('=':xs)
lexeme 0 (' ':'!':xs) = lexeme 0 ('!':xs)
lexeme 0 (' ':':':xs) = lexeme 0 (':':xs)
lexeme 0 (' ':',':xs) = lexeme 0 (',':xs)
lexeme 0 (' ':'@':xs) = lexeme 0 ('@':xs)
lexeme 0 (' ':';':xs) = lexeme 0 (';':xs)
lexeme 0 ('(':' ':xs) = lexeme 0 ('(':xs)
lexeme 0 (')':' ':xs) = lexeme 0 (')':xs)
lexeme 0 ('}':' ':xs) = lexeme 0 ('}':xs)
lexeme 0 ('{':' ':xs) = lexeme 0 ('{':xs)
lexeme 0 (']':' ':xs) = lexeme 0 (']':xs)
lexeme 0 ('[':' ':xs) = lexeme 0 ('[':xs)
lexeme 0 ('+':' ':xs) = lexeme 0 ('+':xs)
lexeme 0 ('-':' ':xs) = lexeme 0 ('-':xs)
lexeme 0 ('*':' ':xs) = lexeme 0 ('*':xs)
lexeme 0 ('/':' ':xs) = lexeme 0 ('/':xs)
lexeme 0 ('<':' ':xs) = lexeme 0 ('<':xs)
lexeme 0 ('>':' ':xs) = lexeme 0 ('>':xs)
lexeme 0 ('=':' ':xs) = lexeme 0 ('=':xs)
lexeme 0 ('!':' ':xs) = lexeme 0 ('!':xs)
lexeme 0 (':':' ':xs) = lexeme 0 (':':xs)
lexeme 0 (',':' ':xs) = lexeme 0 (',':xs)
lexeme 0 ('@':' ':xs) = lexeme 0 ('@':xs)
lexeme 0 (';':' ':xs) = lexeme 0 (';':xs)
lexeme 0 ('i':'f':' ':xs) = lexeme 0 ('i':'f':xs)
lexeme 0 (' ':'i':'f':xs) = lexeme 0 ('i':'f':xs)
lexeme 0 ('e':'l':'s':'e':' ':xs) = lexeme 0 ('e':'l':'s':'e':xs)
lexeme 0 (' ':'e':'l':'s':'e':xs) = lexeme 0 ('e':'l':'s':'e':xs)
lexeme 0 ('\\':x:xs) = x : lexeme 0 xs
lexeme 1 ('\\':x:xs) = x : lexeme 1 xs
lexeme 0 (' ':' ':xs) = lexeme 0 (' ':xs)
lexeme 1 ('"':xs) = '"' : lexeme 0 xs
lexeme 0 ('"':xs) = '"' : lexeme 1 xs
lexeme n (x:xs) = x : lexeme n xs

stripLastSpaces :: String -> String
stripLastSpaces = reverse . dropWhile (== ' ') . reverse

lexeme1 :: String -> String
lexeme1 str = stripLastSpaces $ lexeme 0 (replaceN 0 str)
70 changes: 18 additions & 52 deletions lvtc/src/ParseLvt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,7 @@ import AST
import Parser
import ParseUtil
import ShuntingYard

lexeme :: String -> String
lexeme [] = []
lexeme (',':' ':xs) = lexeme (',':xs)
lexeme ('\n':' ':xs) = lexeme ('\n':xs)
lexeme ('e':'l':'s':'e':' ':xs) = lexeme ("else" ++ xs)
lexeme ('i':'f':' ':xs) = lexeme ("if" ++ xs)
lexeme (' ':'(':xs) = lexeme ("(" ++ xs)
lexeme (' ':')':xs) = lexeme (")" ++ xs)
lexeme (' ':'+':xs) = lexeme ("+" ++ xs)
lexeme (' ':'-':xs) = lexeme ("-" ++ xs)
lexeme (' ':'*':xs) = lexeme ("*" ++ xs)
lexeme (' ':'/':xs) = lexeme ("/" ++ xs)
lexeme ('+':' ':xs) = lexeme ("+" ++ xs)
lexeme ('-':' ':xs) = lexeme ("-" ++ xs)
lexeme ('*':' ':xs) = lexeme ("*" ++ xs)
lexeme ('/':' ':xs) = lexeme ("/" ++ xs)
lexeme ('(':' ':xs) = lexeme ("(" ++ xs)
lexeme (')':' ':xs) = lexeme (")" ++ xs)
lexeme (':':' ':xs) = lexeme (":" ++ xs)
lexeme (' ':':':xs) = lexeme (":" ++ xs)
lexeme (x:xs) = x : lexeme xs
import Lexeme

parseBoolean :: Parser Value
parseBoolean =
Expand Down Expand Up @@ -108,11 +87,7 @@ parseVoid = f <$> parseString "Void"
f _ = Void

parseOperatorFstVal :: Parser Value
parseOperatorFstVal = Parser f
where
f str = case runParser parseValueWithoutOperator str of
Nothing -> Nothing
Just (fstVal, xs) -> Just (fstVal, xs)
parseOperatorFstVal = parseValueWithoutOperator

parseOperatorOp :: Parser Value
parseOperatorOp =
Expand All @@ -133,9 +108,7 @@ parseOperator' sys =
parseOperatorTransformOne' :: [Value] -> Maybe [Value]
parseOperatorTransformOne' (x1:x2:(Var op):rest)
| isOperator op = Just (FuncValue (op, [x1, x2]) : rest)
| otherwise = case parseOperatorTransformOne rest of
Nothing -> Nothing
Just ys -> Just (x1:x2:ys)
| otherwise = (\ys -> x1:x2:ys) <$> parseOperatorTransformOne rest
parseOperatorTransformOne' _ = Nothing

parseOperatorTransformOne :: [Value] -> Maybe [Value]
Expand All @@ -147,9 +120,7 @@ parseOperatorTransformOne (x1:(Var op):rest)
| otherwise = parseOperatorTransformOne' (x1 : Var op : rest)
parseOperatorTransformOne (x1:x2:(Var op):rest) =
parseOperatorTransformOne' (x1 : x2 : Var op : rest)
parseOperatorTransformOne (x:xs) = case parseOperatorTransformOne xs of
Nothing -> Nothing
Just ys -> Just (x:ys)
parseOperatorTransformOne (x:xs) = (x :) <$> parseOperatorTransformOne xs

parseOperatorTransform :: [Value] -> Maybe Value
parseOperatorTransform [] = Nothing
Expand All @@ -172,7 +143,7 @@ parseOperatorS sys = Parser f
parseOperator :: Parser Value
parseOperator = Parser f
where
f str = case runParser (parseOperatorS (SYS [] [])) (lexeme str) of
f str = case runParser (parseOperatorS (SYS [] [])) str of
Nothing -> Nothing
Just (x, xs) -> pat (shuntingYardEnd x) xs
pat (SYS _ vals) str = case parseOperatorTransform vals of
Expand Down Expand Up @@ -263,7 +234,7 @@ parseDeclaration = Parser f
parseAssignation :: Parser Instruction
parseAssignation = Parser f
where
f str = case runParser (parseVar <* parseString " = ") str of
f str = case runParser (parseVar <* parseString "=") str of
Nothing -> Nothing
Just (Var x, xs) ->
case runParser parseValue xs of
Expand All @@ -272,26 +243,26 @@ parseAssignation = Parser f
_notVar -> Nothing

parseCondComp :: Parser Value
parseCondComp = parseString "if(" *> parseValue <* parseString ")\n"
parseCondComp = parseString "if(" *> parseValue <* parseString ")"

parseCondIf :: Parser [Instruction]
parseCondIf = parseString "{\n" *> parseInstructions <* parseString "}"
parseCondIf = parseString "{" *> parseInstructions <* parseString "}"

parseCondElse :: Parser [Instruction]
parseCondElse = parseString "else\n{\n" *> parseInstructions <* parseString "}"
parseCondElse = parseString "else{" *> parseInstructions <* parseString "}"

parseCond' :: Value -> [Instruction] -> Parser Instruction
parseCond' val ifBlock = Parser f
where
f ('\n':xs) = case runParser parseCondElse xs of
f (';':str) = Just (Cond (val, ifBlock, []), ';':str)
f str = case runParser parseCondElse str of
Nothing -> Nothing
Just (elseBlock, ys) -> Just (Cond (val, ifBlock, elseBlock), ys)
f str = Just (Cond (val, ifBlock, []), str)

parseCond :: Parser Instruction
parseCond = Parser f
where
f str = case runParser parseCondComp (lexeme str) of
f str = case runParser parseCondComp str of
Nothing -> Nothing
Just (val, xs) ->
case runParser parseCondIf xs of
Expand All @@ -305,17 +276,15 @@ parseInstruction =
<|> parseDeclaration
<|> parseAssignation
<|> parseFunction
) <* parseString ";\n"
) <* parseString ";"

parseInstructions :: Parser [Instruction]
parseInstructions = Parser f
where
f str = runParser (some parseInstruction) (lexeme str)
parseInstructions = some parseInstruction

parseFuncVar :: Parser Var
parseFuncVar = Parser f
where
f str = case runParser (parseVar <* parseString ":") (lexeme str) of
f str = case runParser (parseVar <* parseString ":") str of
Nothing -> Nothing
Just (Var x, xs) -> runParser (lmbda x <$> parseType) xs
_notVar -> Nothing
Expand All @@ -336,10 +305,7 @@ parseFuncName =
<|> ((\x -> (False, x)) <$> (parseString "fn " *> parseVarName))

parseFuncType :: Parser Type
parseFuncType =
(parseString " -> "
<|> parseString "-> "
<|> parseString "->") *> parseType <* parseString "\n{\n"
parseFuncType = parseString "->" *> parseType <* parseString "{"

parseFuncPrototype :: Parser FuncPrototype
parseFuncPrototype =
Expand All @@ -355,9 +321,9 @@ parseFuncDeclaration' =
(,)
<$> parseFuncPrototype
<*> parseInstructions
<* parseString "};\n"
<* parseString "};"

parseFuncDeclaration :: Parser FuncDeclaration
parseFuncDeclaration = Parser f
where
f str = runParser parseFuncDeclaration' (lexeme str)
f str = runParser parseFuncDeclaration' (lexeme1 str)
4 changes: 3 additions & 1 deletion lvtc/test/Spec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import UTShuntingYard
import UTWatLike
import UTWat
import UTWasm
import UTLexeme

main :: IO ()
main = defaultMain tests
Expand All @@ -31,7 +32,8 @@ tests = testGroup "Leviator Tests - Compiler"
utAlias,
utWatLike,
utWat,
utWasm
utWasm,
utLexeme
]

testParserHelper :: String -> String -> Expression -> IO ()
Expand Down
52 changes: 52 additions & 0 deletions lvtc/test/UTLexeme.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{-
-- EPITECH PROJECT, 2023
-- Leviator compiler
-- File description:
-- UTLexeme
-}

module UTLexeme
(
utLexeme
) where

import Test.Tasty
import Test.Tasty.HUnit

import Lexeme

utLexeme :: TestTree
utLexeme = testGroup "UTLexeme"
[
testCase "lexeme1" $
assertEqual "1"
l1_rep
(lexeme1 l1)
, testCase "lexeme2" $
assertEqual "2"
l2_rep
(lexeme1 l2)
, testCase "lexeme3" $
assertEqual "3"
l3_rep
(lexeme1 l3)
, testCase "lexeme4" $
assertEqual "4"
l4_rep
(lexeme1 l4)
, testCase "lexeme5" $
assertEqual "5"
l5_rep
(lexeme1 l5)
]
where
l1 = "@Int a = 0;"
l1_rep = "@Int a=0;"
l2 = "if (a > b) {\n do(b);\n}\n"
l2_rep = "if(a>b){do(b);}"
l3 = "if (a)\n{\nb(0);\n}\nelse\n{\nc(0);\n};\n"
l3_rep = "if(a){b(0);}else{c(0);};"
l4 = "@Int a = 0;\n @Int c = b(a);\n if (c)\n {\n d(a);\n };\n"
l4_rep = "@Int a=0;@Int c=b(a);if(c){d(a);};"
l5 = "foo(a);\n foo(b);\n"
l5_rep = "foo(a);foo(b);"
7 changes: 4 additions & 3 deletions lvtc/test/UTParseLvt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,26 @@ import Test.Tasty.HUnit

import Parser
import ParseLvt
import Lexeme
import AST

testParserHelper :: String -> String -> Instruction -> IO ()
testParserHelper str restExpected expressionExpected =
case runParser parseInstruction str of
case runParser parseInstruction (lexeme1 str) of
Just (parsed, rest) -> assertEqual str restExpected rest >>
assertEqual str expressionExpected parsed
Nothing -> assertFailure ("Parsing failed for: `" ++ str ++ "`")

testParserFunc :: String -> String -> FuncDeclaration -> IO ()
testParserFunc str restExpected expressionExpected =
case runParser parseFuncDeclaration str of
case runParser parseFuncDeclaration (lexeme1 str) of
Just (parsed, rest) -> assertEqual str restExpected rest >>
assertEqual str expressionExpected parsed
Nothing -> assertFailure ("Parsing failed for: `" ++ str ++ "`")

testParserHelpers :: String -> String -> [Instruction] -> IO ()
testParserHelpers str restExpected expressionExpected =
case runParser parseInstructions str of
case runParser parseInstructions (lexeme1 str) of
Just (parsed, rest) -> assertEqual str restExpected rest >>
assertEqual str expressionExpected parsed
Nothing -> assertFailure ("Parsing failed for: `" ++ str ++ "`")
Expand Down

0 comments on commit 5587c49

Please sign in to comment.