X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler-codegen.lisp;h=9bb915d399b0cb846ab45f8eb46edec5bc02698a;hb=5f9371f19ae17198175d48540f3b06f168e10760;hp=480a856bfb9c0ccb256b5fddc4935202b8f7c61a;hpb=a5cea857580c1060f4e7d7aa3ec6d800e8e7b5cd;p=jscl.git diff --git a/src/compiler-codegen.lisp b/src/compiler-codegen.lisp index 480a856..9bb915d 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) @@ -182,16 +203,14 @@ (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) (let ((op1 (car args)) (op2 (cadr args))) (case op - ;; Transactional compatible operator - (code - (js-format "~a" (apply #'code args))) ;; Accessors (property (js-expr (car args) 0) @@ -351,7 +370,7 @@ (t `(group ,@(cdr form)))))) (t - form))) + (js-macroexpand form)))) (defun js-stmt (form &optional parent) (let ((form (js-expand-stmt form))) @@ -367,8 +386,6 @@ (js-format ";"))) (t (case (car form) - (code - (js-format "~a" (apply #'code (cdr form)))) (label (destructuring-bind (label &body body) (cdr form) (js-identifier label) @@ -429,16 +446,18 @@ (js-expr value) (js-format "){") (dolist (case cases) - (destructuring-bind (x &body body) case - (if (eq x 'default) - (js-format "default: ") - (progn - (unless (or (stringp x) (numberp x)) - (error "Non-constant switch case `~S'." (car cases))) - (js-format "case ") - (js-expr x) - (js-format ":"))) - (mapc #'js-stmt body))) + (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)