A Lisp-to-Javascript compiler bootstrapped from Common Lisp
@PuercoPop
(defvar *source*
'(("boot" :target)
("compat" :host)
("setf" :target)
("utils" :both)
("defstruct" :both)
("lambda-list" :both)
("numbers" :target)
("char" :target)
("list" :target)
("array" :target)
("string" :target)
("sequence" :target)
("stream" :target)
("hash-table" :target)
("print" :target)
("misc" :target)
("ffi" :target)
("symbol" :target)
("package" :target)
("read" :both)
("conditions" :both)
("backquote" :both)
("compiler"
("codegen" :both)
("compiler" :both))
("documentation" :target)
("toplevel" :target)))
;; Tests
(compile-application (append (directory "tests.lisp")
(directory "tests/*.lisp")
(directory "tests-report.lisp"))
(merge-pathnames "tests.js" *base-directory*))
;; Web REPL
(compile-application (list #P"repl-web/repl.lisp")
(merge-pathnames "repl-web.js" *base-directory*))
;; Node REPL
(compile-application (list #P"repl-node/repl.lisp")
(merge-pathnames "repl-node.js" *base-directory*))(defun compile-application (files output)
(with-compilation-environment
(with-open-file (out output :direction :output :if-exists :supersede)
(format out "(function(jscl){~%")
(format out "'use strict';~%")
(format out "(function(values, internals){~%")
(dolist (input files)
(!compile-file input out))
(format out "})(jscl.internals.pv, jscl.internals);~%")
(format out "})( typeof require !== 'undefined'? require('./jscl'): window.jscl )~%"))))
(defmacro async (&body body)
`(#j:setTimeout (lambda () ,@body)))
;; Retrieve a property
(defun length (array)
(oget array "length"))
;; Set a property
(setf (oget my-array 2) "foo")
(let ((obj (new)))
(setf (oget obj "a") 1) obj)
;; Retrieve a variable
(%js-vref "window")
;; Set a variable
(%js-vset "eval_in_lisp"
(lambda (form) (eval (read-from-string form))))Compilador
Tradicionalmente
Lexer -> Parser -> AST -> AST -> Codegen
Lisp
Read -> Macroexpansion -> Compile
define-raw-builtin
define-builtin
literales
operadores
special forms?