eval top-level

This commit is contained in:
Bobby Towers 2023-04-16 04:30:45 -07:00
parent c01a55bedd
commit 72838e060b
2 changed files with 559 additions and 29 deletions

View file

@ -488,3 +488,523 @@ cljuser> 
"(def u 7)\n\n(defn t []\n (map inc (range 8)))"
cljuser> 
#<SciVar@2a2cfbdf: "(def n 7)\n\n(defn t []\n (map inc (range n)))">
cljuser> 
(def n 7)
cljuser> 
(def n 7)
cljuser> 
(def n 7)
cljuser> 
; : count not supported on this type: Character user
cljuser> 
(def n 7)
cljuser> 
"(def n 7)"
cljuser> 
"\n\n(defn t []\n (map inc (range n)))"
cljuser> 
"(defn t []\n (map inc (range n)))"
cljuser> 
#<SciVar@1987336d:
#object[sci.impl.fns$fun$arity_1__7879 0x5abce9fb "sci.impl.fns$fun$arity_1__7879@5abce9fb"]>
cljuser> 
"(defn t []\n (map inc (range n)))"
cljuser> 
#<SciVar@2a2cfbdf: "(def n 7)\n\n(defn t []\n (map inc (range n)))">
cljuser> 
"(def n 7)\n\n(defn t []\n (map inc (range n)))"
cljuser> 
#<SciVar@6b2b5225: 3>
cljuser> 
3
cljuser> 
#<SciVar@1987336d:
#object[sci.impl.fns$fun$arity_1__7879 0x13741ba4 "sci.impl.fns$fun$arity_1__7879@13741ba4"]>
cljuser> 
#<SciVar@2a2cfbdf: "(def n 7)\n\n(defn t []\n (map inc (range n)))">
cljuser> 
(do (def n 7) (defn t [] (map inc (range n))))
cljuser> 
do
cljuser> 
(def n 7)
cljuser> 
3
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
\f
cljuser> 
\n
cljuser> 
\d
cljuser> 
\space
cljuser> 
\t
cljuser> 
\t
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
\t
cljuser> 
#<SciVar@6b2b5225: 17>
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
""
cljuser> 
" t"
cljuser> 
"(def n 7)\n\n(defn t []\n (map inc (range n)))"
cljuser> 
" t"
cljuser> 
()
cljuser> 
()
cljuser> 
" t"
cljuser> 
; : Don't know how to create ISeq from: java.lang.Character user
cljuser> 
()
cljuser> 
(\space \t)
cljuser> 
"(def n 7)\n\n(defn t []\n (map inc (range n)))"
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
(def n 7)
cljuser> 
0
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
nil
cljuser> 
nil
cljuser> 
"(def n 7)\n\n(defn t []\n (map inc (range n)))"
cljuser> 
()
cljuser> 
(\( \d \e \f \space \n \space \7 \) \newline)
cljuser> 
(\n
\space
\7
\)
\newline
\newline
\(
\d
\e
\f
\n
\space
\t
\space
\[
\]
\newline
\space
\space
\(
\m
\a
\p
\space
\i
\n
\c
\space
\(
\r
\a
\n
\g
\e
\space
\n
\)
\)
\))
cljuser> 
(\)
\newline
\newline
\(
\d
\e
\f
\n
\space
\t
\space
\[
\]
\newline
\space
\space
\(
\m
\a
\p
\space
\i
\n
\c
\space
\(
\r
\a
\n
\g
\e
\space
\n
\)
\)
\))
cljuser> 
(\(
\d
\e
\f
\space
\n
\space
\7
\)
\newline
\newline
\(
\d
\e
\f
\n
\space
\t
\space
\[
\]
\newline
\space
\space
\(
\m
\a
\p
\space
\i
\n
\c
\space
\(
\r
\a
\n
\g
\e
\space
\n
\)
\)
\))
cljuser> 
(\(
\d
\e
\f
\space
\n
\space
\7
\)
\newline
\newline
\(
\d
\e
\f
\n
\space
\t
\space
\[
\]
\newline
\space
\space
\(
\m
\a
\p
\space
\i
\n
\c
\space
\(
\r
\a
\n
\g
\e
\space
\n
\)
\)
\))
cljuser> 
(\)
\newline
\newline
\(
\d
\e
\f
\n
\space
\t
\space
\[
\]
\newline
\space
\space
\(
\m
\a
\p
\space
\i
\n
\c
\space
\(
\r
\a
\n
\g
\e
\space
\n
\)
\)
\))
cljuser> 
(\) \) \))
cljuser> 
nil
cljuser> 
"(def n 7)\n\n(defn t []\n (map inc (range n)))"
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
"((def n 7) (defn t [] (map inc (range n))))"
cljuser> 
#<SciVar@4dd7b45f: "((def n 7) (defn t [] (map inc (range n))))">
cljuser> 
1
cljuser> 
"(def n 7)"
cljuser> 
"((def n 7) (defn t [] (map inc (range n))))"
cljuser> 
((def n 7) (defn t [] (map inc (range n))))
cljuser> 
(defn t [] (map inc (range n)))
cljuser> 
("(def n 7)" "(defn t [] (map inc (range n)))")
cljuser> 
#<SciVar@4570d90e: ("(def n 7)" "(defn t [] (map inc (range n)))")>
cljuser> 
("(def n 7)" "(defn t [] (map inc (range n)))")
cljuser> 
"(defn t [] (map inc (range n)))"
cljuser> 
11
cljuser> 
(1 11)
cljuser> 
{"(def n 7)" 1, "(defn t [] (map inc (range n)))" 11}
cljuser> 
{1 "(def n 7)", 11 "(defn t [] (map inc (range n)))"}
cljuser> 
([1 "(def n 7)"] [11 "(defn t [] (map inc (range n)))"])
cljuser> 
; : Could not resolve symbol: s user
cljuser> 
10/9
cljuser> 
1
cljuser> 
5
cljuser> 
26
cljuser> 
#<SciVar@27494622:
#object[sci.impl.fns$fun$arity_1__7879 0x41fb547b "sci.impl.fns$fun$arity_1__7879@41fb547b"]>
cljuser> 
(5 26)
cljuser> 
#<SciVar@27494622:
#object[sci.impl.fns$fun$arity_1__7879 0x39376fb1 "sci.impl.fns$fun$arity_1__7879@39376fb1"]>
cljuser> 
([5 "(def n 7)"] [26 "(defn t [] (map inc (range n)))"])
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x7f499d1f "sci.impl.fns$fun$arity_2__7886@7f499d1f"]>
cljuser> 
([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"])
cljuser> 
([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"])
cljuser> 
([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"])
cljuser> 
([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"])
cljuser> 
-25
cljuser> 
25
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x6c44d57b "sci.impl.fns$fun$arity_2__7886@6c44d57b"]>
cljuser> 
([26 "(defn t [] (map inc (range n)))"] [5 "(def n 7)"])
cljuser> 
([5 "(def n 7)"] [26 "(defn t [] (map inc (range n)))"])
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x7c392ec9 "sci.impl.fns$fun$arity_2__7886@7c392ec9"]>
cljuser> 
[5 "(def n 7)"]
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x2c0e8a15 "sci.impl.fns$fun$arity_2__7886@2c0e8a15"]>
cljuser> 
("(def n 7)")
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x56770638 "sci.impl.fns$fun$arity_2__7886@56770638"]>
cljuser> 
"(def n 7)"
cljuser> 
#<SciVar@4570d90e:
#object[sci.impl.fns$fun$arity_1__7879 0x489acd41 "sci.impl.fns$fun$arity_1__7879@489acd41"]>
cljuser> 
#<SciVar@192f50c2:
#object[sci.impl.fns$fun$arity_2__7886 0x408950ad "sci.impl.fns$fun$arity_2__7886@408950ad"]>
cljuser> 
"(def n 7)"
cljuser> 
"(defn t [] (map inc (range n)))"
cljuser> 

View file

@ -14,7 +14,7 @@
(defn update-editor! [text cursor-pos]
(let [end (count (some-> cm .-state .-doc str))]
(.dispatch cm #js{:changes #js{:from 0 :to end :insert text}
:selection #js{:anchor cursor-pos :head cursor-pos}})))
:selection #js{:anchor cursor-pos :head cursor-pos}})))
(defn parse-char [level pos]
(case pos
@ -45,10 +45,40 @@
(.dispatch cm #js{:selection #js{:anchor cursor-pos :head cursor-pos}}))
true)
(defn code-str [s]
(str (rest (read-string (str "(do " s ")")))))
(defn code-seq [s]
(map str (rest (read-string (str "(do " s ")")))))
;; but we really want to find the center points, not the start points.
(defn find-center [[start s]]
[(+ start (int (/ (count s) 2))) s])
;; then just pick the one with the closest center point to the cursor,
;; and evaluate it!
(defn abs [v]
(if (neg? v) (- v) v))
(defn top-level [s pos]
(first (nfirst
(sort-by #(abs (- pos (first %)))
(map find-center
(map vector
(map #(str/last-index-of (code-str s) %) (code-seq s))
(code-seq s)))))))
(defn eval-top-level [viewer]
(let [region (str "(do " (.-doc (.-state viewer)) " )")
region (if (nil? region) nil (eval-string region))]
(if (nil? region) nil (reset! last-result region)))
(let [code (some-> cm .-state .-doc str)
cursor-pos (some-> cm .-state .-selection .-main .-head)
result (reset! last-result (eval-string (top-level code cursor-pos)))]
(update-editor! (str (subs code 0 cursor-pos)
(when-not (= "" (:result @last-result)) " => ")
(:result result)
(subs code cursor-pos))
cursor-pos))
true)
(defn eval-cell [viewer]
@ -65,11 +95,11 @@
cursor-pos (some-> cm .-state .-selection .-main .-head)
result @last-result
splits (str/split code #" => ")]
(when (not= "" @last-result)
(update-editor! (str (first splits) (subs (last splits) (count (str (:result result)))))
(when (not= "" @last-result)
(update-editor! (str (first splits) (subs (last splits) (count (str (:result result)))))
cursor-pos)
(reset! last-result "")
(reset! eval-tail ""))))
(reset! last-result "")
(reset! eval-tail ""))))
(def extension
(.of js/cv.keymap
@ -86,30 +116,10 @@
(def cm
(let [doc "(def n 7)
(defn t []
(defn r []
(map inc (range n)))"]
(js/cm.EditorView. #js {:doc doc
:extensions #js [js/cm.basicSetup, (js/lc.clojure), (.highest js/cs.Prec extension)]
:parent (js/document.querySelector "#app")})))
(set! (.-cm_instance js/globalThis) cm)
;; what is top-level, anyway?
(def u 7)
(defn t []
(map inc (range 8)))
;; ah, Peter from Calva to the rescue!
;; > Calva does not check the contents of the form in order to
;; determine it as a top-level forms:
;; *all forms not enclosed in any other form are top level forms*.
;; so there we have it!
;; we parse until we are not enclosed in a form.
;; pretty simple, actually.
;; the contents of the cell are a series of forms.
;; evaluate the last one!
;; that is, before the cursor