import Dyna.Term.TTerm
-- import Dyna.Test.Trifecta -- XXX
+import qualified Data.Char as C
+
data ANFDict = AD
{ -- | A map from (functor,arity) to a list of bits indicating whether to
-- (True) or not to (False) evaluate that positional argument.
--
-- XXX Stronger type desired: we'd like static assurance that the
-- length of the list matches the arity in the key!
- ad_arg_dispos :: M.Map (B.ByteString,Int) [Bool]
+ ad_arg_dispos :: (B.ByteString,Int) -> [Bool]
-- | The set of functors that prefer not to be evaluated.
, ad_self_dispos :: S.Set (B.ByteString,Int)
unspan (P.TFunctor a as T.:~ _) = UTerm $ TFunctor a $ map unspan as
unspan (P.TAnnot a t T.:~ _) = UTerm $ TAnnot (fmap unspan a) (unspan t)
+
-- | Convert a syntactic term into ANF; while here, move to a
-- Control.Unification term representation.
--
-- Numerics also get returned in-place.
normTerm_ _ _ _ (P.TNumeric n) = return $ UTerm $ TNumeric n
-
+
-- Quote simply disappears having converted the context to
-- a non-evaluation context.
normTerm_ _ _ ss (P.TFunctor "&" [t T.:~ st]) = do
-- Functors have both top-down and bottom-up dispositions on
-- their handling.
normTerm_ c u ss (P.TFunctor f as) = do
- argdispos <- asks $ maybe (repeat True) (id) . M.lookup (f,length as) . ad_arg_dispos
+ argdispos <- asks $ flip ($) (f,length as) . ad_arg_dispos
normas <- mapM (\(a T.:~ s,d) -> normTerm_ d True (s:ss) a) (zip as argdispos)
selfdispos <- getSelfDispos
(case () of
getSelfDispos = do
set <- asks $ not . S.member (f,length as) . ad_self_dispos
return set
-
+
normTerm :: (MonadState ANFState m, MonadReader ANFDict m)
=> Bool -- ^ In an evaluation context?
return $ Rule nh a nes nr
-- XXX
-dynaFunctorArgDispositions :: M.Map (B.ByteString,Int) [Bool]
-dynaFunctorArgDispositions = M.fromList [
- (("is",2),[False,True])
- ]
+--dynaFunctorArgDispositions :: M.Map (B.ByteString,Int) [Bool]
+dynaFunctorArgDispositions :: (B.ByteString, Int) -> [Bool]
+dynaFunctorArgDispositions x = case x of
+ ("is", 2) -> [False,True]
+ -- evaluate arithmetic / math
+ ("exp", 1) -> [True]
+ ("log", 1) -> [True]
+ -- logic
+ ("and", 2) -> [True, True]
+ ("or", 2) -> [True, True]
+ ("not", 1) -> [True]
+ (name, arity) -> take arity $ repeat $ C.isAlpha $ head $ BU.toString name
-- XXX
--
---------------------------------------------------------------------------
-- | A parser for some chunk of the Dyna language, using Trifecta
---
+--
-- Based in part on
-- <https://github.com/ekmett/trifecta/blob/master/examples/RFC2616.hs>
-- as well as the trifecta code itself
, try $ spanned $ flip TFunctor [] <$> atom
<* (notFollowedBy $ char '(')
- , try $ spanned $ flip TFunctor [] <$> (bsf $ string "*")
+ , try $ spanned $ flip TFunctor [] <$> (bsf $ string "*")
, spanned $ parenfunc
]
where
dterm, dtexpr :: DeltaParsing m => m (Spanned Term)
-dterm = unDL term
-dtexpr = unDL texpr
+dterm = unDL term
+dtexpr = unDL texpr
------------------------------------------------------------------------}}}
-- Rules {{{
-- | Grab the head (term!) and aggregation operator from a line that
--- we hope is a rule.
+-- we hope is a rule.
rulepfx :: DeltaParsing f => f ([Spanned Term] -> Spanned Term -> Rule)
rulepfx = Rule <$> term
<* spaces
- <*> (bsf $ ident dynaOperStyle <?> "Aggregator")
+ <*> ((bsf $ some $ satisfy $ not . isSpace) <?> "Aggregator") -- XXX probably a better way to do this.. probably want aggregators have suffix =
+ <* spaces
rule :: DeltaParsing m => m Rule
rule = choice [
, Fact <$> term
]
where
- hrss = highlight ReservedOperator . spanned . symbol
+ hrss = highlight ReservedOperator . spanned . symbol
drule :: DeltaParsing m => m (Spanned Rule)
drule = spanned rule