X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler-codegen.lisp;h=d624b0ea2b44be78f47000d644f05d9e77630bf3;hb=fc17cd58e6bd60aa129bb879e3cf7452a944384b;hp=455243089a5a8bdda0f2a987230394b8519c8ccb;hpb=354cdd2dd006c81bed209d164ef747584962b624;p=jscl.git diff --git a/src/compiler-codegen.lisp b/src/compiler-codegen.lisp index 4552430..d624b0e 100644 --- a/src/compiler-codegen.lisp +++ b/src/compiler-codegen.lisp @@ -24,6 +24,27 @@ (/debug "loading compiler-codegen.lisp!") +(defvar *js-macros* nil) +(defmacro define-js-macro (name lambda-list &body body) + (let ((form (gensym))) + `(push (cons ',name + (lambda (,form) + (block ,name + (destructuring-bind ,lambda-list ,form + ,@body)))) + *js-macros*))) + +(defun js-macroexpand (js) + (if (and (consp js) (assoc (car js) *js-macros*)) + (let ((expander (cdr (assoc (car js) *js-macros*)))) + (multiple-value-bind (expansion stop-expand-p) + (funcall expander (cdr js)) + (if stop-expand-p + expansion + (js-macroexpand expansion)))) + js)) + + (defconstant no-comma 12) (defvar *js-output* t) @@ -178,9 +199,12 @@ (case (length (cdr form)) (1 `(unary- ,(cadr form))) (t (reduce (lambda (x y) `(- ,x ,y)) (cdr form))))) + ((and or) + (reduce (lambda (x y) `(,(car form) ,x ,y)) (cdr form))) ((progn comma) (reduce (lambda (x y) `(comma ,x ,y)) (cdr form) :from-end t)) - (t form)) + (t + (js-macroexpand form))) form)) (defun js-operator-expression (op args precedence associativity operand-order) @@ -349,7 +373,7 @@ (t `(group ,@(cdr form)))))) (t - form))) + (js-macroexpand form)))) (defun js-stmt (form &optional parent) (let ((form (js-expand-stmt form))) @@ -373,9 +397,11 @@ (js-format ":") (js-stmt `(progn ,@body)))) (break - (destructuring-bind (label) (cdr form) - (js-format "break ") - (js-identifier label) + (destructuring-bind (&optional label) (cdr form) + (js-format "break") + (when label + (js-format " ") + (js-identifier label)) (js-format ";"))) (return (destructuring-bind (value) (cdr form) @@ -419,6 +445,25 @@ (js-expr condition) (js-format ")") (js-stmt `(progn ,@body)))) + (switch + (destructuring-bind (value &rest cases) (cdr form) + (js-format "switch(") + (js-expr value) + (js-format "){") + (dolist (case cases) + (cond + ((and (consp case) (eq (car case) 'case)) + (js-format "case ") + (let ((value (cadr case))) + (unless (or (stringp value) (integerp value)) + (error "Non-constant switch case `~S'." value)) + (js-expr value)) + (js-format ":")) + ((eq case 'default) + (js-format "default:")) + (t + (js-stmt case)))) + (js-format "}"))) (for (destructuring-bind ((start condition step) &body body) (cdr form) (js-format "for (")