tromey / el-compilador Goto Github PK
View Code? Open in Web Editor NEWAn SSA-based compiler for Emacs Lisp
An SSA-based compiler for Emacs Lisp
el-compile should use #!/bin/sh
and then a line like
:; exec emacs --script $0
The C back end assumes that a few special functions can be defined by Emacs to implement primitives like catch
. See elcomp--c-direct-renames
... the names here are invented and can be changed, but what is important is implementing these in the C core.
:elcomp-fetch-condition
: evaluates to the error value in the error branch of a condition-case
:save-excursion-save
and :save-excursion-restore
: save and restore excursion data. These might be very easy based on the implementation of Fsave_excursion
:save-restriction-save
, :save-restriction-restore
: Ditto for restrictions. Also maybe easy.:unwind-protect-continue
: Called at the end of an unwind-protect
to re-throw the exception in flight:catch-value
: Return the value thrown via throw
PUSH_HANDLER
is emitted in various spots but is gone from lisp.h
handler_matches
: emitted by elcomp--c-emit-condition-case
to handle case matchingCurrently el-compile
knows to handle eval-when-compile
but it also needs some special treatment for defvar
(mark as special), defmacro
, and defsubst
. Maybe special treatment for defconst
would also be valuable.
Consider this code:
(elcomp--do '(
(defun test-case ()
(let ((i 0) (s 0))
(while (<= i 10000000)
(setq s (+ s i))
(setq i (1+ i)))
))
)
;; #'elcomp--c-translate
)
Here the compiler should be able to entirely eliminate the loop.
The el-compile
script currently doesn't really do command-linen processing. It should at least accept a list of .el files and an optional C output file name.
See this branch: https://github.com/tromey/emacs/tree/comment-cache
This rewrites some Emacs primitives from C into elisp; the next step is to build these with el-compile, check in the generated file, and integrate into the build
elcomp should support the emacs-ffi API so that the C back end can compile code using it directly to the expected C.
The C back end should recognize the "private function" idiom and generate direct calls to functions start with package--
.
Maybe more practical than #13 is changing the Emacs build to run el-compile
on the various .el
files that are dumped, convert them to C, then compile them and relink.
We can completely eliminate a catch
if it is "lexical". cl-return
and cl-return-from
could be handled this way.
The C output for a simple unwind-protect
case, like:
; -*- lexical-binding:t -*-
(defun x ()
(save-excursion
(message "hi")))
Ends up with:
PUSH_HANDLER (h1, Qnil, UNWIND_PROTECT);
if (sys_setjmp (h1->jmp))
{
handlerlist = handlerlist->next;
goto BB_1;
}
...
BB_1:
handlerlist = handlerlist->next;
One of these is redundant.
The compiler can emit an indirect call via Qlsh
, but this is a good candidate for a direct call. There may be other simple math operations like this to check.
Recently I began thinking about improving the built-in Emacs optimizer by converting lap code into SSA form, doing usual optimisations and converting back into lap code (or simplified Elisp).
Eventually I stumbled upon your project. It looks almost done, with everything ready, only one more backend needed.
So, I have a few of questions:
Thank you!
Hello,
I'm interested in Lisp compiler technology. I see you chose the SSA framework for your compiler. Some other compilers for functional-ish languages use CPS. Do you have an opinion on whether SSA or CPS is best suited for compiling Lisp?
Currently length
(e.g.) is marked as :elcomp-direct
. This is good but it could go farther by using type inference information. For example, length
could lower to various macros like ASIZE
or SCHARS
.
The into-ssa pass is pretty bad. Maybe this paper could be used to make it better: http://compilers.cs.uni-saarland.de/papers/bbhlmz13cc.pdf
The C back end will generate an invalid C string for "\t\r\n "
Currently there's no test suite but there should be one. It's not totally clear how it should work -- pattern-match the expected IR? Write an interpreter for the IR, then interpret various test cases?
I tried compiling json--plist-reverse
. The compiler doesn't initialize a variable near the top.
BB_0:
res_219 = Qnil;
if (!NILP (plist_220))
{
goto BB_3;
}
Here plist_220
should be initialized from plist
.
The null
function could be compiled to NILP(x) ? Qt : Qnil
. Commented out in c-inl.el
Some uses of regular expressions could be compiled to inline code. Some ideas:
looking-at-p
exists; maybe some other macros could be written to make this a bit betterlex-parse-re
from the lex
package to parse a regexp to rx syntaxIs there a design to attach different front ends?
A "non-primitive" constant, like a list, is currently not handled by the C back end. It should emit init code to construct the object and then simply refer to the symbol as needed.
Consider if json--decode-utf16-surrogates
checked the input types:
(defun json--decode-utf-16-surrogates (high low)
"Return the code point represented by the UTF-16 surrogates HIGH and LOW."
(cl-check-type high integer)
(cl-check-type low integer)
(+ (lsh (- high #xD800) 10) (- low #xDC00) #x10000))
This should compile to some ordinary arithmetic. Instead the compiler emits calls to Fminus
, Qlsh
, etc.
Maybe the C back end should not use DEFUN
but instead emit doc strings a different way? The current approach seems to require extra build steps.
Is it possible to make standalone executables with this?
That would open up a whole lot of possibilities..
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.