-
Notifications
You must be signed in to change notification settings - Fork 1
/
mode.cljc
75 lines (54 loc) · 1.46 KB
/
mode.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
(ns fif.stack-machine.mode
"Includes functions for creating mode functions within the stack
machine."
(:require
[fif.stack-machine :as stack]
[fif.stack-machine.stash :as stash]))
(def default-mode-stash
{::flag nil
::state {}})
(defn new-mode-stash
[sm flag state]
(let [init-stash
(assoc default-mode-stash
::flag flag
::state state)]
(-> sm (stash/new-stash init-stash))))
(defn enter-mode
([sm flag state]
(-> sm
(stack/push-flag flag)
(new-mode-stash flag state)))
([sm flag] (enter-mode sm flag {})))
(defn exit-mode
[sm]
(-> sm
stack/pop-flag
stash/remove-stash))
(defn set-state
[sm state]
(stash/update-stash assoc ::state state))
(defn update-state
[sm f & args]
(apply stash/update-stash sm update-in [::state] f args))
(def update-stash stash/update-stash)
(defn get-mode-stash
[sm]
(-> sm stash/peek-stash))
;; TODO: have it check if the stash goes missing, and assign to an
;; error state dispatch.
(defn mode-dispatch-fn
"Function used with defmulti for stack mode dispatch based on state
stored in the stash. This is used in tandom with `enter-mode` and
`exit-mode`."
[sm]
(-> sm stash/peek-stash ::state))
(comment
(defmulti functional-mode mode-dispatch-fn)
(defmethod functional-mode {}
[sm]
(-> sm
(set-state {:op ::reduce})))
(defmethod functional-mode {:op ::reduce}
[sm]
(comment do-stuff)))