module Rule where
import qualified TermParser
import qualified Term
import InOut ( Input(input), Output(output), parsecReader )
import Term ( Term(Node), Identifier )
import SourceText ( ParserRange )
import Text.PrettyPrint.HughesPJ ( fsep, render, text )
import Control.Applicative ( (<$>) )
data Rule range = Rule
{ name :: Identifier range
, parameters :: [ Term range ]
, rhs :: Term range
}
instance Functor Rule where
fmap f r =
Rule {
name = f <$> name r,
parameters = map (f <$>) $ parameters r,
rhs = f <$> rhs r
}
instance Show (Rule range) where show = render . output
instance (ParserRange range) =>
Read (Rule range) where readsPrec = parsecReader
instance Output (Rule range) where
output r =
fsep [ output ( Node (name r) (parameters r) ), text "=",
output ( rhs r ), text ";" ]
instance (ParserRange range) => Input (Rule range) where
input = do
t <- input
(nm, ps) <-
case t of
Term.Node nm args ->
if Term.isVariable nm
then return (nm, args)
else fail $ show nm ++ " is not a function identifier"
_ -> fail $ "the term " ++ show t ++ " is not a valid left-hand side of a rule"
TermParser.symbol "="
r <- input
TermParser.symbol ";"
return $ Rule { name = nm, parameters = ps, rhs = r }