Skip to content

Commit

Permalink
Add operators and add parse func declaration
Browse files Browse the repository at this point in the history
  • Loading branch information
Saverio976 committed Jan 8, 2024
1 parent b5129cc commit d58c0f1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 56 deletions.
6 changes: 5 additions & 1 deletion lvtc/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module Main (main) where
import Expression (parseExpresion, parseAllExpression)
import Parser (runParser)
import Alias (proceedAlias)
import ParseLvt (parseInstruction, parseInstructions)
import ParseLvt (parseInstruction, parseInstructions, parseFuncDeclaration)

test1 :: String
test1 = "if (a)\n{\nb(0);\n};\n"
Expand Down Expand Up @@ -40,6 +40,9 @@ text = aliasInt ++ aliasRetValue ++ funcMain
aliasRetValue = "alias retValue 0;\n"
funcMain = "fn main () -> int \n{\n <- retValue;\n};\n"

test8 :: String
test8 = "fn abc(a: Int) -> Int\n{\n <- a;\n};\n"

main :: IO ()
main =
print (runParser parseInstruction test1)
Expand All @@ -49,3 +52,4 @@ main =
>> print (runParser parseInstruction test5)
>> print (runParser parseInstruction test6)
>> print (runParser (proceedAlias <$> parseAllExpression) text)
>> print (runParser parseFuncDeclaration test8)
107 changes: 79 additions & 28 deletions lvtc/src/ParseLvt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ module ParseLvt
parseDeclaration,
parseAssignation,
parseCond,
-- Function
parseFuncDeclaration
) where

import Control.Applicative
Expand Down Expand Up @@ -52,6 +54,8 @@ 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

parseBoolean :: Parser Value
Expand Down Expand Up @@ -113,15 +117,11 @@ parseOperatorFstVal = Parser f

parseOperatorOp :: Parser Value
parseOperatorOp =
f
<$> (parseString "+"
<|> parseString "-"
<|> parseString "*"
<|> parseString "/"
<|> parseString "("
<|> parseString ")")
where
f op = Var op
Var
<$> (parseString "+" <|> parseString "-" <|> parseString "*"
<|> parseString "/" <|> parseString "(" <|> parseString ")"
<|> parseString "==" <|> parseString "!=" <|> parseString "<"
<|> parseString ">" <|> parseString "<=" <|> parseString ">=")

parseOperator' :: ShuntingYardState -> Parser ShuntingYardState
parseOperator' sys =
Expand All @@ -131,32 +131,34 @@ parseOperator' sys =
fVal val = shuntingYardValue val sys
fOp op = shuntingYardOp op sys

parseOperatorTransform'' :: [Value] -> Maybe [Value]
parseOperatorTransform'' (x1:x2:(Var op):rest)
| isOperator op = Just (FuncValue (op, [x1, x2]) : rest)
| otherwise = case parseOperatorTransform' rest of
Nothing -> Nothing
Just ys -> Just (x1:x2:ys)
parseOperatorTransform'' _ = Nothing

parseOperatorTransform' :: [Value] -> Maybe [Value]
parseOperatorTransform' [] = Just []
parseOperatorTransform' (_:(Var "+"):_) = Nothing
parseOperatorTransform' (_:(Var "-"):_) = Nothing
parseOperatorTransform' (_:(Var "*"):_) = Nothing
parseOperatorTransform' (_:(Var "/"):_) = Nothing
parseOperatorTransform' (x1:x2:(Var "+"):rest) =
Just ((FuncValue ("+", [x1, x2])) : rest)
parseOperatorTransform' (x1:x2:(Var "-"):rest) =
Just ((FuncValue ("-", [x1, x2])) : rest)
parseOperatorTransform' (x1:x2:(Var "*"):rest) =
Just ((FuncValue ("*", [x1, x2])) : rest)
parseOperatorTransform' (x1:x2:(Var "/"):rest) =
Just ((FuncValue ("/", [x1, x2])) : rest)
parseOperatorTransform' (x:xs) =
case parseOperatorTransform' xs of
Nothing -> Nothing
Just ys -> Just (x:ys)
parseOperatorTransform' [x] = Just [x]
parseOperatorTransform' [_, _] = Nothing
parseOperatorTransform' (x1:(Var op):rest)
| isOperator op = Nothing
| otherwise = parseOperatorTransform'' (x1 : Var op : rest)
parseOperatorTransform' (x1:x2:(Var op):rest) =
parseOperatorTransform'' (x1 : x2 : Var op : rest)
parseOperatorTransform' (x:xs) = case parseOperatorTransform' xs of
Nothing -> Nothing
Just ys -> Just (x:ys)

parseOperatorTransform :: [Value] -> Maybe Value
parseOperatorTransform [] = Nothing
parseOperatorTransform vals =
case parseOperatorTransform' vals of
Nothing -> Nothing
Just [] -> Nothing
Just (x:[]) -> Just x
Just [x] -> Just x
Just (x:rest) -> parseOperatorTransform (x:rest)

parseOperatorS :: ShuntingYardState -> Parser ShuntingYardState
Expand Down Expand Up @@ -231,10 +233,10 @@ parseFunction :: Parser Instruction
parseFunction = parseCall

parseReturn :: Parser Instruction
parseReturn = Return <$> (parseString "<- " *> parseValue)
parseReturn = Return <$> ((parseString "<- " <|> parseString "<-") *> parseValue)

parseType :: Parser String
parseType =
parseType =
parseString "Bool"
<|> parseString "Int"
<|> parseString "Char"
Expand Down Expand Up @@ -310,3 +312,52 @@ parseInstructions :: Parser [Instruction]
parseInstructions = Parser f
where
f str = runParser (some parseInstruction) (lexeme str)

parseFuncVar :: Parser Var
parseFuncVar = Parser f
where
f str = case runParser (parseVar <* parseString ":") (lexeme str) of
Nothing -> Nothing
Just (Var x, xs) -> runParser (lmbda x <$> parseType) xs
_notVar -> Nothing
lmbda var typ = (var, typ)

parseFuncVars :: Parser [Var]
parseFuncVars =
parseChar '(' *>
some
(parseFuncVar
<* (parseString "," <|> parseString " ," <|> parseString ", ")
<|> parseFuncVar)
<* parseChar ')'

parseFuncName :: Parser Symbol
parseFuncName = Parser f
where
f str = case runParser
((parseString "export fn " <|> parseString "fn ") *> parseVar)
str
of
Nothing -> Nothing
Just (Var x, xs) -> Just (x, xs)
_notVar -> Nothing

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

parseFuncPrototype :: Parser FuncPrototype
parseFuncPrototype =
(,,)
<$> parseFuncName
<*> parseFuncVars
<*> parseFuncType

parseFuncDeclaration :: Parser FuncDeclaration
parseFuncDeclaration =
(,)
<$> parseFuncPrototype
<*> parseInstructions
<* parseString "};\n"
63 changes: 36 additions & 27 deletions lvtc/src/ShuntingYard.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ module ShuntingYard
shuntingYardOp,
shuntingYardEnd,
shuntingYardValue,
ShuntingYardState (..)
ShuntingYardState (..),
isOperator
) where

import AST
Expand All @@ -26,44 +27,52 @@ instance Show ShuntingYardState where
shuntingYardValue :: Value -> ShuntingYardState -> ShuntingYardState
shuntingYardValue val (SYS ops out) = SYS ops (out ++ [val])

isOperator :: String -> Bool
isOperator "!=" = True
isOperator "==" = True
isOperator "<" = True
isOperator ">" = True
isOperator "<=" = True
isOperator ">=" = True
isOperator "+" = True
isOperator "-" = True
isOperator "*" = True
isOperator "/" = True
isOperator _ = False

getPrecedence :: String -> Int
getPrecedence "!=" = 1
getPrecedence "==" = 1
getPrecedence "<" = 1
getPrecedence ">" = 1
getPrecedence "<=" = 1
getPrecedence ">=" = 1
getPrecedence "+" = 2
getPrecedence "-" = 2
getPrecedence "*" = 3
getPrecedence "/" = 3
getPrecedence _ = 0

opOnStack :: Value -> ShuntingYardState -> ShuntingYardState
opOnStack (Var "+") (SYS ((Var "*"):ops) out) =
opOnStack (Var "+") (SYS ops (out ++ [Var "*"]))
opOnStack (Var "+") (SYS ((Var "/"):ops) out) =
opOnStack (Var "+") (SYS ops (out ++ [Var "/"]))
opOnStack (Var "+") (SYS ((Var "-"):ops) out) =
opOnStack (Var "+") (SYS ops (out ++ [Var "-"]))
opOnStack (Var "+") (SYS ((Var "+"):ops) out) =
opOnStack (Var "+") (SYS ops (out ++ [Var "+"]))
opOnStack (Var "-") (SYS ((Var "*"):ops) out) =
opOnStack (Var "-") (SYS ops (out ++ [Var "*"]))
opOnStack (Var "-") (SYS ((Var "/"):ops) out) =
opOnStack (Var "-") (SYS ops (out ++ [Var "/"]))
opOnStack (Var "-") (SYS ((Var "+"):ops) out) =
opOnStack (Var "-") (SYS ops (out ++ [Var "+"]))
opOnStack (Var "-") (SYS ((Var "-"):ops) out) =
opOnStack (Var "-") (SYS ops (out ++ [Var "-"]))
opOnStack (Var "*") (SYS ((Var "/"):ops) out) =
opOnStack (Var "*") (SYS ops (out ++ [Var "/"]))
opOnStack (Var "*") (SYS ((Var "*"):ops) out) =
opOnStack (Var "*") (SYS ops (out ++ [Var "*"]))
opOnStack (Var "/") (SYS ((Var "*"):ops) out) =
opOnStack (Var "/") (SYS ops (out ++ [Var "*"]))
opOnStack (Var "/") (SYS ((Var "/"):ops) out) =
opOnStack (Var "/") (SYS ops (out ++ [Var "/"]))
opOnStack (Var op1) (SYS ((Var op2):ops) out)
| prec2 >= prec1 = opOnStack (Var op1) (SYS ops (out ++ [Var op2]))
| otherwise = SYS (Var op2:ops) out
where
prec1 = getPrecedence op1
prec2 = getPrecedence op2
opOnStack _ sys = sys

shuntingYardOp :: Value -> ShuntingYardState -> ShuntingYardState
shuntingYardOp (Var "(") (SYS ops out) =
SYS ((Var "(") : ops) out
SYS (Var "(" : ops) out
shuntingYardOp (Var ")") (SYS [] _) =
SYS [] []
shuntingYardOp (Var ")") (SYS ((Var "("):ops) out) =
SYS ops out
shuntingYardOp (Var ")") (SYS (op:ops) out) =
shuntingYardOp (Var ")") (SYS ops (out ++ [op]))
shuntingYardOp (Var op) sys =
SYS ((Var op):ops') out'
SYS (Var op:ops') out'
where
(SYS ops' out') = opOnStack (Var op) sys
shuntingYardOp _ _ = SYS [] []
Expand Down
16 changes: 16 additions & 0 deletions lvtc/test/UTParseLvt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ testParserHelper str restExpected expressionExpected =
assertEqual str expressionExpected parsed
Nothing -> assertFailure ("Parsing failed for: `" ++ str ++ "`")

testParserFunc :: String -> String -> FuncDeclaration -> IO ()
testParserFunc str restExpected expressionExpected =
case runParser parseFuncDeclaration 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
Expand Down Expand Up @@ -86,4 +93,13 @@ utParserLvt = testGroup "Parse Lvt"
Declaration (("c", "Int"), FuncValue ("b", [Var "a"])),
Cond (Var "c", [Function ("d", [Var "a"])], [])
]
, testCase "test func" $
testParserFunc "fn abc(a: Int) -> Int\n{\n <- a;\n};\n"
""
(
("abc", [("a", "Int")], "Int"),
[
Return (Var "a")
]
)
]

0 comments on commit d58c0f1

Please sign in to comment.