Juicemacs.elisp
This subproject holds the Emacs Lisp interpreter (to be) used by Juicemacs. This document tries to provide a brief introduction of its implementation and several behaviors different from GNU Emacs Lisp.
1. Running
The build process of GNU Emacs generates a bunch of file that are crucial to the
interpreter and you will need to first build a GNU Emacs if you want this
project to do anything useful. (For example, Unicode properties and charset
mappings in Emacs are all loaded from generated .el or mapping files.)
Currently, the project can fully run through the Emacs loadup.el when run in
pbootstrap/pdump mode. You may try out a partially initialized environment
with ../app/, which contains a simple ELisp REPL.
See ../README.html for instructions.
2. Structure
Juicemacs.elisp is written with the Truffle Language Implementation Framework and loosely follows how language implementations structure their code.
party.iroiro.juicemacs.elisp.ELispLanguagedefines aTruffleLanguage, feeding user input into a parser, starting code execution.party.iroiro.juicemacs.elisp.runtime.ELispContextis a Truffle language context.party.iroiro.juicemacs.elisp.runtime.ELispGlobalsholds almost all the global elisp variables. It is a huge file, most of which is generated directly from Emacs source code.party.iroiro.juicemacs.elisp.formsholds all the built-in subroutine definitions. Most of the methods there are generated byemacs-extractorfrom Emacs sources and are yet to be implemented. (They currently simply throwUnsupportedOperationException.)The process of implementing a subroutine is quite straight-forward:
- Find the class corresponding to the subroutine
- Change its method signature to match the real subroutine
- Optionally write more
@Specializationmethods to handle all possible types - Write the code
If a subroutine is not generated yet. One will need to modify
emacs-extractorand run./gradlew :elisp:emacsGen.party.iroiro.juicemacs.elisp.forms.regexcontains a tiny regex engine that (I hope) conforms to the Emacs regex syntax.
party.iroiro.juicemacs.elisp.parserholds a lexer and a parser.party.iroiro.juicemacs.elisp.runtime.objectsholds the ELisp object definitions.party.iroiro.juicemacs.elisp.nodesand several classes inparty.iroiro.juicemacs.elisp.runtimeimplements logic to run ELisp code with Truffle. One may start fromparty.iroiro.juicemacs.elisp.nodes.ast.ELispInterpretedNodeto see how we transform a Lisp object into a dynamic AST.party.iroiro.juicemacs.elisp.nodes.bytecode(and theELispBytecodeclass) hosts classes implementing a Emacs Lisp bytecode interpreter.