Generating Observable code
ns codegen
(:require [scicloj.kindly.v4.kind :as kind]
(:as str])) [clojure.string
This is a draft experiment of generating Observable code from Clojure forms.
defn list-starting-with? [prefix form]
(and (list? form)
(-> form first (= prefix)))) (
defn vector-starting-with? [prefix form]
(and (vector? form)
(-> form first (= prefix)))) (
defn dot? [form]
('. form)) (list-starting-with?
defn def? [form]
('def form)) (list-starting-with?
defn viewof? [form]
('viewof form)) (list-starting-with?
defn generated? [form]
(:generated form)) (vector-starting-with?
defn generated [string]
(assert (string? string))
(:generated string]) [
defn generated->str [form]
(second form)) (
defn js? [form]
(:js form)) (vector-starting-with?
defn primitive? [form]
(or (string? form)
(number? form)
(
(boolean? form)symbol? form))) (
defn handle-form [form]
(cond (generated? form) (generated->str form)
(map? form) (->> form
(map (fn [[k v]]
(format "%s: %s"
(name k) (handle-form v))))
(", ")
(str/join format "{%s}"))
(->> form
(dot? form) (rest
map handle-form)
("."))
(str/join let [[lhs rhs] (rest form)]
(def? form) (format "%s = %s"
(name lhs)
(
(handle-form rhs)))let [[lhs rhs] (rest form)]
(viewof? form) (format "viewof %s = %s"
(name lhs)
(
(handle-form rhs)))-> form
(js? form) (second
str)
list? form) (->> form
(rest
map handle-form)
(", ")
(str/join format "%s(%s)" (-> form first name)))
(vector? form) (->> form
(map handle-form)
(", ")
(str/join format "[%s]"))
(pr-str form))) (primitive? form) (
defn obs [& forms]
(->> forms
(map handle-form)
("\n\n")
(str/join kind/observable))