atomo-0.4.0.2: src/Atomo/Kernel/Nucleus.hs
{-# LANGUAGE QuasiQuotes #-}
module Atomo.Kernel.Nucleus where
import Data.IORef
import Data.Hashable (hash)
import Data.Maybe (isJust)
import Atomo
import Atomo.Load
import Atomo.Method
import Atomo.Pattern
load :: VM ()
load = do
[p|x id|] =::: [e|x|]
[p|(x: Object) clone|] =: do
x <- here "x"
newObject [x] noMethods
[p|(x: Object) copy|] =: do
x <- here "x" >>= objectFor
ms <- liftIO (readIORef (oMethods x))
liftM (Object (oDelegates x)) (liftIO (newIORef ms))
[p|(x: Object) copy: (diff: Block)|] =:::
[e|x copy do: diff|]
[p|(x: Object) delegating-to: (y: Object)|] =: do
f <- here "x" >>= objectFor
t <- here "y"
return f
{ oDelegates = oDelegates f ++ [t]
}
[p|(x: Object) delegates-to?: (y: Object)|] =: do
x <- here "x"
y <- here "y"
return (Boolean (delegatesTo x y))
[p|(x: Object) delegates|] =: do
o <- here "x" >>= objectFor
return $ list (oDelegates o)
[p|(x: Object) with-delegates: (ds: List)|] =: do
ds <- getList [e|ds|]
x <- here "x" >>= objectFor
return x { oDelegates = ds }
[p|(x: Object) super|] =::: [e|x delegates head|]
[p|(x: Object) is-a?: (y: Object)|] =: do
x <- here "x"
y <- here "y"
liftM Boolean (isA x y)
[p|(x: Object) responds-to?: (p: Particle)|] =: do
x <- here "x"
Particle p' <- here "p" >>= findParticle
case p' of
Keyword {} ->
liftM Boolean (particleMatch p' x)
Single { mName = n } ->
liftM (Boolean . isJust) . findMethod x $
single n x
[p|x has-slot?: (name: String)|] =: do
x <- here "x" >>= objectFor
n <- getString [e|name|]
(ss, _) <- liftIO (readIORef (oMethods x))
return (Boolean (memberMap (hash n) ss))
[p|x set-slot: (name: String) to: v|] =: do
x <- here "x"
n <- getString [e|name|]
v <- here "v"
define (single n (PMatch x)) (EPrimitive Nothing v)
return v
[p|(o: Object) methods|] =: do
o <- here "o" >>= objectFor
(ss, ks) <- liftIO (readIORef (oMethods o))
[e|Object|] `newWith`
[ ("singles", list (map (list . map Method) (elemsMap ss)))
, ("keywords", list (map (list . map Method) (elemsMap ks)))
]
[p|(x: Object) dump|] =: do
o <- here "x"
liftIO (print o)
return o
[p|(x: Object) describe-error|] =::: [e|x as: String|]
[p|(s: String) as: String|] =::: [e|s|]
[p|(x: Object) as: String|] =::: [e|x show|]
[p|(x: Object) show|] =::: [e|x pretty render|]
[p|(t: Object) load: (fn: String)|] =: do
t <- here "t"
fn <- getString [e|fn|]
withTop t (loadFile fn)
return (particle "ok")
[p|(t: Object) require: (fn: String)|] =: do
t <- here "t"
fn <- getString [e|fn|]
withTop t (requireFile fn)
return (particle "ok")
particleMatch :: Particle Value -> Value -> VM Bool
particleMatch p' x = do
o <- objectFor x
mms <- liftIO (readIORef (oMethods o))
is <- gets primitives
return . maybe False (maybeMatch is p') $
lookupMap (mID p') (methods p' mms)
where
methods (Single {}) (s, _) = s
methods (Keyword {}) (_, k) = k
maybeMatch is (Single { mTarget = Just t }) ms =
any (flip (match is (Just x)) t . mTarget . mPattern) ms
maybeMatch is (Keyword { mTargets = ts }) ms =
any (all (\(Just v, pat) -> match is (Just x) pat v) . filter (isJust . fst) . zip ts . mTargets . mPattern) ms
maybeMatch _ (Single {}) _ = True