module Graphics.Implicit.ExtOpenScad.Definitions (ArgParser(AP, APTest, APBranch, APTerminator, APFailIf, APExample),
Symbol,
Pattern(Wild, Name, ListP),
Expr(LitE, Var, ListE, LamE, (:$)),
StatementI(StatementI),
Statement(DoNothing, NewModule, Include, Echo, If, For, ModuleCall, (:=)),
OVal(ONum, OBool, OString, OList, OFunc, OUndefined, OModule,OError, OObj2, OObj3),
VarLookup,
FStack,
TestInvariant(EulerCharacteristic),
collector) where
import Prelude(Eq, Show, String, Maybe, Bool(True, False), Int, IO, (==), show, map, ($), (++), undefined, all, id, zipWith, foldl1)
import Graphics.Implicit.Definitions (ℝ, SymbolicObj2, SymbolicObj3)
import Control.Applicative (Applicative, Alternative((<|>), empty), pure, (<*>))
import Control.Monad (Functor, Monad, fmap, (>>=), mzero, mplus, MonadPlus, liftM, ap)
import Data.Map (Map)
data ArgParser a
= AP String (Maybe OVal) String (OVal -> ArgParser a)
| APTerminator a
| APFailIf Bool String (ArgParser a)
| APExample String (ArgParser a)
| APTest String [TestInvariant] (ArgParser a)
| APBranch [ArgParser a]
instance Functor ArgParser where
fmap = liftM
instance Applicative ArgParser where
pure a = APTerminator a
(<*>) = ap
instance Monad ArgParser where
(AP str fallback d f) >>= g = AP str fallback d (\a -> (f a) >>= g)
(APFailIf b errmsg child) >>= g = APFailIf b errmsg (child >>= g)
(APExample str child) >>= g = APExample str (child >>= g)
(APTest str tests child) >>= g = APTest str tests (child >>= g)
(APTerminator a) >>= g = g a
(APBranch bs) >>= g = APBranch $ map (>>= g) bs
instance MonadPlus ArgParser where
mzero = APFailIf True "" undefined
mplus (APBranch as) (APBranch bs) = APBranch ( as ++ bs )
mplus (APBranch as) b = APBranch ( as ++ [b] )
mplus a (APBranch bs) = APBranch ( [a] ++ bs )
mplus a b = APBranch [ a , b ]
instance Alternative ArgParser where
(<|>) = mplus
empty = mzero
type Symbol = String
data Pattern = Name Symbol
| ListP [Pattern]
| Wild
| Symbol :@ Pattern
deriving (Show, Eq)
data Expr = Var Symbol
| LitE OVal
| ListE [Expr]
| LamE [Pattern] Expr
| Expr :$ [Expr]
deriving (Show, Eq)
data StatementI = StatementI Int (Statement StatementI)
deriving (Show, Eq)
data Statement st = Include String Bool
| Pattern := Expr
| Echo [Expr]
| For Pattern Expr [st]
| If Expr [st] [st]
| NewModule Symbol [(Symbol, Maybe Expr)] [st]
| ModuleCall Symbol [(Maybe Symbol, Expr)] [st]
| DoNothing
deriving (Show, Eq)
data OVal = OUndefined
| OError [String]
| OBool Bool
| ONum ℝ
| OList [OVal]
| OString String
| OFunc (OVal -> OVal)
| OModule ([OVal] -> ArgParser (IO [OVal]))
| OObj3 SymbolicObj3
| OObj2 SymbolicObj2
instance Eq OVal where
(OBool a) == (OBool b) = a == b
(ONum a) == (ONum b) = a == b
(OList a) == (OList b) = all id $ zipWith (==) a b
(OString a) == (OString b) = a == b
_ == _ = False
instance Show OVal where
show OUndefined = "Undefined"
show (OBool b) = show b
show (ONum n) = show n
show (OList l) = show l
show (OString s) = show s
show (OFunc _) = "<function>"
show (OModule _) = "module"
show (OError msgs) = "Execution Error:\n" ++ foldl1 (\a b -> a ++ "\n" ++ b) msgs
show (OObj2 obj) = "<obj2: " ++ show obj ++ ">"
show (OObj3 obj) = "<obj3: " ++ show obj ++ ">"
type VarLookup = Map String OVal
type FStack = [OVal]
collector :: Symbol -> [Expr] -> Expr
collector _ [x] = x
collector s l = Var s :$ [ListE l]
data TestInvariant = EulerCharacteristic Int
deriving (Show)