{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}

module Language.REST.MetaTerm where

import Data.String
import Data.Hashable
import GHC.Generics (Generic)

import Language.REST.Op
import Language.REST.RuntimeTerm

-- | A MetaTerm is a term with variables; used for 'Rewrite' rules
data MetaTerm =
    Var String
  | RWApp Op [MetaTerm] deriving (MetaTerm -> MetaTerm -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MetaTerm -> MetaTerm -> Bool
$c/= :: MetaTerm -> MetaTerm -> Bool
== :: MetaTerm -> MetaTerm -> Bool
$c== :: MetaTerm -> MetaTerm -> Bool
Eq, Eq MetaTerm
MetaTerm -> MetaTerm -> Bool
MetaTerm -> MetaTerm -> Ordering
MetaTerm -> MetaTerm -> MetaTerm
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MetaTerm -> MetaTerm -> MetaTerm
$cmin :: MetaTerm -> MetaTerm -> MetaTerm
max :: MetaTerm -> MetaTerm -> MetaTerm
$cmax :: MetaTerm -> MetaTerm -> MetaTerm
>= :: MetaTerm -> MetaTerm -> Bool
$c>= :: MetaTerm -> MetaTerm -> Bool
> :: MetaTerm -> MetaTerm -> Bool
$c> :: MetaTerm -> MetaTerm -> Bool
<= :: MetaTerm -> MetaTerm -> Bool
$c<= :: MetaTerm -> MetaTerm -> Bool
< :: MetaTerm -> MetaTerm -> Bool
$c< :: MetaTerm -> MetaTerm -> Bool
compare :: MetaTerm -> MetaTerm -> Ordering
$ccompare :: MetaTerm -> MetaTerm -> Ordering
Ord, Int -> MetaTerm -> ShowS
[MetaTerm] -> ShowS
MetaTerm -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MetaTerm] -> ShowS
$cshowList :: [MetaTerm] -> ShowS
show :: MetaTerm -> String
$cshow :: MetaTerm -> String
showsPrec :: Int -> MetaTerm -> ShowS
$cshowsPrec :: Int -> MetaTerm -> ShowS
Show, forall x. Rep MetaTerm x -> MetaTerm
forall x. MetaTerm -> Rep MetaTerm x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep MetaTerm x -> MetaTerm
$cfrom :: forall x. MetaTerm -> Rep MetaTerm x
Generic, Eq MetaTerm
Int -> MetaTerm -> Int
MetaTerm -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: MetaTerm -> Int
$chash :: MetaTerm -> Int
hashWithSalt :: Int -> MetaTerm -> Int
$chashWithSalt :: Int -> MetaTerm -> Int
Hashable)

instance IsString MetaTerm where
  fromString :: String -> MetaTerm
fromString = String -> MetaTerm
Var

-- | Helper class, enabling conversion of 'RuntimeTerm's to 'MetaTerm's
class ToMetaTerm a where
  toMetaTerm :: a -> MetaTerm

instance ToMetaTerm MetaTerm where
  toMetaTerm :: MetaTerm -> MetaTerm
toMetaTerm = forall a. a -> a
id

instance ToMetaTerm RuntimeTerm where
  toMetaTerm :: RuntimeTerm -> MetaTerm
toMetaTerm (App Op
f [RuntimeTerm]
xs) = Op -> [MetaTerm] -> MetaTerm
RWApp Op
f (forall a b. (a -> b) -> [a] -> [b]
map forall a. ToMetaTerm a => a -> MetaTerm
toMetaTerm [RuntimeTerm]
xs)