Factor show out to its own package.

This commit is contained in:
Scott Richmond 2022-04-25 20:21:23 -04:00
parent 6f16495aab
commit 19a0e7e3d5
2 changed files with 69 additions and 2 deletions

View File

@ -1,6 +1,7 @@
(ns ludus.prelude
(:require
[ludus.data :as data]))
[ludus.data :as data]
[ludus.show]))
(def eq {:name "eq"
::data/type ::data/clj
@ -44,6 +45,17 @@
(println (apply str args))
:ok)})
(declare show)
(defn- show-vector [v]
(if (= (first v) ::data/tuple)
(str "(" (apply str (into [] (comp (map (:body show)) (interpose ", ")) (next v))) ")")
(str "[" (apply str (into [] (comp (map (:body show)) (interpose ", ")) v)) "]")))
(def show {:name "show"
::data/type ::data/clj
:body ludus.show/show})
(def prelude {"eq" eq
"add" add
"panic!" panic!
@ -53,4 +65,5 @@
"div" div
"inc" inc-
"dec" dec-
"not" not})
"not" not
"show" show})

54
src/ludus/show.clj Normal file
View File

@ -0,0 +1,54 @@
(ns ludus.show
(:require
[ludus.data :as data]
[clojure.pprint :as pp]))
(declare show show-linear show-keyed)
(defn- show-vector [v]
(if (= (first v) ::data/tuple)
(str "(" (apply str (into [] show-linear (next v))) ")")
(str "[" (apply str (into [] show-linear v)) "]")))
;; TODO:
(defn- show-map [v]
(cond
(or (= (::data/type v) ::data/fn)
(= (::data/type v) ::data/clj))
(str "fn " (:name v))
(= (::data/type v) ::data/ns)
(str "ns " (::data/name v) " {"
(apply str (into [] show-keyed (dissoc v ::data/struct ::data/type ::data/name)))
"}")
(::data/struct v)
(str "@{" (apply str (into [] show-keyed (dissoc v ::data/struct))) "}")
:else
(str "#{" (apply str (into [] show-keyed v)) "}")
))
(defn- show-set [v]
(str "${" (apply str (into [] show-linear v)) "}"))
(defn show [v]
(cond
(string? v) (str "\"" v "\"")
(number? v) (str v)
(keyword? v) (str v)
(boolean? v) (str v)
(nil? v) "nil"
(vector? v) (show-vector v)
(set? v) (show-set v)
(map? v) (show-map v)
:else (with-out-str (pp/pprint v))))
(def show-linear (comp (map show) (interpose ", ")))
(def show-keyed (comp
(map #(str (show (first %)) " " (show (second %))))
(interpose ", ")))
(show {::data/type ::data/fn :name "foo"})