content: module ReadSolidExpressionExample 
  ( readSolidExpressionExample
  ) where
  
  import qualified Waterfall.Solids as Solids
  import qualified Waterfall.Booleans as Booleans
  import qualified Waterfall.IO
  import Text.Parsec
  import Control.Monad.Combinators.Expr
  
  type Parser a = Parsec String () a
  
  atomParser :: Parser (IO Solids.Solid)
  atomParser = 
      let filenameParser = char '{' *> (manyTill anyChar (try $ char '}')) <?> "filename"
      in Waterfall.IO.readSolid <$> filenameParser
  
  termParser :: Parser (IO Solids.Solid)
  termParser = 
      let brackets = between (char '(') (char ')')
      in brackets exprParser <|> atomParser <?> "term"
  
  exprParser :: Parser (IO Solids.Solid)
  exprParser = 
      let binary name f = InfixL  (f <$ name)
          table =
              [ [ binary (char '*') (liftA2 Booleans.intersection)]
                , [ binary (char '+') (liftA2 Booleans.union) 
                , binary (char '-') (liftA2 Booleans.difference)
                ]
              ]
      in makeExprParser termParser table
  
  readSolidExpressionExample :: String -> IO Solids.Solid
  readSolidExpressionExample expression = 
      case runParser exprParser () "expression" expression of 
          Left err -> do 
              print err
              fail "Error when parsing expression"
          Right action -> action 
  
  
  