Skip to content

Cirru/sepal.clj

Repository files navigation

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