/sepal.clj

Generate Clojure syntax from vectors

Primary LanguageCirru

Cirru Sepal for Clojure

Generates Clojure code from EDN, based on FIPP. This is the essential library for bridging Cirru to Clojure.

Usages Clojars Project

[cirru/sepal "0.2.9"]
; generates an expression
(cirru-sepal.core/make-string ["println" ["+" "2" "2"]]) ; => string

; generates scripts, i.e. containing multiple expressions
(cirru-sepal.core/write-code [["println" ["+" "2" "2"]]]) ; => string

For example:

[ "defn" "f1" [ "x" ]
  [ "+" "x" "1" ] ]

runs through make-string and it generates:

(defn f1 [x] (+ x 1))

Supposed syntax

Special forms:

  • []
  • {}
  • #{}
  • ; and ;;(for comment)
  • case
  • def
  • defn, defn$(with arity overloading)
  • defn-, defn$-(with arity overloading)
  • fn, fn$(with arity overloading)
  • fn*, #()
  • let
  • loop
  • ns
  • doseq

Special syntax:

  • "str and |str generates "str"
  • #"x generates #"x"

For example, maps,

(def demo {:a 1, :b [2], :c {:d 4}})

(def demo2 {:a 1, :b [2], :c {:d 4}})

(def demo-3 {(f) (f), (g) (g)})

(get demo :a)

(:a demo)

can be generated with:

[
  ["def" "demo"
    ["{}" [":a" "1"] [":b" ["[]" "2"]] [":c" ["{}" [":d" "4"]]]]]

  ["def" "demo2" ["{}" ":a" "1" ":b" ["[]" "2"] ":c" ["{}" ":d" "4"]]]

  ["def" "demo-3" ["{}" [["f"] ["f"]] [["g"] ["g"]]]]

  ["get" "demo" ":a"]

  [":a" "demo"]
]

and for structures with pairs in syntax,

(cond (< a 1) "little" (> a 1) "great" :else "so-so")

(let [a 1, b (+ 1 1)] (+ a b))

(loop [a 0, b 1] (+ a b))

(doseq [x xs, y ys] (println x y))

can be generated with:

[
  ["cond"
    [["<" "a" "1"] "|little"]
    [[">" "a" "1"] "|great"]
    [":else" "|so-so"]]

  ["let"
    [["a" "1"] ["b" ["+" "1" "1"]]]
    ["+" "a" "b"]]

  ["loop"
    [["a" "0"] ["b" "1"]]
    ["+" "a" "b"]]

  ["doseq"
    [["x" "xs"] ["y" "ys"]]
    ["println" "x" "y"]]
]

Find more examples in data/.

File Mode

write-file generates a whole file with namespaces and definitions, also bare scripts.

(cirru-sepal.analyze/write-file {:ns ["ns" "a.b"],
                                 :proc [],
                                 :defs {:main! ["defn" "main!" ["a" "b"]]}})

Notice this structure, :defs holds all defn def defonce forms. There might be dependencies among each function, this library tries detect dependenies of function and sort functions in a right order. (declare some-function) will be inserted when potential circular dependencies is detected.

Test

yarn test

Acknowledgements

License

MIT