From: Red Daly Date: Sun, 26 Jul 2009 20:22:54 +0000 (+0000) Subject: Fixed eval-when special form and added tests to prevent future breakage. X-Git-Url: https://git.hcoop.net/clinton/parenscript.git/commitdiff_plain/0f5e99ffaa8e22e253c44ccc52bb2e46da62723c Fixed eval-when special form and added tests to prevent future breakage. --- diff --git a/src/compiler.lisp b/src/compiler.lisp index d793725..9c912a1 100644 --- a/src/compiler.lisp +++ b/src/compiler.lisp @@ -170,17 +170,20 @@ compiled to an :expression (the default), a :statement, or a :symbol.")) (defun adjust-ps-compilation-level (form level) - (cond ((or (and (consp form) (eq 'progn (car form))) - (and (symbolp form) (eq :toplevel level))) - level) - ((eq :toplevel level) :inside-toplevel-form))) + "Given the current *ps-compilation-level*, LEVEL, and the fully macroexpanded +form, FORM, returns the new value for *ps-compilation-level*." + (cond ((or (and (consp form) (member (car form) + '(progn locally macrolet symbol-macrolet compile-file))) + (and (symbolp form) (eq :toplevel level))) + level) + ((eq :toplevel level) :inside-toplevel-form))) + (defmethod compile-parenscript-form :around (form &key expecting) (assert (if expecting (member expecting '(:expression :statement :symbol)) t)) (if (eq expecting :symbol) (compile-to-symbol form) - (let ((*ps-compilation-level* (adjust-ps-compilation-level form *ps-compilation-level*))) - (call-next-method)))) + (call-next-method))) (defun compile-to-symbol (form) "Compiles the given Parenscript form and guarantees that the @@ -234,22 +237,25 @@ the form cannot be compiled to a symbol." (defmethod compile-parenscript-form ((form cons) &key (expecting :statement)) (multiple-value-bind (form expanded-p) (ps-macroexpand form) - (cond (expanded-p (compile-parenscript-form form :expecting expecting)) - ((ps-special-form-p form) (apply (get-ps-special-form (car form)) (cons expecting (cdr form)))) - ((op-form-p form) - `(js:operator ,(ps-convert-op-name (compile-parenscript-form (car form) :expecting :symbol)) - ,@(mapcar (lambda (form) - (compile-parenscript-form (ps-macroexpand form) :expecting :expression)) - (cdr form)))) - ((funcall-form-p form) - `(js:funcall ,(compile-parenscript-form (if (symbolp (car form)) - (maybe-rename-local-function (car form)) - (ps-macroexpand (car form))) - :expecting :expression) - ,@(mapcar (lambda (arg) - (compile-parenscript-form (ps-macroexpand arg) :expecting :expression)) - (cdr form)))) - (t (error "Cannot compile ~S to a ParenScript form." form))))) + (let ((*ps-compilation-level* (if expanded-p + *ps-compilation-level* + (adjust-ps-compilation-level form *ps-compilation-level*)))) + (cond (expanded-p (compile-parenscript-form form :expecting expecting)) + ((ps-special-form-p form) (apply (get-ps-special-form (car form)) (cons expecting (cdr form)))) + ((op-form-p form) + `(js:operator ,(ps-convert-op-name (compile-parenscript-form (car form) :expecting :symbol)) + ,@(mapcar (lambda (form) + (compile-parenscript-form (ps-macroexpand form) :expecting :expression)) + (cdr form)))) + ((funcall-form-p form) + `(js:funcall ,(compile-parenscript-form (if (symbolp (car form)) + (maybe-rename-local-function (car form)) + (ps-macroexpand (car form))) + :expecting :expression) + ,@(mapcar (lambda (arg) + (compile-parenscript-form (ps-macroexpand arg) :expecting :expression)) + (cdr form)))) + (t (error "Cannot compile ~S to a ParenScript form." form)))))) (defvar *ps-gensym-counter* 0) diff --git a/t/ps-tests.lisp b/t/ps-tests.lisp index 239797b..3cd58dc 100644 --- a/t/ps-tests.lisp +++ b/t/ps-tests.lisp @@ -1136,3 +1136,42 @@ x1 - x1; (test-ps-js slot-value-reserved-word (slot-value foo :default) "foo['default'];") + +(test-ps-js eval-when-ps-side + (eval-when (:execute) + 5) + "5;") + +(defvar *lisp-output* nil) + +(test eval-when-lisp-side () + (setf *lisp-output* 'original-value) + (let ((js-output (normalize-js-code + (ps-doc* `(eval-when (:compile-toplevel) + (setf *lisp-output* 'it-works)))))) + (is (eql 'it-works *lisp-output*)) + (is (string= "" js-output)))) + +(defpsmacro my-in-package (package-name) + `(eval-when (:compile-toplevel) + (setf *lisp-output* ,package-name))) + +(test eval-when-macro-expansion () + (setf *lisp-output* 'original-value) + (let ((js-output (normalize-js-code + (ps-doc* `(progn + (my-in-package :cl-user) + 3))))) + (declare (ignore js-output)) + (is (eql :cl-user *lisp-output*)))) + +(test eval-when-macrolet-expansion () + (setf *lisp-output* 'original-value) + (let ((js-output (normalize-js-code + (ps-doc* `(macrolet ((my-in-package2 (package-name) + `(eval-when (:compile-toplevel) + (setf *lisp-output* ,package-name)))) + (my-in-package2 :cl-user) + 3))))) + (declare (ignore js-output)) + (is (eql :cl-user *lisp-output*))))