clojure source code as EDN data
Clojure
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
doc
src/codn
target
test/codn
.gitignore
README.md
project.clj

README.md

codn

clojure source code as EDN data

notes:

  • this is WIP in both design and implementation, but passes all the tests inherited from tools.reader
  • the current implementation is frankenstein-ed off of clojure.tools.reader (Thanks!) and neither elegant or consistent
  • look in the test/codn/parser directory for more examples

Rationale

Clojure's built-in readers both parse source code, and interpret reader macros such as ` (syntax-quote).

This means the result of read is a) a derivative of the source code, rather than a literal representation, and b) tied to the environment in which the read is performed.

These two characteristics of clojure's readers make them unsuitable for tasks such as source code analysis, and dynamic code distribution in distributed systems.

Codn (COde as eDN) transliterates clojure source code into a strict EDN subset, allowing the source code to be treated as pure data.

Objectives

The objectives of codn are:

  • represent clojure source code as pure EDN data
  • provide a basis for source code analysis
  • provide a basis for implementing sub-codeqs in codeq
  • provide a basis for multipass analysis and compilation
  • provide a safe, analyzable basis for code exchange in distributed systems
  • cleanly interoperate with term rewriting / tree transformation libraries

It is a non-objective of codn to provide isomorphic representation of textual documents containing source code. While codn is potentially useful for IDEs and editors, the goal is not to represent the document containing the program, but the program itself.

Usage

Codn provides facilities for parsing source code into the codn format, and for reading codn data into their corresponding runtime structures.

Add codn to your project dependencies:

[codn/codn "0.1.0-SNAPSHOT"]

Parsing

load parser namespace:

(require '[codn.parser.core :as p])

Primitives return a form {:head primitive-type-keyword :value primitive-value}

(p/parse-string "a")
=> {:head :symbol, :value a}

Compound structures return a form {:head compound-type-keyword :body [components..]}

(p/parse-string "[a]")
=> {:head :vector, :body [{:head :symbol, :value a}]}

(p/parse-string "(deref a)")
=> {:head :list, :body [{:head :symbol, :value deref} {:head :symbol, :value a}]}

Reader macros and other non-EDN syntaxes are parsed into compound structures, differentiated by their :head :

(p/parse-string "`a")
=> {:head :syntax-quote, :body [{:head :symbol, :value a}]}

(p/parse-string "@a")
=> {:head :deref, :body [{:head :symbol, :value a}]}

(p/parse-string "#foo.bar[1]")
=> {:head :constructor, :body [{:head :symbol, :value foo.bar} {:head :vector, :body [{:head :integer, :value 1}]}]}

Reading

load reader namespace:

(require '[codn.reader.core :as r])

(r/read-codn '{:head :vector, :body [{:head :symbol, :value a}]})
=> [a]