File tree 5 files changed +48
-20
lines changed
5 files changed +48
-20
lines changed Original file line number Diff line number Diff line change 17
17
(let [{:keys [expr error]} (rum/react state)]
18
18
[:div
19
19
[:h3 " Type some code!" ]
20
- [:input {:on-change (fn [evt]
21
- (let [val (get-val evt)
22
- result (try
23
- {:expr (run val)
24
- :error nil }
25
- (catch js/Error e
26
- {:error (.-message e)
27
- :expr nil }))]
28
- (swap! state
29
- (fn [old]
30
- (-> old
31
- (assoc :code val)
32
- (merge result))))))}]
20
+ [:textarea
21
+ {:auto-focus true
22
+ :on-change (fn [evt]
23
+ (let [val (get-val evt)
24
+ result (try
25
+ {:expr (run val)
26
+ :error nil }
27
+ (catch js/Error e
28
+ {:error (.-message e)
29
+ :expr nil }))]
30
+ (swap! state
31
+ (fn [old]
32
+ (-> old
33
+ (assoc :code val)
34
+ (merge result))))))
35
+ :rows 5 }]
33
36
(when expr
34
37
[:p " Result: " expr])
35
38
(when error
Original file line number Diff line number Diff line change 11
11
BLOCK = '[' TERM* ']' ;
12
12
NUM = #'\\ -?\\ d+(\\ .\\ d+)?' ;
13
13
OP = '+' | '/' | '-' | '*' | '>' | '<' | '<=' | '>=' ;
14
- TERM = (WORD | BLOCK | STR | NUM | OP) #' ?' ; " ))
14
+ TERM = (WORD | BLOCK | STR | NUM | OP) #'\\ s ?' ; " ))
15
15
16
16
(defn to-num [string]
17
17
#? (:clj (read-string string)
Original file line number Diff line number Diff line change 13
13
stack])
14
14
15
15
(def words
16
+ " Map of word names to functions that return:
17
+ [new-expressions
18
+ new-stack
19
+ new-library]"
16
20
{" +" (partial binary +)
17
21
" -" (partial binary -)
18
22
" *" (partial binary *)
22
26
" <=" (partial binary <=)
23
27
" >=" (partial binary >=)
24
28
" !=" (partial binary not=)
29
+ " def" (fn [[fn-name body & rest]]
30
+ [[]
31
+ rest
32
+ {fn-name
33
+ (if (coll? body)
34
+ body
35
+ [body])}])
25
36
" dup" (fn [stack] [[(first stack)] stack])
26
37
" dup2" (fn [stack] [(reverse (take 2 stack)) stack])
27
38
" drop" (fn [stack] [[] (rest stack)])
50
61
(defn run-word [word lib stack]
51
62
(let [task (get lib word)]
52
63
(if task
53
- (task stack)
64
+ (if (fn? task)
65
+ (task stack)
66
+ [task stack])
54
67
(let [error (str " word not found: " word)]
55
68
#?(:clj (throw (Exception. error))
56
69
:cljs (throw (js/Error. error)))))))
57
70
58
- (defn exec [stack-0 lib exprs-0]
59
- (loop [stack stack-0 exprs exprs-0]
71
+ (defn exec [stack-0 lib-0 exprs-0]
72
+ (loop [stack stack-0 exprs exprs-0 lib lib-0 ]
60
73
(let [expr (first exprs)]
61
74
(cond
62
75
(nil? expr) stack
63
76
(symbol? expr)
64
- (let [[newexprs newstack] (run-word (str expr) lib stack)]
65
- (recur newstack (concat newexprs (rest exprs))))
77
+ (let [[newexprs newstack new-lib] (run-word (str expr) lib stack)]
78
+ (recur
79
+ newstack
80
+ (concat newexprs (rest exprs))
81
+ (merge lib new-lib)))
66
82
(or (= expr true ) (= expr false ) (number? expr) (string? expr) (char? expr) (coll? expr))
67
- (recur (cons expr stack) (rest exprs))
83
+ (recur (cons expr stack) (rest exprs) lib )
68
84
true
69
85
(let [error (str " unrecognized: "
70
86
expr " of " (type expr))]
Original file line number Diff line number Diff line change 57
57
(deftest fibonacci
58
58
(is (= (run " 1 1 [dup2 +] 5 repeat" ) " 1 1 2 3 5 8 13" )))
59
59
60
+ (deftest def-word-alias
61
+ (is (= (run " 1 \" one\" def one" ) " 1" )))
62
+
63
+ (deftest def-words
64
+ (is (= (run " [1 +] \" inc\" def 2 inc" ) " 3" )))
65
+
60
66
(run-tests 'purr.core-test)
Original file line number Diff line number Diff line change 18
18
(deftest block
19
19
(is (= (parse " 1 [2 3]" ) [1 [2 3 ]])))
20
20
21
+ (deftest newlines
22
+ (is (= (parse " 1\n 2\n +" ) [1 2 '+])))
23
+
21
24
(run-tests 'purr.parse-test)
You can’t perform that action at this time.
0 commit comments