Eisen as a Domain Specific Language - blancas/eisen GitHub Wiki
The Eisen core language is small; it contains the most basic functions:
- Module and import
- Value declarations
- Function definitions (including forward declarations)
- Let and letrec constructs
- Logical and arithmetic infix expressions
- Sequenced expressions
On top of this basic functions the namespace blancas.eisen.clojure adds language constructs that correspond to Clojure's special forms and macros. They are included by the core function init-eisen, though the use of this function is up to the host program, which may use it as is, install language features from a custom function, or something altogether different.
We recommend studying the code in blancas.eisen.clojure to have a better idea of how new custom features may take advantage of the compiler's existing code. The implementation of language constructs in there is modular and designed around the main functions of parsing and translation for each construct.
The extensibility features of the library make it possible to take an existing Clojure DSL and give it a syntax that is free from the restrictions of S-expressions. Many macros can be used without modification from Eisen as any other imported function. In these cases, it is convenient to just take advantage of this reuse. For other macros, however, having their own syntax can improve their usability and make them easier to learn, especially for end users.
Extensibility Functions
The following functions support the extensibility of the core Eisen language. Examples of their use may be found in other pages under this section of the guide.
add-epression Adds a language construct that is parsed and translated in the context of an expression or sub-expression. It takes a unique token as a Clojure keyword, the parsing function, the translation function, and zero or more words to be reserved.
add-declaration Adds a language construct that is parsed and translated in the context of a top-level declaration. It takes a unique token as a Clojure keyword, the parsing function, the translation function, and zero or more words to be reserved.
init-eisen installs the language constructs defined in the blancas.eisen.clojure namespace. It also adds references from the eisen.user module to common Clojure functions, but with camel-case names to avoid backquotes.
Compiler Hooks
There are two hooks available to the host program.
blancas.eisen.parser/ast-hook takes a single argument. The parser calls this function before returning the AST as the result of the core function parse-eisen. Using dynamic binding, a host program may apply transformations to the resulting AST.
blancas.eisen.parser/code-hook takes a single argument. The translator calls this function before returning the translated code is evaluated in Clojure by calls to Eisen core functions eisen, eisen=, and eisenf. Using dynamic binding, a host program may apply further transformations to the generated code.