module Roller.Parse ( parse, naturalNumber, dieTerm ) where import Roller.Types import Text.Regex.Applicative import Data.Char (isDigit, isSpace) import Data.Word naturalNumber :: RE Char Word8 naturalNumber = read <$> some (psym isDigit) dieTerm :: RE Char DiceExpression dieTerm = constructDieTerm <$> naturalNumber <* sym dieSymbol <*> naturalNumber addedDieTerm :: RE Char DiceExpression addedDieTerm = constructAddedDieTerm <$> (sym additionSymbol *> naturalNumber) <* sym dieSymbol <*> naturalNumber subtractedDieTerm :: RE Char DiceExpression subtractedDieTerm = constructSubtractedDieTerm <$> (sym subtractionSymbol *> naturalNumber) <* sym dieSymbol <*> naturalNumber constantTerm :: RE Char DiceExpression constantTerm = constructConstantTerm <$> naturalNumber addedConstantTerm :: RE Char DiceExpression addedConstantTerm = constructAddedConstantTerm <$> (sym additionSymbol *> naturalNumber) subtractedConstantTerm :: RE Char DiceExpression subtractedConstantTerm = constructSubtractedConstantTerm <$> (sym subtractionSymbol *> naturalNumber) diceExpression :: RE Char [DiceExpression] diceExpression = (:) <$> term <*> many signedTerm where term = dieTerm <|> constantTerm signedTerm = signedDieTerm <|> signedConstantTerm signedDieTerm = addedDieTerm <|> subtractedDieTerm signedConstantTerm = addedConstantTerm <|> subtractedConstantTerm parse :: String -> Maybe [DiceExpression] parse x = filter (not . isSpace) x =~ diceExpression