module Parser.Expr (exprP) where import Control.Applicative import Expr import Parser.Core -- Parse expression separated by one infix operator of the operator list operatorChoiceChain :: Parser a -> [Parser (a -> a -> a)] -> Parser a operatorChoiceChain x operators = x `chainl1` choice operators -- Parse an expression (lowest operator priority) exprP :: Parser Expr exprP = operatorChoiceChain termP [ infixOp "+" Add , infixOp "-" Sub ] termP :: Parser Expr termP = operatorChoiceChain factorP [ infixOp "**" Dot , infixOp "*" Mul , infixOp "/" Div , infixOp "%" Mod ] factorP :: Parser Expr factorP = choice [ parenthesizedExprP , imaginaryP , Rational <$> floatP , matrixP , Function <$> labelP <*> parenthesizedExprP , Variable <$> labelP ] `chainl1` (infixOp "^" Exp) where parenthesizedExprP = parenthesis exprP imaginaryP = Imaginary <$> (floatP <|> pure 1.0) <* char 'i' -- Parse a matrix in the following format: -- [ [a, b]; [c, d] ] matrixP :: Parser Expr matrixP = Matrix <$> brackets (matrixRowP `sepBy` (char ';')) where matrixRowP = brackets (exprP `sepBy` (char ',')) brackets = between "[" "]"