Sunday, May 8, 2011

Compiling, linking, and loading in EdgeLisp

EdgeLisp now has first-class object files (called FASL, for Fast-Loadable) and a primitive linker:

Let's compile a FASL from a piece of code:

(defvar fasl (compile #'(print "foo")))
#[fasl [{"execute":"((typeof _lisp_function_print !== \"undefined\" ? _lisp_function_print : lisp_undefined_identifier(\"print\", \"function\", undefined))(null, \"foo\"))"}]]

(Note that EdgeLisp uses #' and #` for code quotation.)

The FASL contains the compiled JavaScript code of the expression (print "foo").

We can load that FASL, which prints foo.

(load fasl)

Let's create a second FASL:

(defvar fasl-2 (compile #'(+ 1 2)))
#[fasl [{"execute":"((typeof _lisp_function_P !== \"undefined\" ? _lisp_function_P : lisp_undefined_identifier(\"+\", \"function\", undefined))(null, (lisp_number(\"+1\")), (lisp_number(\"+2\"))))"}]]

(load fasl-2)

Using link we can concatenate the FASLs, combining their effects:

(defvar linked-fasl (link fasl fasl-2))
(load linked-fasl)

Compile-time effects

Fasls keep separate the runtime and the compile-time effects of code.

For example, a macro definition returns nil at runtime, and does its work at compile-time (edited for readability):

(compile #'(defmacro foo () #'bar))
#[fasl [

(typeof _lisp_variable_nil !== "undefined" ? _lisp_variable_nil : lisp_undefined_identifier("nil", "variable", undefined))

((typeof _lisp_function_Nset_macro_function !== "undefined" ? _lisp_function_Nset_macro_function : lisp_undefined_identifier("%set-macro-function", "function", undefined))(null, "foo", (function(_key_, _lisp_variable_NNform){ lisp_arity_min_max(arguments.length, 2, 2); return (((typeof _lisp_function_Ncompound_apply !== "undefined" ? _lisp_function_Ncompound_apply : lisp_undefined_identifier("%compound-apply", "function", undefined))(null, (function(_key_){ lisp_arity_min_max(arguments.length, 1, 1); return (((new Lisp_identifier_form("bar")))); }), ((typeof _lisp_function_Ncompound_slice !== "undefined" ? _lisp_function_Ncompound_slice : lisp_undefined_identifier("%compound-slice", "function", undefined))(null, (typeof _lisp_variable_NNform !== "undefined" ? _lisp_variable_NNform : lisp_undefined_identifier("%%form", "variable", undefined)), (lisp_number("+1"))))))); }))) ]]

No comments: