atomo-0.2.2: src/Atomo/Kernel/Comparable.hs
{-# LANGUAGE QuasiQuotes #-}
module Atomo.Kernel.Comparable (load) where
import qualified Data.Vector as V
import Atomo
load :: VM ()
load = do
mapM_ eval
[ [$e|operator 4 == /= < <= >= >|]
, [$e|operator right 3 &&|]
, [$e|operator right 2 |||]
]
[$p|a equals?: b|] =: do
a <- here "a"
b <- here "b"
return $ Boolean (a == b)
[$p|(a: Object) == (b: Object)|] =::: [$e|a equals?: b|]
[$p|(a: Object) /= (b: Object)|] =::: [$e|(a == b) not|]
[$p|(a: Char) < (b: Char)|] =: do
Char a <- here "a" >>= findChar
Char b <- here "b" >>= findChar
return $ Boolean (a < b)
[$p|(a: Char) > (b: Char)|] =: do
Char a <- here "a" >>= findChar
Char b <- here "b" >>= findChar
return $ Boolean (a > b)
[$p|(a: Char) <= (b: Char)|] =: do
Char a <- here "a" >>= findChar
Char b <- here "b" >>= findChar
return $ Boolean (a <= b)
[$p|(a: Char) >= (b: Char)|] =: do
Char a <- here "a" >>= findChar
Char b <- here "b" >>= findChar
return $ Boolean (a >= b)
[$p|(a: Char) == (b: Char)|] =: do
Char a <- here "a" >>= findChar
Char b <- here "b" >>= findChar
return $ Boolean (a == b)
[$p|(a: Integer) < (b: Integer)|] =: primII (<)
[$p|(a: Double) < (b: Double)|] =: primDD (<)
[$p|(a: Rational) < (b: Rational)|] =: primRR (<)
[$p|(a: Integer) < (b: Double)|] =: primID (<)
[$p|(a: Integer) < (b: Rational)|] =: primIR (<)
[$p|(a: Double) < (b: Integer)|] =: primDI (<)
[$p|(a: Double) < (b: Rational)|] =: primDR (<)
[$p|(a: Rational) < (b: Integer)|] =: primRI (<)
[$p|(a: Rational) < (b: Double)|] =: primRD (<)
[$p|(a: Integer) > (b: Integer)|] =: primII (>)
[$p|(a: Double) > (b: Double)|] =: primDD (>)
[$p|(a: Rational) > (b: Rational)|] =: primRR (>)
[$p|(a: Integer) > (b: Double)|] =: primID (>)
[$p|(a: Integer) > (b: Rational)|] =: primIR (>)
[$p|(a: Double) > (b: Integer)|] =: primDI (>)
[$p|(a: Double) > (b: Rational)|] =: primDR (>)
[$p|(a: Rational) > (b: Integer)|] =: primRI (>)
[$p|(a: Rational) > (b: Double)|] =: primRD (>)
[$p|(a: Integer) <= (b: Integer)|] =: primII (<=)
[$p|(a: Double) <= (b: Double)|] =: primDD (<=)
[$p|(a: Rational) <= (b: Rational)|] =: primRR (<=)
[$p|(a: Integer) <= (b: Double)|] =: primID (<=)
[$p|(a: Integer) <= (b: Rational)|] =: primIR (<=)
[$p|(a: Double) <= (b: Integer)|] =: primDI (<=)
[$p|(a: Double) <= (b: Rational)|] =: primDR (<=)
[$p|(a: Rational) <= (b: Integer)|] =: primRI (<=)
[$p|(a: Rational) <= (b: Double)|] =: primRD (<=)
[$p|(a: Integer) >= (b: Integer)|] =: primII (>=)
[$p|(a: Double) >= (b: Double)|] =: primDD (>=)
[$p|(a: Rational) >= (b: Rational)|] =: primRR (>=)
[$p|(a: Integer) >= (b: Double)|] =: primID (>=)
[$p|(a: Integer) >= (b: Rational)|] =: primIR (>=)
[$p|(a: Double) >= (b: Integer)|] =: primDI (>=)
[$p|(a: Double) >= (b: Rational)|] =: primDR (>=)
[$p|(a: Rational) >= (b: Integer)|] =: primRI (>=)
[$p|(a: Rational) >= (b: Double)|] =: primRD (>=)
[$p|(a: Integer) == (b: Integer)|] =: primII (==)
[$p|(a: Double) == (b: Double)|] =: primDD (==)
[$p|(a: Rational) == (b: Rational)|] =: primRR (==)
[$p|(a: Integer) == (b: Double)|] =: primID (==)
[$p|(a: Integer) == (b: Rational)|] =: primIR (==)
[$p|(a: Double) == (b: Integer)|] =: primDI (==)
[$p|(a: Double) == (b: Rational)|] =: primDR (==)
[$p|(a: Rational) == (b: Integer)|] =: primRI (==)
[$p|(a: Rational) == (b: Double)|] =: primRD (==)
[$p|(a: List) == (b: List)|] =: do
as <- getVector [$e|a|]
bs <- getVector [$e|b|]
if V.length as == V.length bs
then do
eqs <- V.zipWithM (\a b -> dispatch (keyword ["=="] [a, b])) as bs
return $ Boolean (V.all (== Boolean True) eqs)
else return $ Boolean False
[$p|(a: Process) == (b: Process)|] =: do
Process _ a <- here "a" >>= findProcess
Process _ b <- here "b" >>= findProcess
return $ Boolean (a == b)
[$p|(a: Message) == (b: Message)|] =: do
Message a <- here "a" >>= findMessage
Message b <- here "b" >>= findMessage
case (a, b) of
(Single ai _ at, Single bi _ bt) -> do
Boolean t <- dispatch (keyword ["=="] [at, bt]) >>= findBoolean
return $ Boolean (ai == bi && t)
(Keyword ai _ avs, Keyword bi _ bvs)
| ai == bi && length avs == length bvs -> do
eqs <- zipWithM (\x y -> dispatch (keyword ["=="] [x, y])) avs bvs
return $ Boolean (all (== Boolean True) eqs)
_ -> return $ Boolean False
[$p|(a: Particle) == (b: Particle)|] =: do
Particle a <- here "a" >>= findParticle
Particle b <- here "b" >>= findParticle
case (a, b) of
(PMSingle an, PMSingle bn) ->
return $ Boolean (an == bn)
(PMKeyword ans avs, PMKeyword bns bvs)
| ans == bns && length avs == length bvs -> do
eqs <- zipWithM (\mx my ->
case (mx, my) of
(Nothing, Nothing) -> return (Boolean True)
(Just x, Just y) ->
dispatch (keyword ["=="] [x, y])
_ -> return $ Boolean False) avs bvs
return $ Boolean (all (== Boolean True) eqs)
_ -> return $ Boolean False
where
primII f = do
Integer a <- here "a" >>= findInteger
Integer b <- here "b" >>= findInteger
return (Boolean $ f a b)
primDD f = do
Double a <- here "a" >>= findDouble
Double b <- here "b" >>= findDouble
return (Boolean $ f a b)
primRR f = do
Rational a <- here "a" >>= findRational
Rational b <- here "b" >>= findRational
return (Boolean $ f a b)
primID f = do
Integer a <- here "a" >>= findInteger
Double b <- here "b" >>= findDouble
return (Boolean $ f (fromIntegral a) b)
primIR f = do
Integer a <- here "a" >>= findInteger
Rational b <- here "b" >>= findRational
return (Boolean $ f (toRational a) b)
primDI f = do
Double a <- here "a" >>= findDouble
Integer b <- here "b" >>= findInteger
return (Boolean $ f a (fromIntegral b))
primDR f = do
Double a <- here "a" >>= findDouble
Rational b <- here "b" >>= findRational
return (Boolean $ f (toRational a) b)
primRD f = do
Rational a <- here "a" >>= findRational
Double b <- here "b" >>= findDouble
return (Boolean $ f a (toRational b))
primRI f = do
Rational a <- here "a" >>= findRational
Integer b <- here "b" >>= findInteger
return (Boolean $ f a (toRational b))