Start implementing EH stdlib
This commit is contained in:
36
src/cljs/emptyhead/newlib/delegate.cljs
Normal file
36
src/cljs/emptyhead/newlib/delegate.cljs
Normal file
@@ -0,0 +1,36 @@
|
||||
(ns emptyhead.newlib.delegate
|
||||
"Delegation: treat one message as though it were another, enabling behaviour sharing and polymorphism."
|
||||
(:require [emptyhead.thought.crud :as thought]
|
||||
[emptyhead.idea.crud :as idea]
|
||||
[emptyhead.thought.define :as def]
|
||||
[emptyhead.thought.eval :as eval]
|
||||
[emptyhead.thought.extend :as extend]
|
||||
[emptyhead.newlib.core]))
|
||||
|
||||
(defn remove-delegate
|
||||
"Undelegate `del` from `msg`."
|
||||
[msg del]
|
||||
(let [remover (thought/register-thought! [:EH :CORE :NOP] :ext-stages [[:EH :MSG :REMOVE-DELEGATE msg del]])]
|
||||
(eval/execute! remover)))
|
||||
|
||||
;; FIXME Delegate order is currently undefined! Give this a proper order.
|
||||
(defn add-delegate
|
||||
"Register `del` as a delegate for `msg`: implementations defined for `del` will now run trigger on `msg` as well.
|
||||
For instance, if message =(:foo :bar)= is defined and we =(add-delegate :quux :bar)= then =(:foo :quux)= will alias to =(:foo :bar)=.
|
||||
Note that this also works on the left hand side."
|
||||
[msg del]
|
||||
(remove-delegate msg del)
|
||||
(let [delegator (thought/register-thought!
|
||||
[:EH :IO :RETURN]
|
||||
:data del
|
||||
:transient false)
|
||||
remover (thought/register-thought! [:EH :IDEA :FORGET] :data delegator)]
|
||||
(extend/register-extension! delegator [:EH :MSG :DELEGATE msg])
|
||||
(extend/register-extension! remover [:EH :MSG :REMOVE-DELEGATE msg del])))
|
||||
|
||||
(defn get-delegates
|
||||
"Get possible delegates for `msg`."
|
||||
[msg]
|
||||
(let [stage [:EH :MSG :DELEGATE msg]]
|
||||
(-> (thought/register-thought! [:EH :CORE :CONTAINER] :ext-stages [stage])
|
||||
eval/execute! thought/pop-stack second)))
|
||||
Reference in New Issue
Block a user