Emacs Lisp interpreter in JavaScript
Clone or download

README

Emacs Lisp implementation in JavaScript.

Copyright (c) 2009 Sami Samhuri - sami.samhuri@gmail.com

Released under the terms of the MIT license.  See the included file
LICENSE.

Latest version available on github:

    http://github.com/samsonjs/elisp.js


      Introduction
(or "You must be kidding")
==========================

The idea of editing code directly on github or bitbucket in a web
browser is pretty cool, and if you're going to do such a thing why not
use the best tools available?  IMO those tools are written in Emacs
Lisp so I would like to use them in the browser.  Maybe with some
HTML5 offline goodness thrown in.

Seeing Ymacs[1] in action[2] was also an inspiration to start this
project as I've had it on my TODO list for several months now.  Emacs
in the browser could be a reality; Ymacs is proof.

With Palm's release of "Project Ares"[3] the need for such tools is
beginning to be a reality.  I'm no longer that uncertain why such a
beast would be useful.  The question now is whether using something
like Google's Native Client and original C version of Emacs is the way
to go, or if a slower implementation in JavaScript is feasible for
real use.

[1] http://www.ymacs.org/
[2] http://www.ymacs.org/demo/
[3] http://pdnblog.palm.com/2009/12/project-ares-open-beta/
[4] http://code.google.com/p/nativeclient/


Getting Started
===============

I'm currently using CommonJS via Narwhal[1] with the JavaScriptCore
engine.  I've run the tests under v8 as well and they all pass, but
not everything is tested by any means.

[1] http://narwhaljs.org/

If you have rlwrap and narwhal then just run elisp.sh.  If not install
a JavaScript shell of your choice, and I recommend you install rlwrap
(readline wrap).  Edit elisp.sh to reflect whether or not you use
rlwrap and your shell's name or path, and then run elisp.sh.

Type a 'Q' or 'q' to quit the repl.  Or anything that starts with Q,
like 'quickly quit lisp!'.  (If lisp freaks out because you entered ^D
or something ^C or ^Z should still get you out.)

Here's an example:

% cd Projects/elisp.js
% ./elisp.sh
elisp>
(defvar *directory* "/Users/sjs" "My home directory")
nil
elisp>
*directory*
"/Users/sjs"
elisp> 
(setq foo 1 bar 2 baz 3)
3
elisp> 
(/ (+ foo bar baz) 3)
2
elisp> 
(string-match "[a-z]lurgh" (symbol-name 'foo-blurgh))
4
elisp> 
q
% 

(If you know how to print without a trailing newline in JavaScript
 please let me know.)

There are other interfaces into the parser and evaluator besides the
shortcuts.  new elisp.parser.Parser([input]) returns a parser object
and likewise new elisp.evaluator.Evaluator([exprs]) returns an
evaluator object.

Mainly toy functions that do extremely simple operations on numbers
and strings can be implemented right now.  Stay tuned, or better yet
hack away and submit a pull request on github.


What's here?
============

Not much compared to the real thing but it's a decent start for 1500
lines.

 * parser/reader. there's no lexing to tokens we go straight to tagged
   data.  (ints, floats, strings, symbols, lists, quoted expressions)

 * symbol table, but needs to be replaced ASAP.
   (functions & variables separate)

 * (broken) lexical scoping

 * expression evaluator

 * primitive types
   (string, symbol, lambda, number, cons)

 * special forms for defvar, defun, set, setq, if, and quote

 * eval/apply for atoms, function calls, and a few special forms

 * a few primitive math ops
   (thanks to JS' overloading + works on strings too)