MetaObject-0.0.3: examples/old/mi.hs
{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances -fallow-overlapping-instances #-}
import MO.Run
import MO.Compile
import MO.Compile.Class
import MO.Compile.Attribute
import MO.Util
import Debug.Trace
import Data.List (sort)
import Data.Typeable
say = putStrLn
base = newMI $ emptyMI { clsName = "base" }
point = newMI $ emptyMI
{ clsName = "point"
, clsParents = [AnyClass base]
, clsAttributes = [mkAttribute "x" (__"defaultX"), mkAttribute "y" (__"defaultY")]
, clsPublicMethods = newCollection' methodName $ map AnyMethod [
MkSimpleMethod
{ smName = "distance"
, smDefinition = MkMethodCompiled $ PureCode (const (__("distance defined in point")))
}]
}
point3d = newMI $ emptyMI
{ clsName = "point3d"
, clsParents = [AnyClass point]
, clsAttributes = [mkAttribute "z" (__"defaultZ")]
-- , clsPublicMethods = newCollection' methodName $ map AnyMethod [
-- MkSimpleMethod
-- { smName = "z"
-- , smDefinition = MkMethodCompiled
-- { mcBody = PureCode (const (__("z defined in point3d"))) }
-- }]
}
colorful = newMI $ emptyMI
{ clsName = "colorful"
, clsParents = [AnyClass base]
, clsAttributes = [mkAttribute "color" (__"prettyColor")]
-- , clsPublicMethods = newCollection' methodName $ map AnyMethod [
-- MkSimpleMethod
-- { smName = "color"
-- , smDefinition = MkMethodCompiled
-- { mcBody = PureCode (const (__("color defined in colorful"))) }
-- }]
}
colorful_point = newMI $ emptyMI
{ clsName = "colorful_point"
, clsParents = [AnyClass point, AnyClass colorful]
}
colorful_point3d = newMI $ emptyMI
{ clsName = "colorful_point3d"
, clsParents = [AnyClass point3d, AnyClass colorful]
}
mkbox :: forall m. (Typeable1 m, Monad m) => String -> MI m -> Invocant m
mkbox s c = MkInvocant s (class_interface c)
base_box = mkbox "base" base
point_box = mkbox "point" point
point3d_box = mkbox "point3d" point3d
colorful_box = mkbox "colorful" colorful
colorful_point_box = mkbox "colorful_point" colorful_point
colorful_point3d_box = mkbox "colorful_point3d" colorful_point3d
call :: (Typeable a, Ord a, Show a, Typeable1 m, Monad m) => String -> [a] -> MethodInvocation m
call s args = MkMethodInvocation
{ miName = s
, miArguments = mkArgs (map __ args)
}
call0 :: (Typeable1 m, Monad m) => String -> MethodInvocation m
call0 s = MkMethodInvocation
{ miName = s
, miArguments = mkArgs []
}
make_instance0 box = do
r' <- ivDispatch box (call0 "bless")
say ("instance created: " ++ (show r'))
return r'
check_methods c l = show (sort (all_methods c)) == show (sort l)
ok c msg = if c then say ("ok - " ++ msg) else say ("NOT OK - " ++ msg)
main = do
-- Create instances
base_i <- make_instance0 base_box
point_i <- make_instance0 point_box
point3d_i <- make_instance0 point3d_box
colorful_i <- make_instance0 colorful_box
colorful_point_i <- make_instance0 colorful_point_box
colorful_point3d_i <- make_instance0 colorful_point3d_box
let precedences = map class_precedence_list
[base, point, point3d, colorful, colorful_point, colorful_point3d]
correct = map (map AnyClass) [[base], [point,base], [point3d,point,base]
, [colorful,base], [colorful_point,point,colorful,base]
, [colorful_point3d,point3d,point,colorful,base]]
if precedences == correct
then say "ok - Precedences are fine."
else say "NOT OK - precedences are wrong."
let matrix =
[ (base, ["bless"] )
, (point, ["bless", "distance", "x", "y"] )
, (point3d, ["bless", "distance", "x", "y", "z"] )
, (colorful, ["bless", "color"] )
, (colorful_point, ["bless", "distance", "x", "y", "color"] )
, (colorful_point3d, ["bless", "distance", "x", "y", "color", "z"] )
]
mapM_ (\(c,ms) -> do
ok (check_methods c ms) (class_name c ++ " instance methods")
) matrix