packages feed

waterfall-cad-examples-0.2.2.0: src/ReadSolidExpressionExample.hs

module ReadSolidExpressionExample 
( readSolidExpressionExample
) where

import qualified Waterfall.Solids as Solids
import qualified Waterfall.Booleans as Booleans
import qualified Waterfall.IO
import Control.Applicative (liftA2)
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