Fixed 'lisp' form to produce code that captures enclosing lexical scope correctly...
authorVladimir Sedach <vsedach@gmail.com>
Sun, 12 Apr 2009 01:57:19 +0000 (19:57 -0600)
committerVladimir Sedach <vsedach@gmail.com>
Sun, 12 Apr 2009 23:10:18 +0000 (17:10 -0600)
src/printer.lisp
src/special-forms.lisp
t/ps-tests.lisp

index 39dcc09..ef77c6f 100644 (file)
@@ -361,6 +361,7 @@ arguments, defines a printer for that form using the given body."
   (psw #\)))
 
 (defprinter js:escape (literal-js)
+  ;; literal-js should be a form that evaluates to a string containing valid JavaScript
   (psw literal-js))
 
 ;;; named statements
index 3841f6f..ad49e28 100644 (file)
@@ -718,9 +718,7 @@ lambda-list::=
 (define-ps-special-form regex (regex)
   `(js:regex ,(string regex)))
 
-(defpsmacro lisp (&body forms)
-  "Evaluates the given forms in Common Lisp at ParenScript
-macro-expansion time. The value of the last form is treated as a
-ParenScript expression and is inserted into the generated Javascript
-\(use nil for no-op)."
-  (eval (cons 'progn forms)))
+(define-ps-special-form lisp (lisp-form)
+  ;; (ps (foo (lisp bar))) is in effect equivalent to (ps* `(foo ,bar))
+  ;; when called from inside of ps*, lisp-form has access only to the dynamic environment (like for eval)
+  `(js:escape (ps1* ,lisp-form)))
index 4e61258..86bc5c2 100644 (file)
@@ -785,3 +785,15 @@ try {
 (test-ps-js literal-array-1
   '(1 foo 3)
   "[1, 'foo', 3]")
+
+(test ps-lisp-expands-in-lexical-environment
+  (is (string= "5;" (let ((x 5)) (ps (lisp x))))))
+
+(test ps*-lisp-expands-in-null-lexical-environment
+  (signals error (let ((x 5)) (ps* '(lisp x)))))
+
+(test ps*-lisp-expands-in-dynamic-environment
+  (is (string= "1 + 2;" (let ((*print-level* 2)) (ps* '(+ 1 (lisp *print-level*)))))))
+
+(test ps-lisp-dynamic-environment
+  (is (string= "1 + 2;" (let ((*print-level* 2)) (ps (+ 1 (lisp *print-level*)))))))