diff options
Diffstat (limited to 'lib/Language/Elna/Parser.hs')
| -rw-r--r-- | lib/Language/Elna/Parser.hs | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/lib/Language/Elna/Parser.hs b/lib/Language/Elna/Parser.hs index cee533e..aa7c315 100644 --- a/lib/Language/Elna/Parser.hs +++ b/lib/Language/Elna/Parser.hs @@ -9,7 +9,9 @@ import Data.Text (Text) import qualified Data.Text as Text import Data.Void (Void) import Language.Elna.AST - ( Declaration(..) + ( VariableAccess(..) + , Condition(..) + , Declaration(..) , Expression(..) , Identifier(..) , Literal(..) @@ -21,12 +23,12 @@ import Language.Elna.AST ) import Text.Megaparsec ( Parsec + , MonadParsec(..) , (<?>) , optional , between , sepBy , choice - , MonadParsec(..) ) import Text.Megaparsec.Char ( alphaNumChar @@ -124,19 +126,23 @@ termP :: Parser Expression termP = choice [ parensP expressionP , LiteralExpression <$> literalP - , VariableExpression <$> identifierP + , VariableExpression <$> variableAccessP ] +variableAccessP :: Parser VariableAccess +variableAccessP = do + identifier <- identifierP + indices <- many $ bracketsP expressionP + pure $ foldr (flip ArrayAccess) (VariableAccess identifier) indices + operatorTable :: [[Operator Parser Expression]] operatorTable = - [ [Postfix (flip ArrayExpression <$> bracketsP expressionP)] - , unaryOperator + [ unaryOperator , factorOperator , termOperator - , comparisonOperator ] where - unaryOperator = + unaryOperator = [ prefix "-" NegationExpression , prefix "+" id ] @@ -148,20 +154,27 @@ operatorTable = [ binary "+" SumExpression , binary "-" SubtractionExpression ] - comparisonOperator = - [ binary "<" LessExpression - , binary "<=" LessOrEqualExpression - , binary ">" GreaterExpression - , binary ">=" GreaterOrEqualExpression - , binary "=" EqualExpression - , binary "#" NonEqualExpression - ] prefix name f = Prefix (f <$ symbol name) binary name f = InfixL (f <$ symbol name) expressionP :: Parser Expression expressionP = makeExprParser termP operatorTable +conditionP :: Parser Condition +conditionP = do + lhs <- expressionP + conditionCons <- choice comparisonOperator + conditionCons lhs <$> expressionP + where + comparisonOperator = + [ symbol "<" >> pure LessCondition + , symbol "<=" >> pure LessOrEqualCondition + , symbol ">" >> pure GreaterCondition + , symbol ">=" >> pure GreaterOrEqualCondition + , symbol "=" >> pure EqualCondition + , symbol "#" >> pure NonEqualCondition + ] + statementP :: Parser Statement statementP = EmptyStatement <$ semicolonP @@ -173,18 +186,18 @@ statementP <?> "statement" where ifElseP = IfStatement - <$> (symbol "if" *> parensP expressionP) + <$> (symbol "if" *> parensP conditionP) <*> statementP <*> optional (symbol "else" *> statementP) whileP = WhileStatement - <$> (symbol "while" *> parensP expressionP) + <$> (symbol "while" *> parensP conditionP) <*> statementP callP = CallStatement <$> identifierP <*> parensP (sepBy expressionP commaP) <* semicolonP assignmentP = AssignmentStatement - <$> expressionP + <$> variableAccessP <* symbol ":=" <*> expressionP <* semicolonP |
