Fix dynamic returns getting precedence over lexical ones
[parenscript.git] / tests / output-tests.lisp
blob26764e24fc476f8e0f2b91600e1e3399b412c70c
1 ;;; Copyright 2005-2006 Henrik Hjelte
2 ;;; Copyright 2007-2012 Vladimir Sedach
4 ;;; SPDX-License-Identifier: BSD-3-Clause
6 ;;; Redistribution and use in source and binary forms, with or
7 ;;; without modification, are permitted provided that the following
8 ;;; conditions are met:
10 ;;; 1. Redistributions of source code must retain the above copyright
11 ;;; notice, this list of conditions and the following disclaimer.
13 ;;; 2. Redistributions in binary form must reproduce the above
14 ;;; copyright notice, this list of conditions and the following
15 ;;; disclaimer in the documentation and/or other materials provided
16 ;;; with the distribution.
18 ;;; 3. Neither the name of the copyright holder nor the names of its
19 ;;; contributors may be used to endorse or promote products derived
20 ;;; from this software without specific prior written permission.
22 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
27 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 ;;; POSSIBILITY OF SUCH DAMAGE.
36 (in-package #:parenscript.tests)
37 (named-readtables:in-readtable :parenscript)
39 (fiveam:in-suite output-tests)
41 (test-ps-js statements-and-expressions-1
42 (+ i (if 1 2 3))
43 "i + (1 ? 2 : 3);")
45 (test-ps-js statements-and-expressions-2
46 (if 1 2 3)
47 "if (1) {
49 } else {
51 };")
53 (test-ps-js symbol-conversion-1
54 !?#@%
55 "bangwhathashatpercent;")
57 (test-ps-js symbol-conversion-2
58 bla-foo-bar
59 "blaFooBar;")
61 (test-ps-js symbol-conversion-3
62 *array
63 "Array;")
65 (test-ps-js symbol-conversion-4
66 *global-array*
67 "GLOBALARRAY;")
69 (test-ps-js symbol-conversion-5
70 encodeURIComponent
71 "encodeURIComponent;")
73 (test-ps-js symbol-conversion-6
74 URI
75 "URI;")
77 (test-ps-js number-literals-1
79 "1;")
81 (test-ps-js number-literals-2
82 123.123
83 "123.123;")
85 (test-ps-js number-literals-3
86 #x10
87 "16;")
89 (test-ps-js string-literals-1
90 "foobar"
91 "'foobar';")
93 (test-ps-js string-literals-2
94 "bratzel bub"
95 "'bratzel bub';")
97 (test-ps-js string-literals-3
98 " "
99 "'\\t';")
101 (test-ps-js array-literals-1
102 (array)
103 "[];")
105 (test-ps-js array-literals-2
106 (array 1 2 3)
107 "[1, 2, 3];")
109 (test-ps-js array-literals-3
110 (array (array 2 3)
111 (array "foobar" "bratzel bub"))
112 "[[2, 3], ['foobar', 'bratzel bub']];")
114 (test-ps-js array-literals-4
115 (make-array)
116 "new Array();")
118 (test-ps-js array-literals-5
119 (make-array 1 2 3)
120 "new Array(1, 2, 3);")
122 (test-ps-js array-literals-6
123 (make-array
124 (make-array 2 3)
125 (make-array "foobar" "bratzel bub"))
126 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
128 (test-ps-js array-init-1
129 (make-array 2 :initial-contents '(10 20))
130 "(function () {
131 var arr1 = new Array(2);
132 var init2 = [10, 20];
133 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
134 arr1[i4] = init2[i4];
136 __PS_MV_REG = [];
137 return arr1;
138 })();")
140 (test-ps-js array-init-2
141 (make-array 5 :initial-element 10)
142 "(function () {
143 var arr1 = new Array(5);
144 var elt3 = 10;
145 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
146 arr1[i4] = elt3;
148 __PS_MV_REG = [];
149 return arr1;
150 })();")
152 (test-ps-js object-literals-1
153 (create foo "bar" :blorg 1)
154 "{ foo : 'bar', 'blorg' : 1 };")
156 (test-ps-js object-literals-2
157 (create foo "hihi"
158 blorg (array 1 2 3)
159 another-object (create :schtrunz 1))
160 "{ foo : 'hihi',
161 blorg : [1, 2, 3],
162 anotherObject : { 'schtrunz' : 1 } };")
164 (test-ps-js object-literals-3
165 (getprop an-object 'foo)
166 "anObject.foo;")
168 (test-ps-js object-literals-4
169 (@ an-object foo bar)
170 "anObject.foo.bar;")
172 (test-ps-js object-literals-5
173 (with-slots (a b c) this
174 (+ a b c))
175 "this.a + this.b + this.c;")
177 (test-ps-js with-slots-single-eval
178 (lambda () (with-slots (a b) (foo) (+ a b)))
179 "function () {
180 var object1 = foo();
181 __PS_MV_REG = [];
182 return object1.a + object1.b;
183 };")
185 (test-ps-js object-literal-quoted-symbols
186 (create 'test "bang" 'symbol-saved-my-life "parenscript")
187 "{ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' };")
189 (test-ps-js object-literal-property-accessors
190 (defun foo ()
191 (let ((x 10))
192 (create (get x) x
193 (set x v) (setf x v))))
194 "function foo() {
195 var x = 10;
196 return { get x() {
197 return x;
198 }, set x(v) {
199 return x = v;
200 } };
202 :js-target-version "1.8.5")
204 (test-ps-js object-method-apply-1
205 (apply (@ an-object foo) nil)
206 "anObject.foo.apply(anObject, null);")
208 (test-ps-js object-method-apply-2
209 (apply (getprop (make-an-object) foo 'bar) nil)
210 "(function () {
211 var _js1 = makeAnObject()[foo];
212 var _js2 = _js1.bar;
213 __PS_MV_REG = [];
214 return _js2.apply(_js1, null);
215 })();")
217 (test-ps-js object-method-apply-3
218 (apply (@ (make-an-object) foo) (bar))
219 "(function () {
220 var _js1 = makeAnObject();
221 var _js2 = _js1.foo;
222 __PS_MV_REG = [];
223 return _js2.apply(_js1, bar());
224 })();")
226 (test-ps-js regular-expression-literals-1
227 (regex "foobar")
228 "/foobar/;")
230 (test-ps-js regular-expression-literals-2
231 (regex "/foobar/i")
232 "/foobar/i;")
234 (test-ps-js literal-symbols-1
236 "true;")
238 (test-ps-js literal-symbols-2
239 false
240 "false;")
242 (test-ps-js literal-symbols-3
244 "false;")
246 (test-ps-js literal-symbols-4
247 (lambda () nil)
248 "function () {
249 return null;
250 };")
252 (test-ps-js literal-symbols-5
253 undefined
254 "undefined;")
256 (test-ps-js literal-symbols-6
257 this
258 "this;")
260 (test-ps-js variables-1
261 variable
262 "variable;")
264 (test-ps-js variables-2
265 a-variable
266 "aVariable;")
268 (test-ps-js variables-3
269 *math
270 "Math;")
272 (test-ps-js function-calls-and-method-calls-1
273 (blorg 1 2)
274 "blorg(1, 2);")
276 (test-ps-js function-calls-and-method-calls-2
277 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
278 "foobar(blorg(1, 2), blabla(3, 4), [2, 3, 4]);")
280 (test-ps-js function-calls-and-method-calls-3
281 ((getprop this 'blorg) 1 2)
282 "this.blorg(1, 2);")
284 (test-ps-js function-calls-and-method-calls-4
285 ((aref foo i) 1 2)
286 "foo[i](1, 2);")
288 (test-ps-js function-calls-and-method-calls-5
289 ((getprop (aref foobar 1) 'blorg) nil t)
290 "foobar[1].blorg(null, true);")
292 (test-ps-js operator-expressions-1
293 (* 1 2)
294 "1 * 2;")
296 (test-ps-js operator-expressions-2
297 (= 1 2)
298 "1 === 2;")
300 (test-ps-js operator-expressions-3
301 (* 1 (+ 2 3 4) 4 (/ 6 7))
302 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
304 (test-ps-js operator-expressions-4
305 (incf i)
306 "++i;")
308 (test-ps-js operator-expressions-5
309 (decf i)
310 "--i;")
312 (test-ps-js operator-expressions-6
313 (1- i)
314 "i - 1;")
316 (test-ps-js operator-expressions-7
317 (1+ i)
318 "i + 1;")
320 (test-ps-js operator-expressions-8
321 (not (< i 2))
322 "i >= 2;")
324 (test-ps-js body-forms-1
325 (progn (blorg i) (blafoo i))
326 "blorg(i);
327 blafoo(i);")
329 (test-ps-js body-forms-2
330 (+ i (progn (blorg i) (blafoo i)))
331 "i + (blorg(i), blafoo(i));")
333 (test-ps-js function-definition-1
334 (defun a-function (a b)
335 (+ a b))
336 "function aFunction(a, b) {
337 return a + b;
338 };")
340 (test-ps-js lambda-definition-2
341 (lambda (a b) (+ a b))
342 "function (a, b) {
343 return a + b;
344 };")
346 (test-ps-js assignment-1
347 (setf a 1)
348 "a = 1;")
350 (test-ps-js assignment-2
351 (setf a 2 b 3 c 4 x (+ a b c))
352 "a = 2;
353 b = 3;
354 c = 4;
355 x = a + b + c;")
357 (test-ps-js assignment-3
358 (setf a (+ a 2 3 4 a))
359 "a = a + 2 + 3 + 4 + a;")
361 (test-ps-js assignment-4
362 (setf a (- 1 a))
363 "a = 1 - a;")
365 (test-ps-js assignment-5
366 (let ((a 1) (b 2))
367 (psetf a b b a))
368 "(function () {
369 var a = 1;
370 var b = 2;
371 var _js3 = b;
372 var _js4 = a;
373 a = _js3;
374 return b = _js4;
375 })();")
377 (test-ps-js assignment-6
378 (setq a 1)
379 "a = 1;")
381 (test-ps-js assignment-8
382 (progn
383 (defun (setf color) (new-color el)
384 (setf (getprop (getprop el 'style) 'color) new-color))
385 (setf (color some-div) (+ 23 "em")))
386 "function __setf_color(newColor, el) {
387 return el.style.color = newColor;
389 __setf_color(23 + 'em', someDiv);")
391 (test-ps-js assignment-10
392 (progn
393 (defsetf left (el) (offset)
394 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
395 (setf (left some-div) (+ 123 "px")))
396 "(function () {
397 var _js2 = someDiv;
398 var _js1 = 123 + 'px';
399 return _js2.style.left = _js1;
400 })();")
402 (test-ps-js assignment-12
403 (macrolet ((left (el)
404 `(getprop ,el 'offset-left)))
405 (left some-div))
406 "someDiv.offsetLeft;")
408 (test-ps-js nil-block-return-1
409 (block nil (return) 1)
410 "(function () {
411 return null;
412 return 1;
413 })();")
415 (test-ps-js single-argument-statements-2
416 (throw "foobar")
417 "throw 'foobar';")
419 (test-ps-js single-argument-expression-1
420 (delete (new (*foobar 2 3 4)))
421 "delete new Foobar(2, 3, 4);")
423 (test-ps-js single-argument-expression-2
424 (if (= (typeof blorg) *string)
425 (alert (+ "blorg is a string: " blorg))
426 (alert "blorg is not a string"))
427 "if (typeof blorg === String) {
428 alert('blorg is a string: ' + blorg);
429 } else {
430 alert('blorg is not a string');
431 };")
433 (test-ps-js conditional-statements-1
434 (defun foo ()
435 (if ((@ blorg is-correct))
436 (progn (carry-on) (return-from foo i))
437 (alert "blorg is not correct!")))
438 "function foo() {
439 if (blorg.isCorrect()) {
440 carryOn();
441 __PS_MV_REG = [];
442 return i;
443 } else {
444 __PS_MV_REG = [];
445 return alert('blorg is not correct!');
447 };")
449 (test-ps-js conditional-statements-2
450 (+ i (if ((@ blorg add-one)) 1 2))
451 "i + (blorg.addOne() ? 1 : 2);")
453 (test-ps-js conditional-statements-3
454 (defun foo ()
455 (when ((@ blorg is-correct))
456 (carry-on)
457 (return-from foo i)))
458 "function foo() {
459 if (blorg.isCorrect()) {
460 carryOn();
461 __PS_MV_REG = [];
462 return i;
464 };")
466 (test-ps-js conditional-statements-4
467 (unless ((@ blorg is-correct))
468 (alert "blorg is not correct!"))
469 "if (!blorg.isCorrect()) {
470 alert('blorg is not correct!');
471 };")
473 (test-ps-js variable-declaration-1
474 (defvar *a* (array 1 2 3))
475 "if ('undefined' === typeof A) { var A = [1, 2, 3]; };")
477 (test-ps-js variable-declaration-2
478 (progn (defvar *a* 4)
479 (let ((x 1)
480 (*a* 2))
481 (let* ((y (+ x 1))
482 (x (+ x y)))
483 (+ *a* x y))))
484 "if ('undefined' === typeof A) { var A = 4; };
485 (function () {
486 var x = 1;
487 var A_TMPSTACK1;
488 try {
489 A_TMPSTACK1 = A;
490 A = 2;
491 var y = x + 1;
492 var x2 = x + y;
493 return A + x2 + y;
494 } finally {
495 A = A_TMPSTACK1;
497 })();")
499 (test-ps-js variable-declaration-3
500 (defparameter A 987)
501 "var A = 987;")
503 (test-ps-js variable-declaration-4
504 (progn (defparameter *a* 4)
505 (let ((x 1)
506 (*a* 2))
507 (let* ((y (+ x 1))
508 (x (+ x y)))
509 (+ *a* x y))))
510 "var A = 4;
511 (function () {
512 var x = 1;
513 var A_TMPSTACK1;
514 try {
515 A_TMPSTACK1 = A;
516 A = 2;
517 var y = x + 1;
518 var x2 = x + y;
519 return A + x2 + y;
520 } finally {
521 A = A_TMPSTACK1;
523 })();")
525 (test-ps-js variable-declaration-5
526 (defvar BAZ)
527 "var BAZ;")
529 (test-ps-js iteration-constructs-1
530 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
531 (d 0 (1+ d))
532 (e (aref c d) (aref c d)))
533 ((or (= d (@ c length)) (string= e "x")))
534 (setf a d b e)
535 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
536 "(function () {
537 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
538 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
539 a = d;
540 b = e;
541 document.write('a: ' + a + ' b: ' + b + '<br/>');
543 })();")
545 (test-ps-js iteration-constructs-2
546 (do ((i 0 (1+ i))
547 (s 0 (+ s i (1+ i))))
548 ((> i 10))
549 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
550 "(function () {
551 var i = 0;
552 var s = 0;
553 for (; i <= 10; ) {
554 document.write('i: ' + i + ' s: ' + s + '<br/>');
555 var _js1 = i + 1;
556 var _js2 = s + i + (i + 1);
557 i = _js1;
558 s = _js2;
560 })();")
562 (test-ps-js iteration-constructs-3
563 (do* ((i 0 (1+ i))
564 (s 0 (+ s i (1- i))))
565 ((> i 10))
566 ((@ document write) (+ "i: " i " s: " s "<br/>")))
567 "(function () {
568 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
569 document.write('i: ' + i + ' s: ' + s + '<br/>');
571 })();")
573 (test-ps-js iteration-constructs-4
574 (let ((arr (array "a" "b" "c" "d" "e")))
575 (dotimes (i (@ arr length))
576 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
577 "(function () {
578 var arr = ['a', 'b', 'c', 'd', 'e'];
579 for (var i = 0; i < arr.length; i += 1) {
580 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
582 })();")
584 (test-ps-js iteration-constructs-5
585 (let ((res 0))
586 (alert (+ "Summation to 10 is "
587 (dotimes (i 10 res)
588 (incf res (1+ i))))))
589 "(function () {
590 var res = 0;
591 __PS_MV_REG = [];
592 return alert('Summation to 10 is ' + (function () {
593 for (var i = 0; i < 10; i += 1) {
594 res += i + 1;
596 var i = null;
597 return res;
598 })());
599 })();")
601 (test-ps-js iteration-constructs-6
602 (let ((l (list 1 2 4 8 16 32)))
603 (dolist (c l)
604 ((@ document write) (+ "c: " c "<br/>"))))
605 "(function () {
606 var l = [1, 2, 4, 8, 16, 32];
607 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
608 c = l[_js_idx2];
609 document.write('c: ' + c + '<br/>');
611 })();")
613 (test-ps-js iteration-constructs-7
614 (let ((l '(1 2 4 8 16 32))
615 (s 0))
616 (alert (+ "Sum of " l " is: "
617 (dolist (c l s)
618 (incf s c)))))
619 "(function () {
620 var l = [1, 2, 4, 8, 16, 32];
621 var s = 0;
622 __PS_MV_REG = [];
623 return alert('Sum of ' + l + ' is: ' + (function () {
624 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
625 c = l[_js_idx1];
626 s += c;
628 var c = null;
629 return s;
630 })());
631 })();")
633 (test-ps-js iteration-constructs-8
634 (let ((obj (create a 1 b 2 c 3)))
635 (for-in (i obj)
636 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
637 "(function () {
638 var obj = { a : 1, b : 2, c : 3 };
639 for (var i in obj) {
640 document.write(i + ': ' + obj[i] + '<br/>');
642 })();")
644 (test-ps-js iteration-constructs-9
645 (loop while (funcall (@ film is-not-finished)) do
646 (funcall (@ this eat) (new *popcorn)))
647 "(function () {
648 while (film.isNotFinished()) {
649 this.eat(new Popcorn);
651 }).call(this);")
653 (test-ps-js loop-for-bindings
654 (loop :for ((a b) (:c :d)) :in arr :do (foo a b c d))
655 "(function () {
656 var _js2 = arr.length;
657 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
658 var _db4 = arr[_js1];
659 var _db5 = _db4[0];
660 var a = _db5[0];
661 var b = _db5[1];
662 var _js3 = _db4[1];
663 var c = _js3['c'];
664 var d = _js3['d'];
665 foo(a, b, c, d);
667 })();")
669 (test-ps-js loop-for-on
670 (loop :for (k v) :on plist :by 2 :do (foo k v))
671 "(function () {
672 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
673 var k = _js1[0];
674 var v = _js1[1];
675 foo(k, v);
677 })();")
679 (test-ps-js loop-for-keys-of
680 (loop :for k :of obj :do (foo k))
681 "(function () {
682 for (var k in obj) {
683 foo(k);
685 })();")
687 (test-ps-js loop-for-key-val-pairs-of
688 (loop :for (k v) :of obj :do (foo k v))
689 "(function () {
690 for (var k in obj) {
691 var v = obj[k];
692 foo(k, v);
694 })();")
696 (test-ps-js loop-for-key-val-pairs-of-with-bindings
697 (loop :for (k (a b)) :of obj :do (foo k a b))
698 "(function () {
699 for (var k in obj) {
700 var _db1 = obj[k];
701 var a = _db1[0];
702 var b = _db1[1];
703 foo(k, a, b);
705 })();")
707 (test-ps-js loop-for-just-vals-of
708 (loop :for (nil v) :of obj :do (foo k v))
709 "(function () {
710 for (var _js1 in obj) {
711 var v = obj[_js1];
712 foo(k, v);
714 })();")
716 (test-ps-js loop-map-to
717 (loop :for str :in strs :map str :to (length str))
718 "(function () {
719 var _js2 = strs.length;
720 var map3 = { };
721 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
722 var str = strs[_js1];
723 map3[str] = str.length;
725 return map3;
726 })();")
728 (test-ps-js loop-for-of-map-to
729 (loop :for k :of obj :map k :to (foo k))
730 "(function () {
731 var map1 = { };
732 for (var k in obj) {
733 map1[k] = foo(k);
735 __PS_MV_REG = [];
736 return map1;
737 })();")
739 (test-ps-js loop-for-of-when
740 (loop :for k :of obj :when (foo k) :map k :to (bar k))
741 "(function () {
742 var map1 = { };
743 for (var k in obj) {
744 if (foo(k)) {
745 map1[k] = bar(k);
748 __PS_MV_REG = [];
749 return map1;
750 })();")
752 (test-ps-js loop-for-in-until-when
753 (loop :for a :in b :until (> a 100) :when (< a 50) :do (foo a))
754 "(function () {
755 var _js2 = b.length;
756 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
757 var a = b[_js1];
758 if (a > 100) {
759 break;
761 if (a < 50) {
762 foo(a);
765 })();")
767 (test-ps-js loop-with-for-when
768 (loop :with c = c1 :for d :from c1 :below c2
769 :when (foo c d) :do (setf c d)
770 :do (bar d))
771 "(function () {
772 var c = c1;
773 for (var d = c1; d < c2; d += 1) {
774 if (foo(c, d)) {
775 c = d;
777 bar(d);
779 })();")
781 (test-ps-js loop-for-then-for-in-while
782 (defun blah (c)
783 (loop :for a = (foo) :then (bar) :for b :in c :while b :do (foo a b c)))
784 "function blah(c) {
785 var _js2 = c.length;
786 var FIRST3 = true;
787 for (var a = foo(); true; a = bar()) {
788 var _js1 = FIRST3 ? 0 : _js1 + 1;
789 if (_js1 >= _js2) {
790 break;
792 var b = c[_js1];
793 if (!b) {
794 break;
796 foo(a, b, c);
797 FIRST3 = null;
799 };")
801 (test-ps-js loop-while-when
802 (loop :for a = (pop stack) :while a :for (b c) = (foo a) :when b :do (bar c))
803 "(function () {
804 for (var a = pop(stack); a; a = pop(stack)) {
805 var _db1 = foo(a);
806 var b = _db1[0];
807 var c = _db1[1];
808 if (b) {
809 bar(c);
812 })();")
814 (test-ps-js loop-for-of-for-in
815 (defun blah (obj b)
816 (loop :for k :of obj :for a :in b :do (foo k a)))
817 "function blah(obj, b) {
818 var _js2 = b.length;
819 var FIRST3 = true;
820 for (var k in obj) {
821 var _js1 = FIRST3 ? 0 : _js1 + 1;
822 if (_js1 >= _js2) {
823 break;
825 var a = b[_js1];
826 foo(k, a);
827 FIRST3 = null;
829 };")
831 (test-ps-js loop-for-dot
832 (loop :for (op . args) :in expr :do (foo op args))
833 "(function () {
834 var _js2 = expr.length;
835 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
836 var _db3 = expr[_js1];
837 var op = _db3[0];
838 var args = _db3.length > 1 ? _db3.slice(1) : [];
839 foo(op, args);
841 })();")
843 (test-ps-js loop-for-rest
844 (loop :for (op &rest args) :in expr :do (foo op args))
845 "(function () {
846 var _js2 = expr.length;
847 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
848 var _db3 = expr[_js1];
849 var op = _db3[0];
850 var args = _db3.length > 1 ? _db3.slice(1) : [];
851 foo(op, args);
853 })();")
855 (test-ps-js loop-collect
856 (setf x (loop :for a :in b :collect (foo a)))
857 "x = (function () {
858 var _js2 = b.length;
859 var collect3 = [];
860 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
861 var a = b[_js1];
862 collect3.push(foo(a));
864 __PS_MV_REG = [];
865 return collect3;
866 })();")
868 (test-ps-js loop-append
869 (loop :for a :in b :append a)
870 "(function () {
871 var _js2 = b.length;
872 var append3 = [];
873 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
874 var a = b[_js1];
875 append3 = append3.concat(a);
877 __PS_MV_REG = [];
878 return append3;
879 })();")
881 (test-ps-js the-case-statement-1
882 (case (aref blorg i)
883 ((1 "one") (alert "one"))
884 (2 (alert "two"))
885 (t (alert "default clause")))
886 "switch (blorg[i]) {
887 case 1:
888 case 'one':
889 alert('one');
890 break;
891 case 2:
892 alert('two');
893 break;
894 default:
895 alert('default clause');
896 };")
898 (test-ps-js the-case-statement-2
899 (switch (aref blorg i)
900 (1 (alert "If I get here"))
901 (2 (alert "I also get here"))
902 (default (alert "I always get here")))
903 "switch (blorg[i]) {
904 case 1: alert('If I get here');
905 case 2: alert('I also get here');
906 default: alert('I always get here');
907 };")
909 (test-ps-js the-try-statement-1
910 (try (throw "i")
911 (:catch (error)
912 (alert (+ "an error happened: " error)))
913 (:finally
914 (alert "Leaving the try form")))
915 "try {
916 throw 'i';
917 } catch (error) {
918 alert('an error happened: ' + error);
919 } finally {
920 alert('Leaving the try form');
921 };")
923 (test-ps-js the-html-generator-1
924 (ps-html ((:a :href "foobar") "blorg"))
925 "'<a href=\\\"foobar\\\">blorg</a>';")
927 (test-ps-js the-html-generator-2
928 (ps-html ((:a :href (generate-a-link)) "blorg"))
929 "['<a href=\\\"', generateALink(), '\\\">blorg</a>'].join('');")
931 (test-ps-js the-html-generator-3
932 (funcall (getprop document 'write)
933 (ps-html ((:a :href "#"
934 :onclick (ps-inline (transport))) "link")))
935 "document.write(['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">link</a>'].join(''));")
937 (test-ps-js the-html-generator-4
938 (let ((disabled nil)
939 (authorized t))
940 (setf (getprop element 'inner-h-t-m-l)
941 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
942 "Edit me"))))
943 "(function () {
944 var disabled = null;
945 var authorized = true;
946 return element.innerHTML = ['<textarea', disabled || !authorized ? [' disabled=\\\"', 'disabled', '\\\"'].join('') : '', '>Edit me</textarea>'].join('');
947 })();")
949 (test-ps-js plus-is-not-commutative
950 (setf x (+ "before" x "after"))
951 "x = 'before' + x + 'after';")
953 (test-ps-js plus-works-if-first
954 (setf x (+ x "middle" "after"))
955 "x = x + 'middle' + 'after';")
957 (test-ps-js method-call-op-form
958 (funcall (getprop (+ "" x) 'to-string))
959 "('' + x).toString();")
961 (test-ps-js method-call-op-form-args
962 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
963 "('' + x).foo(1, 2, 'baz', 3);")
965 (test-ps-js method-call-string
966 ((getprop "hi" 'to-string))
967 "'hi'.toString();")
969 (test-ps-js method-call-conditional
970 ((if a x y) 1)
971 "(a ? x : y)(1);")
973 (test-ps-js method-call-variable
974 ((@ x to-string))
975 "x.toString();")
977 (test-ps-js method-call-array
978 ((@ (list 10 20) to-string))
979 "[10, 20].toString();")
981 (test-ps-js method-call-lambda-call
982 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
983 "(function (x) { return x; })(10).toString();")
985 (fiveam:test no-whitespace-before-dot
986 (let ((str (ps* '((@ ((lambda (x) x) 10) to-string)))))
987 (fiveam:is (char= #\) (elt str (1- (position #\. str)))))))
989 (test-ps-js simple-getprop
990 (let ((foo (create a 1)))
991 (alert (getprop foo 'a)))
992 "(function () {
993 var foo = { a : 1 };
994 __PS_MV_REG = [];
995 return alert(foo.a);
996 })();")
998 (test-ps-js buggy-getprop
999 (getprop foo slot-name)
1000 "foo[slotName];")
1002 (test-ps-js buggy-getprop-two
1003 (getprop foo (get-slot-name))
1004 "foo[getSlotName()];")
1006 (test-ps-js old-case-is-now-switch
1007 ;; Switch was "case" before, but that was very non-lispish.
1008 ;; For example, this code makes three messages and not one
1009 ;; which may have been expected. This is because a switch
1010 ;; statment must have a break statement for it to return
1011 ;; after the alert. Otherwise it continues on the next
1012 ;; clause.
1013 (switch (aref blorg i)
1014 (1 (alert "one"))
1015 (2 (alert "two"))
1016 (default (alert "default clause")))
1017 "switch (blorg[i]) {
1018 case 1: alert('one');
1019 case 2: alert('two');
1020 default: alert('default clause');
1021 };")
1023 (test-ps-js lisp-like-case
1024 (case (aref blorg i)
1025 (1 (alert "one"))
1026 (2 (alert "two"))
1027 (t (alert "default clause")))
1028 "switch (blorg[i]) {
1029 case 1:
1030 alert('one');
1031 break;
1032 case 2:
1033 alert('two');
1034 break;
1035 default: alert('default clause');
1036 };")
1039 (test-ps-js even-lispier-case
1040 (case (aref blorg i)
1041 ((1 2) (alert "Below three"))
1042 (3 (alert "Three"))
1043 (t (alert "Something else")))
1044 "switch (blorg[i]) {
1045 case 1:
1046 case 2:
1047 alert('Below three');
1048 break;
1049 case 3:
1050 alert('Three');
1051 break;
1052 default: alert('Something else');
1053 };")
1055 (test-ps-js otherwise-case
1056 (case (aref blorg i)
1057 (1 (alert "one"))
1058 (otherwise (alert "default clause")))
1059 "switch (blorg[i]) {
1060 case 1:
1061 alert('one');
1062 break;
1063 default: alert('default clause');
1064 };")
1066 (fiveam:test escape-sequences-in-string
1067 (let ((escapes
1068 `((#\\ . #\\)
1069 (#\b . #\Backspace)
1070 (#\f . ,(code-char 12))
1071 ("u000B" . ,(code-char #xB)) ; vertical tab
1072 (#\n . #\Newline)
1073 (#\r . #\Return)
1074 (#\' . #\')
1075 (#\" . #\")
1076 (#\t . #\Tab)
1077 ("u001F" . ,(code-char #x1F)) ; character below 32
1078 ("u0080" . ,(code-char 128)) ; character over 127
1079 ("u00A0" . ,(code-char 160)) ; non-breaking space
1080 ("u00AD" . ,(code-char 173)) ; soft hyphen
1081 ("u200B" . ,(code-char #x200B)) ; zero-width space
1082 ("u200C" . ,(code-char #x200C)) ; zero-width non-joiner
1084 (loop for (js-escape . lisp-char) in escapes
1085 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
1086 for wanted = (format nil "'hello\\~ahi';" js-escape)
1087 do (fiveam:is (string= generated wanted)))))
1089 (fiveam:test escape-doublequotes
1090 (let ((*js-string-delimiter* #\"))
1091 (fiveam:is (string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1093 (test-ps-js getprop-setf
1094 (setf (getprop x 'y) (+ (+ a 3) 4))
1095 "x.y = (a + 3) + 4;")
1097 (test-ps-js getprop-conditional1
1098 (getprop (if zoo foo bar) 'x)
1099 "(zoo ? foo : bar).x;")
1101 (test-ps-js getprop-conditional2
1102 (getprop (if (not zoo) foo bar) 'x)
1103 "(!zoo ? foo : bar).x;")
1105 (fiveam:test script-star-eval1
1106 (fiveam:is (string=
1107 (normalize-js-output (ps* '(setf x 1) '(setf y 2)))
1108 "x = 1; y = 2;")))
1110 (fiveam:test script-star-eval2
1111 (fiveam:is (string=
1112 (normalize-js-output (ps* '(setf x 1)))
1113 "x = 1;")))
1115 (test-ps-js list-with-single-nil
1116 (array nil)
1117 "[null];")
1119 (test-ps-js quoted-nil-is-array
1120 'nil
1121 "[];")
1123 (test-ps-js quoted-nil-is-array1
1125 "[];")
1127 (test-ps-js literal-nil
1128 (foo ())
1129 "foo(null);")
1131 (test-ps-js quoted-quoted-nil
1132 '(())
1133 "[null];")
1135 (test-ps-js quoted-quoted-nil1
1136 '(1 ())
1137 "[1, null];")
1139 (test-ps-js defsetf1
1140 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1141 (setf (baz 1 2) 3))
1142 "(function () {
1143 var _js2 = 1;
1144 var _js3 = 2;
1145 var _js1 = 3;
1146 __PS_MV_REG = [];
1147 return setBaz(_js2, _js3, _js1);
1148 })();")
1150 (test-ps-js setf-macroexpands1
1151 (macrolet ((bar (x y)
1152 `(aref ,x ,y 1)))
1153 (setf (bar foo 2) 3))
1154 "foo[2][1] = 3;")
1156 (test-ps-js defsetf-short
1157 (progn (defsetf baz set-baz "docstring")
1158 (setf (baz 1 2 3) "foo"))
1159 "setBaz(1, 2, 3, 'foo');")
1161 (test-ps-js defun-setf1
1162 (progn (defun (setf some-thing) (new-val i1 i2)
1163 (setf (aref *some-thing* i1 i2) new-val))
1164 (setf (some-thing 1 2) "foo"))
1165 "function __setf_someThing(newVal, i1, i2) {
1166 return SOMETHING[i1][i2] = newVal;
1168 __setf_someThing('foo', 1, 2);")
1170 (test-ps-js defun-optional1
1171 (defun test-opt (&optional x)
1172 (if x "yes" "no"))
1173 "function testOpt(x) {
1174 return x ? 'yes' : 'no';
1175 };")
1177 (test-ps-js defun-optional2
1178 (defun foo (x &optional y)
1179 (+ x y))
1180 "function foo(x, y) {
1181 return x + y;
1182 };")
1184 (test-ps-js defun-optional3
1185 (defun blah (&optional (x 0))
1187 "function blah(x) {
1188 if (x === undefined) {
1189 x = 0;
1191 return x;
1192 };")
1194 (test-ps-js arglist-optional4
1195 (lambda (&optional (x 0 supplied?))
1197 "function (x) {
1198 var suppliedwhat = x !== undefined;
1199 if (!suppliedwhat) {
1200 x = 0;
1202 return x;
1203 };")
1205 (test-ps-js return-nothing
1206 (defun foo () (return-from foo))
1207 "function foo() {
1208 return null;
1209 };")
1211 (test-ps-js return-values
1212 (defun foo ()
1213 (return-from foo (values 1 2 3)))
1214 "function foo() {
1215 var val1 = 1;
1216 __PS_MV_REG = [2, 3];
1217 return val1;
1218 };")
1220 (test-ps-js set-timeout
1221 (set-timeout (lambda () (alert "foo")) 10)
1222 "setTimeout(function () { __PS_MV_REG = []; return alert('foo'); }, 10);")
1224 (test-ps-js operator-precedence
1225 (* 3 (+ 4 5) 6)
1226 "3 * (4 + 5) * 6;")
1228 (test-ps-js operators-1
1229 (in prop obj)
1230 "prop in obj;")
1232 (test-ps-js incf1
1233 (incf foo bar)
1234 "foo += bar;")
1236 (test-ps-js decf1
1237 (decf foo bar)
1238 "foo -= bar;")
1240 (test-ps-js incf2
1241 (incf x 5)
1242 "x += 5;")
1244 (test-ps-js decf2
1245 (decf y 10)
1246 "y -= 10;")
1248 (test-ps-js setf-conditional
1249 (setf foo (if x 1 2))
1250 "foo = x ? 1 : 2;")
1252 (test-ps-js obj-literal-numbers
1253 (create 1 "foo")
1254 "{ 1 : 'foo' };")
1256 (test-ps-js obj-literal-strings
1257 (create "foo" 2)
1258 "{ 'foo' : 2 };")
1260 (test-ps-js getprop-string
1261 (getprop foo "bar")
1262 "foo['bar'];")
1264 (test-ps-js getprop-string1
1265 (getprop "bar" 'length)
1266 "'bar'.length;")
1268 (test-ps-js getprop-progn
1269 (getprop (progn (some-fun "abc") "123") "length")
1270 "(someFun('abc'), '123')['length'];")
1272 (test-ps-js getprop-multi1
1273 (getprop foo 1 "two" three 'bar 1 2)
1274 "foo[1]['two'][three].bar[1][2];")
1276 (test-ps-js method-call-block
1277 ((@ (progn (some-fun "abc") "123") to-string))
1278 "(someFun('abc'), '123').toString();")
1280 (test-ps-js create-blank
1281 (create)
1282 "{ };")
1284 (test-ps-js blank-object-literal
1286 "{ };")
1288 (test-ps-js array-literal1
1290 "[];")
1292 (test-ps-js array-literal2
1293 ([])
1294 "[];")
1296 (test-ps-js array-literal3
1297 ([] 1 2 3)
1298 "[1, 2, 3];")
1300 (test-ps-js array-literal4
1301 ([] 1 (2 3))
1302 "[1, [2, 3]];")
1304 (test-ps-js array-literal5
1305 ([] (1 2) ("a" "b"))
1306 "[[1, 2], ['a', 'b']];")
1308 (test-ps-js defun-rest1
1309 (defun foo (&rest bar)
1310 (alert (aref bar 1)))
1311 "function foo() {
1312 var bar = Array.prototype.slice.call(arguments, 0);
1313 __PS_MV_REG = [];
1314 return alert(bar[1]);
1315 };")
1317 (test-ps-js defun-rest2
1318 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1319 "function foo(baz) {
1320 var bar = Array.prototype.slice.call(arguments, 1);
1321 __PS_MV_REG = [];
1322 return baz + bar[1];
1323 };")
1325 (test-ps-js defun-keyword1
1326 (defun zoo (foo bar &key baz) (+ foo bar baz))
1327 "function zoo(foo, bar) {
1328 var _js2 = arguments.length;
1329 for (var n1 = 2; n1 < _js2; n1 += 2) {
1330 switch (arguments[n1]) {
1331 case 'baz':
1332 baz = arguments[n1 + 1];
1335 var baz;
1336 return foo + bar + baz;
1337 };")
1339 (test-ps-js defun-keyword2
1340 (defun zoo (&key baz) (* baz baz))
1341 "function zoo() {
1342 var _js2 = arguments.length;
1343 for (var n1 = 0; n1 < _js2; n1 += 2) {
1344 switch (arguments[n1]) {
1345 case 'baz':
1346 baz = arguments[n1 + 1];
1349 var baz;
1350 return baz * baz;
1351 };")
1353 (test-ps-js defun-keyword3
1354 (defun zoo (&key baz (bar 4)) (* baz bar))
1355 "function zoo() {
1356 var _js2 = arguments.length;
1357 for (var n1 = 0; n1 < _js2; n1 += 2) {
1358 switch (arguments[n1]) {
1359 case 'baz':
1360 baz = arguments[n1 + 1];
1361 break;
1362 case 'bar':
1363 bar = arguments[n1 + 1];
1366 var baz;
1367 var bar = 'undefined' === typeof bar ? 4 : bar;
1368 return baz * bar;
1369 };")
1371 (test-ps-js defun-keyword4
1372 (defun hello-world (&key ((:my-name-key my-name) 1))
1373 my-name)
1374 "function helloWorld() {
1375 var _js2 = arguments.length;
1376 for (var n1 = 0; n1 < _js2; n1 += 2) {
1377 switch (arguments[n1]) {
1378 case 'my-name-key':
1379 myName = arguments[n1 + 1];
1382 var myName = 'undefined' === typeof myName ? 1 : myName;
1383 return myName;
1384 };")
1386 (test-ps-js arglist-keyword-supplied
1387 (lambda (&key (foo 1 supplied?))
1388 foo)
1389 "function () {
1390 var _js2 = arguments.length;
1391 for (var n1 = 0; n1 < _js2; n1 += 2) {
1392 switch (arguments[n1]) {
1393 case 'foo':
1394 foo = arguments[n1 + 1];
1395 suppliedwhat = true;
1398 var suppliedwhat;
1399 var foo = 'undefined' === typeof foo ? 1 : foo;
1400 return foo;
1401 };")
1403 (test-ps-js keyword-funcall1
1404 (func :baz 1)
1405 "func('baz', 1);")
1407 (test-ps-js keyword-funcall2
1408 (func :baz 1 :bar foo)
1409 "func('baz', 1, 'bar', foo);")
1411 (test-ps-js keyword-funcall3
1412 (fun a b :baz c)
1413 "fun(a, b, 'baz', c);")
1415 (test-ps-js cond1
1416 (cond ((= x 1) 1))
1417 "if (x === 1) {
1419 };")
1421 (test-ps-js cond2
1422 (cond ((= x 1) 2)
1423 ((= y (* x 4)) (foo "blah") (* x y)))
1424 "if (x === 1) {
1426 } else if (y === x * 4) {
1427 foo('blah');
1428 x * y;
1429 };")
1431 (test-ps-js if-exp-without-else-return
1432 (defun foo () (return-from foo (if x 1)))
1433 "function foo() {
1434 return x ? 1 : null;
1435 };")
1437 (test-ps-js progn-expression-single-statement
1438 (defun foo () (return-from foo (progn (* x y))))
1439 "function foo() {
1440 return x * y;
1441 };")
1443 (test-ps-js cond-expression1
1444 (defun foo ()
1445 (cond ((< 1 2) (bar "foo") (* 4 5))))
1446 "function foo() {
1447 if (1 < 2) {
1448 bar('foo');
1449 __PS_MV_REG = [];
1450 return 4 * 5;
1452 };")
1454 (test-ps-js cond-expression2
1455 (defun foo ()
1456 (cond ((< 2 1) "foo")
1457 ((= 7 7) "bar")))
1458 "function foo() {
1459 if (2 < 1) {
1460 return 'foo';
1461 } else if (7 === 7) {
1462 return 'bar';
1464 };")
1466 (test-ps-js cond-expression-final-t-clause
1467 (defun foo ()
1468 (cond ((< 1 2) (bar "foo") (* 4 5))
1469 ((= a b) (+ c d))
1470 ((< 1 2 3 4 5) x)
1471 (t "foo")))
1472 "function foo() {
1473 var _cmp1;
1474 var _cmp2;
1475 var _cmp3;
1476 if (1 < 2) {
1477 bar('foo');
1478 __PS_MV_REG = [];
1479 return 4 * 5;
1480 } else if (a === b) {
1481 __PS_MV_REG = [];
1482 return c + d;
1483 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1484 __PS_MV_REG = [];
1485 return x;
1486 } else {
1487 __PS_MV_REG = [];
1488 return 'foo';
1490 };")
1492 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1493 (defun foo ()
1494 (cond ((< 2 1) 5)
1495 (t "foo")
1496 ((< 1 2) "bar")))
1497 "function foo() {
1498 if (2 < 1) {
1499 return 5;
1500 } else {
1501 return 'foo';
1503 };")
1505 (test-ps-js funcall-if-expression
1506 (funcall (getprop document 'write)
1507 (if (= *linkornot* 1)
1508 (ps-html ((:a :href "#"
1509 :onclick (ps-inline (transport)))
1510 img))
1511 img))
1512 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1514 (test-ps-js negate-number-literal
1515 (- 1)
1516 "-1;")
1518 (fiveam:test macro-environment1
1519 (fiveam:is
1520 (string=
1521 (normalize-js-output
1522 (let* ((macroname (gensym)))
1523 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1524 `(defun test1 ()
1525 (macrolet ((,macroname (x) `(aref data ,x)))
1526 (when (,macroname x)
1527 (setf (,macroname x) 123)))))))
1528 (normalize-js-output
1529 "function test1() {
1530 return data[x] ? (data[x] = 123) : null;
1531 };"))))
1533 (fiveam:test macro-environment2
1534 (fiveam:is
1535 (string=
1536 (let ((outer-lexical-variable 1))
1537 (defpsmacro macro-environment2-macro (x)
1538 `(+ ,outer-lexical-variable ,x))
1539 (ps* '(macro-environment2-macro 2)))
1540 "1 + 2;")))
1542 (test-ps-js ampersand-whole-1
1543 (macrolet ((foo (&whole foo bar baz)
1544 (declare (ignore bar baz))
1545 (with-standard-io-syntax
1546 (let ((*print-case* :downcase))
1547 (format nil "~a" foo)))))
1548 (foo 1 2))
1549 "'(foo 1 2)';")
1551 (test-ps-js ampersand-whole-2
1552 (macrolet ((foo (&whole foo bar baz)
1553 `(+ ,bar ,baz)))
1554 (foo 1 2))
1555 "1 + 2;")
1557 (test-ps-js keyword-consistent
1559 "'x';")
1561 (test-ps-js simple-symbol-macrolet
1562 (symbol-macrolet ((x 1)) x)
1563 "1;")
1565 (test-ps-js compound-symbol-macrolet
1566 (symbol-macrolet ((x 123)
1567 (y (* 2 x)))
1569 "2 * 123;")
1571 (test-ps-js define-symbol-macro
1572 (progn (define-symbol-macro tst-sym-macro 2)
1573 tst-sym-macro)
1574 "2;")
1576 (test-ps-js define-symbol-macro1
1577 (progn (define-symbol-macro tst-sym-macro1 2)
1578 (foo tst-sym-macro1))
1579 "foo(2);")
1581 (test-ps-js define-symbol-macro2
1582 (progn (define-symbol-macro tst-sym-macro2 3)
1583 (list tst-sym-macro2))
1584 "[3];")
1586 (test-ps-js define-symbol-macro3
1587 (progn (define-symbol-macro tst-sym-macro3 4)
1588 (setq foo (create tst-sym-macro3 tst-sym-macro3)))
1589 "foo = { tstSymMacro3 : 4 };")
1591 (test-ps-js define-symbol-macro4
1592 (progn (define-symbol-macro tst-sym-macro4 5)
1593 (setq foo (if (baz) tst-sym-macro4 bar)))
1594 "foo = baz() ? 5 : bar;")
1596 (test-ps-js expression-progn
1597 (1+ (progn (foo) (if x 1 2)))
1598 "(foo(), x ? 1 : 2) + 1;")
1600 (test-ps-js let-decl-in-expression
1601 (defun f (x)
1602 (if x 1 (let* ((foo x)) foo)))
1603 "function f(x) {
1604 if (x) {
1605 return 1;
1606 } else {
1607 var foo = x;
1608 return foo;
1610 };")
1612 (test-ps-js special-var1
1613 (progn (defvar *foo*)
1614 (let* ((*foo* 2))
1615 (* *foo* 2)))
1616 "var FOO;
1617 (function () {
1618 var FOO_TMPSTACK1;
1619 try {
1620 FOO_TMPSTACK1 = FOO;
1621 FOO = 2;
1622 return FOO * 2;
1623 } finally {
1624 FOO = FOO_TMPSTACK1;
1626 })();")
1628 (test-ps-js special-var2
1629 (progn (defparameter *foo*)
1630 (let* ((*baz* 3)
1631 (*foo* 2))
1632 (* *foo* 2 *baz*)))
1633 "var FOO;
1634 (function () {
1635 var BAZ = 3;
1636 var FOO_TMPSTACK1;
1637 try {
1638 FOO_TMPSTACK1 = FOO;
1639 FOO = 2;
1640 return FOO * 2 * BAZ;
1641 } finally {
1642 FOO = FOO_TMPSTACK1;
1644 })();")
1646 (test-ps-js literal1
1647 (setf x undefined)
1648 "x = undefined;")
1650 (test-ps-js literal2
1651 (aref this x)
1652 "this[x];")
1654 (test-ps-js setf-dec1
1655 (setf x (- 1 x 2))
1656 "x = 1 - x - 2;")
1658 (test-ps-js setf-dec2
1659 (setf x (- x 1 2))
1660 "x = x - 1 - 2;")
1662 (test-ps-js special-char-equals
1663 blah=
1664 "blahequals;")
1666 (test-ps-js setf-operator-priority
1667 (defun foo ()
1668 (or (getprop cache id)
1669 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1670 "function foo() {
1671 __PS_MV_REG = [];
1672 return cache[id] || (cache[id] = document.getElementById(id));
1673 };")
1675 (test-ps-js aref-operator-priority
1676 (aref (if (and x (> (length x) 0))
1677 (aref x 0)
1680 "(x && x.length > 0 ? x[0] : y)[z];")
1682 (test-ps-js aref-operator-priority1
1683 (aref (or (getprop x 'y)
1684 (getprop a 'b))
1686 "(x.y || a.b)[z];")
1688 (test-ps-js aref-operator-priority2
1689 (aref (if a b c) 0)
1690 "(a ? b : c)[0];")
1692 (test-ps-js negate-operator-priority
1693 (- (if x y z))
1694 "-(x ? y : z);")
1696 (test-ps-js op-p1
1697 (new (or a b))
1698 "new (a || b);")
1700 (test-ps-js op-p2
1701 (delete (if a (or b c) d))
1702 "delete (a ? b || c : d);")
1704 (test-ps-js op-p3
1705 (not (if (or x (not y)) z))
1706 "!(x || !y ? z : null);")
1708 (test-ps-js op-p4
1709 (- (- (* 1 2) 3))
1710 "-(1 * 2 - 3);")
1712 (test-ps-js op-p5
1713 (instanceof (or a b) (if x y z))
1714 "((a || b) instanceof (x ? y : z));")
1716 (test-ps-js op-p7
1717 (or x (if (= x 0) "zero" "empty"))
1718 "x || (x === 0 ? 'zero' : 'empty');")
1720 (test-ps-js named-op-expression
1721 (throw (if a b c))
1722 "throw a ? b : c;")
1724 (test-ps-js named-op-expression1
1725 (typeof (or x y))
1726 "typeof (x || y);")
1728 (test-ps-js aref-array-expression
1729 (aref (or a b c) 0)
1730 "(a || b || c)[0];")
1732 (test-ps-js getprop-operator
1733 (getprop (or a b c) 'd)
1734 "(a || b || c).d;")
1736 (test-ps-js getprop-parens
1737 (getprop (getprop foo 'bar) 'baz)
1738 "foo.bar.baz;")
1740 (test-ps-js funcall-funcall
1741 ((foo))
1742 "foo()();")
1744 (test-ps-js expression-funcall
1745 ((or (@ window eval) eval) foo nil)
1746 "(window.eval || eval)(foo, null);")
1748 (test-ps-js expression-funcall1
1749 (((or (@ window eval) eval) foo nil))
1750 "(window.eval || eval)(foo, null)();")
1752 (test-ps-js expression-funcall2
1753 (((or (@ window eval) eval)) foo nil)
1754 "(window.eval || eval)()(foo, null);")
1756 (test-ps-js who-html1
1757 (who-ps-html (:span :class "ticker-symbol"
1758 :ticker-symbol symbol
1759 (:a :href "http://foo.com"
1760 symbol)
1761 (:span :class "ticker-symbol-popup")))
1762 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1764 (test-ps-js who-html2
1765 (who-ps-html (:p "t0" (:span "t1")))
1766 "'<p>t0<span>t1</span></p>';")
1768 (test-ps-js flet1
1769 ((lambda () (flet ((foo (x)
1770 (1+ x)))
1771 (foo 1))))
1772 "(function () {
1773 var foo = function (x) {
1774 return x + 1;
1776 __PS_MV_REG = [];
1777 return foo(1);
1778 })();")
1780 (test-ps-js flet2
1781 (flet ((foo (x) (1+ x))
1782 (bar (y) (+ 2 y)))
1783 (bar (foo 1)))
1784 "(function () {
1785 var foo = function (x) {
1786 return x + 1;
1788 var bar = function (y) {
1789 return 2 + y;
1791 __PS_MV_REG = [];
1792 return bar(foo(1));
1793 })();")
1795 (test-ps-js flet3
1796 (flet ((foo (x) (+ 2 x)))
1797 (flet ((foo (x) (1+ x))
1798 (bar (y) (+ 2 (foo y))))
1799 (bar (foo 1))))
1800 "(function () {
1801 var foo = function (x) {
1802 return 2 + x;
1804 var foo1 = function (x) {
1805 return x + 1;
1807 var bar = function (y) {
1808 __PS_MV_REG = [];
1809 return 2 + foo(y);
1811 __PS_MV_REG = [];
1812 return bar(foo1(1));
1813 })();")
1815 (test-ps-js labels1
1816 ((lambda () (labels ((foo (x)
1817 (if (= 0 x)
1819 (+ x (foo (1- x))))))
1820 (foo 3))))
1821 "(function () {
1822 var foo = function (x) {
1823 __PS_MV_REG = [];
1824 return 0 === x ? 0 : x + foo(x - 1);
1826 __PS_MV_REG = [];
1827 return foo(3);
1828 })();")
1830 (test-ps-js labels2
1831 (labels ((foo (x) (1+ (bar x)))
1832 (bar (y) (+ 2 (foo y))))
1833 (bar (foo 1)))
1834 "(function () {
1835 var foo = function (x) {
1836 __PS_MV_REG = [];
1837 return bar(x) + 1;
1839 var bar = function (y) {
1840 __PS_MV_REG = [];
1841 return 2 + foo(y);
1843 __PS_MV_REG = [];
1844 return bar(foo(1));
1845 })();")
1847 (test-ps-js labels3
1848 (labels ((foo (x) (1+ x))
1849 (bar (y) (+ 2 (foo y))))
1850 (bar (foo 1)))
1851 "(function () {
1852 var foo = function (x) {
1853 return x + 1;
1855 var bar = function (y) {
1856 __PS_MV_REG = [];
1857 return 2 + foo(y);
1859 __PS_MV_REG = [];
1860 return bar(foo(1));
1861 })();")
1863 (test-ps-js labels-lambda-list
1864 (labels ((foo (x &optional (y 0))
1865 (+ x y)))
1866 (foo 1))
1867 "(function () {
1868 var foo = function (x, y) {
1869 if (y === undefined) {
1870 y = 0;
1872 return x + y;
1874 __PS_MV_REG = [];
1875 return foo(1);
1876 })();")
1878 (test-ps-js for-loop-var-init-exp
1879 ((lambda (x)
1880 (do* ((y (if x 0 1) (1+ y))
1881 (z 0 (1+ z)))
1882 ((= y 3) z)))
1884 "(function (x) {
1885 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1887 return z;
1888 })(true);")
1890 (test-ps-js math-pi
1892 "Math.PI;")
1894 (test-ps-js literal-array
1895 '(1 2 3)
1896 "[1, 2, 3];")
1898 (test-ps-js literal-array-1
1899 '(1 foo 3)
1900 "[1, 'foo', 3];")
1902 (test-ps-js literal-array-literal
1904 "[];")
1906 (test-ps-js literal-array-literal1
1907 '(1 [])
1908 "[1, []];")
1910 (fiveam:test ps-lisp-expands-in-lexical-environment
1911 (fiveam:is (string= (let ((x 5)) (ps (lisp x)))
1912 "5;")))
1914 (fiveam:test ps-lisp-expands-in-lexical-environment1
1915 (fiveam:is (string= (let ((x 5)) (ps (+ 1 (lisp x))))
1916 "1 + 5;")))
1918 (fiveam:test ps-lisp-expands-in-lexical-environment2
1919 (fiveam:is (string= (let ((x 2)) (ps (+ 1 (lisp x) 3)))
1920 "1 + 2 + 3;")))
1922 (fiveam:test ps*-lisp-expands-in-null-lexical-environment
1923 (fiveam:signals unbound-variable
1924 (let ((x 5))
1925 (declare (ignore x))
1926 (ps* '(lisp x)))))
1928 (fiveam:test ps*-lisp-expands-in-dynamic-environment
1929 (fiveam:is (string=
1930 (let ((foo 2))
1931 (declare (special foo))
1932 (ps* '(+ 1 (lisp (locally (declare (special foo))
1933 foo)))))
1934 "1 + 2;")))
1936 (fiveam:test ps-lisp-dynamic-environment
1937 (fiveam:is (string=
1938 (let ((foo 2))
1939 (declare (special foo))
1940 (ps (+ 1 (lisp foo))))
1941 "1 + 2;")))
1943 (test-ps-js nested-if-expressions1
1944 (defun foo ()
1945 (return-from foo (if (if x y z) a b)))
1946 "function foo() {
1947 if (x ? y : z) {
1948 return a;
1949 } else {
1950 return b;
1952 };")
1954 (test-ps-js nested-if-expressions2
1955 (defun foo ()
1956 (if x y (if z a b)))
1957 "function foo() {
1958 if (x) {
1959 return y;
1960 } else {
1961 return z ? a : b;
1963 };")
1965 (test-ps-js nested-if-expressions3
1966 (foo (if (if x y z) a b)
1967 (if x y (if z a b)))
1968 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
1970 (test-ps-js let1
1971 (let (x)
1972 (+ x x))
1973 "(function () {
1974 var x = null;
1975 return x + x;
1976 })();")
1978 (test-ps-js let2
1979 (let ((x 1))
1980 (+ x x))
1981 "(function () {
1982 var x = 1;
1983 return x + x;
1984 })();")
1986 (test-ps-js let-x-x
1987 (let ((x (1+ x)))
1988 (+ x x))
1989 "(function () {
1990 var x1 = x + 1;
1991 return x1 + x1;
1992 })();")
1994 (test-ps-js let3
1995 (let ((x 1)
1996 (y 2))
1997 (+ x x))
1998 "(function () {
1999 var x = 1;
2000 var y = 2;
2001 return x + x;
2002 })();")
2004 (test-ps-js let4
2005 (let ((x 1)
2006 (y (1+ x)))
2007 (+ x y))
2008 "(function () {
2009 var x1 = 1;
2010 var y = x + 1;
2011 return x1 + y;
2012 })();")
2014 (test-ps-js let5
2015 (let ((x 1))
2016 (+ x 1)
2017 (let ((x (+ x 5)))
2018 (+ x 1))
2019 (+ x 1))
2020 "(function () {
2021 var x = 1;
2022 x + 1;
2023 var x1 = x + 5;
2024 x1 + 1;
2025 return x + 1;
2026 })();")
2028 (test-ps-js let6
2029 (let ((x 2))
2030 (let ((x 1)
2031 (y (1+ x)))
2032 (+ x y)))
2033 "(function () {
2034 var x = 2;
2035 var x1 = 1;
2036 var y = x + 1;
2037 return x1 + y;
2038 })();")
2040 (test-ps-js let-exp1
2041 (lambda ()
2042 (let (x)
2043 (+ x x)))
2044 "function () {
2045 var x = null;
2046 return x + x;
2047 };")
2049 (test-ps-js let*1
2050 (let* ((x 1))
2051 (+ x x))
2052 "(function () {
2053 var x = 1;
2054 return x + x;
2055 })();")
2057 (test-ps-js let*2
2058 (let* ((x 1)
2059 (y (+ x 2)))
2060 (+ x y))
2061 "(function () {
2062 var x = 1;
2063 var y = x + 2;
2064 return x + y;
2065 })();")
2067 (test-ps-js let*3
2068 (let ((x 3))
2069 (let* ((x 1)
2070 (y (+ x 2)))
2071 (+ x y)))
2072 "(function () {
2073 var x = 3;
2074 var x1 = 1;
2075 var y = x1 + 2;
2076 return x1 + y;
2077 })();")
2079 (test-ps-js let*4
2080 (let ((x 3))
2081 (let* ((y (+ x 2))
2082 (x 1))
2083 (+ x y)))
2084 "(function () {
2085 var x = 3;
2086 var y = x + 2;
2087 var x1 = 1;
2088 return x1 + y;
2089 })();")
2091 (test-ps-js symbol-macrolet-var
2092 (symbol-macrolet ((x y))
2093 (var x))
2094 "var y;")
2096 (test-ps-js setf-conditional1
2097 (setf x (unless (null a) (1+ a)))
2098 "x = a != null ? a + 1 : null;")
2100 (test-ps-js setf-let1
2101 (setf x (let ((a 1)) a))
2102 "x = (function () {
2103 var a = 1;
2104 return a;
2105 })();")
2107 (test-ps-js setf-let2
2108 (setf x (let ((a (foo)))
2109 (unless (null a)
2110 (1+ a))))
2111 "x = (function () {
2112 var a = foo();
2113 __PS_MV_REG = [];
2114 return a != null ? a + 1 : null;
2115 })();")
2117 (test-ps-js symbol-macro-env1
2118 (symbol-macrolet ((bar 1))
2119 (macrolet ((bar (x y) `(+ ,x ,y)))
2120 (bar bar bar)))
2121 "1 + 1;")
2123 (test-ps-js symbol-macrolet-fun1
2124 (symbol-macrolet ((baz +))
2125 (baz 1 2))
2126 "baz(1, 2);")
2128 (test-ps-js lisp2-namespaces1
2129 (let ((list nil))
2130 (setf list (list 1 2 3)))
2131 "(function () {
2132 var list = null;
2133 return list = [1, 2, 3];
2134 })();")
2136 (test-ps-js let-shadows-symbol-macrolet
2137 (symbol-macrolet ((x y))
2138 (let ((x 1))
2139 (+ x x))
2140 (+ x x))
2141 "(function () {
2142 var x1 = 1;
2143 return x1 + x1;
2144 })();
2145 y + y;")
2147 (test-ps-js let-rename-optimization1
2148 (let ((x 1))
2149 (+ x x))
2150 "(function () {
2151 var x = 1;
2152 return x + x;
2153 })();")
2155 (test-ps-js let-rename-optimization2
2156 (lambda (x)
2157 (let ((x (+ 1 x)))
2159 "function (x) {
2160 var x1 = 1 + x;
2161 return x1;
2162 };")
2164 (test-ps-js symbol-macro-array
2165 (symbol-macrolet ((x 1))
2166 (list x))
2167 "[1];")
2169 (test-ps-js symbol-macro-obj
2170 (symbol-macrolet ((x (+ 1 2)))
2171 (create x 1))
2172 "{ x : 1 };")
2174 (test-ps-js symbol-macro-obj1
2175 (symbol-macrolet ((x (+ 1 2)))
2176 (ps:create x x))
2177 "{ x : 1 + 2 };")
2179 (test-ps-js symbol-macro-getprop1
2180 (symbol-macrolet ((x (+ 1 2)))
2181 (ps:getprop a x))
2182 "a[1 + 2];")
2184 (test-ps-js symbol-macro-getprop1
2185 (symbol-macrolet ((x (+ 1 2)))
2186 (ps:getprop a 'x))
2187 "a.x;")
2189 (test-ps-js let-let-create
2190 (let ((a 99))
2191 (let ((a 22))
2192 (create a 33)))
2193 "(function () {
2194 var a = 99;
2195 var a1 = 22;
2196 return { a : 33 };
2197 })();")
2199 (test-ps-js symbol-macro-conditional1
2200 (symbol-macrolet ((x y))
2201 (if x x x))
2202 "if (y) {
2204 } else {
2206 };")
2208 (test-ps-js symbol-macro-conditional2
2209 (symbol-macrolet ((x y))
2210 (1+ (if x x x)))
2211 "(y ? y : y) + 1;")
2213 (test-ps-js preserve-this
2214 (defun foo ()
2215 (let ((y (block nil (bar this))))
2216 (baz y)))
2217 "function foo() {
2218 var y = (function () {
2219 __PS_MV_REG = [];
2220 return bar(this);
2221 }).call(this);
2222 __PS_MV_REG = [];
2223 return baz(y);
2224 };")
2226 (test-ps-js flet-apply
2227 (flet ((foo () 'bar))
2228 (apply (function foo) nil))
2229 "(function () {
2230 var foo = function () {
2231 return 'bar';
2233 return foo.apply(this, null);
2234 }).call(this);")
2236 (test-ps-js let-apply
2237 (let ((foo (lambda () 1)))
2238 (let ((foo (lambda () 2)))
2239 (apply foo nil)))
2240 "(function () {
2241 var foo = function () {
2242 return 1;
2244 var foo1 = function () {
2245 return 2;
2247 return foo1.apply(this, null);
2248 }).call(this);")
2250 (test-ps-js flet-let
2251 (flet ((x (x) (1+ x)))
2252 (let ((x 2))
2253 (x x)))
2254 "(function () {
2255 var x = function (x) {
2256 return x + 1;
2258 var x1 = 2;
2259 __PS_MV_REG = [];
2260 return x(x1);
2261 })();")
2263 (test-ps-js let-flet
2264 (let ((x 2))
2265 (flet ((x (x) (1+ x)))
2266 (x x)))
2267 "(function () {
2268 var x = 2;
2269 var x1 = function (x) {
2270 return x + 1;
2272 __PS_MV_REG = [];
2273 return x1(x);
2274 })();")
2276 (test-ps-js labels-let
2277 (labels ((x (x) (1+ x)))
2278 (let ((x 2))
2279 (x x)))
2280 "(function () {
2281 var x = function (x) {
2282 return x + 1;
2284 var x1 = 2;
2285 __PS_MV_REG = [];
2286 return x(x1);
2287 })();")
2289 (test-ps-js let-labels
2290 (let ((x 2))
2291 (labels ((x (x) (1+ x)))
2292 (x x)))
2293 "(function () {
2294 var x = 2;
2295 var x1 = function (x) {
2296 return x + 1;
2298 __PS_MV_REG = [];
2299 return x1(x);
2300 })();")
2302 (test-ps-js macrolet-let-inteference
2303 (macrolet ((a (n) `(+ ,n 5)))
2304 (let ((a (a 1)))
2305 (let ((b (a (- a 4))))
2306 (+ a b))))
2307 "(function () {
2308 var a = 1 + 5;
2309 var b = (a - 4) + 5;
2310 return a + b;
2311 })();")
2313 (test-ps-js let-subtract-add
2314 (let ((x 1))
2315 (let ((x 2))
2316 (- x x)
2317 (- x)
2318 (decf x)
2319 (incf x)))
2320 "(function () {
2321 var x = 1;
2322 var x1 = 2;
2323 x1 - x1;
2324 -x1;
2325 --x1;
2326 return ++x1;
2327 })();")
2329 (test-ps-js create-reserved-word
2330 (create :default 1)
2331 "{ 'default' : 1 };")
2333 (test-ps-js getprop-reserved-word
2334 (getprop foo :default)
2335 "foo['default'];")
2337 (test-ps-js getprop-reserved-word1
2338 (getprop foo 'default)
2339 "foo['default'];")
2341 (test-ps-js eval-when-ps-side
2342 (eval-when (:execute)
2344 "5;")
2346 (defvar *lisp-output* nil)
2348 (fiveam:test eval-when-lisp-side ()
2349 (setf *lisp-output* 'original-value)
2350 (let ((js-output
2351 (normalize-js-output
2352 (ps-doc* `(eval-when (:compile-toplevel)
2353 (setf *lisp-output* 'it-works))))))
2354 (fiveam:is (eql 'it-works *lisp-output*))
2355 (fiveam:is (string= "" js-output))))
2357 (defpsmacro my-in-package (package-name)
2358 `(eval-when (:compile-toplevel)
2359 (setf *lisp-output* ,package-name)))
2361 (fiveam:test eval-when-macro-expansion ()
2362 (setf *lisp-output* 'original-value)
2363 (let ((js-output
2364 (normalize-js-output
2365 (ps-doc* `(progn
2366 (my-in-package :cl-user)
2367 3)))))
2368 (declare (ignore js-output))
2369 (fiveam:is (eql :cl-user *lisp-output*))))
2371 (fiveam:test eval-when-macrolet-expansion ()
2372 (setf *lisp-output* 'original-value)
2373 (let ((js-output
2374 (normalize-js-output
2375 (ps-doc*
2376 `(macrolet ((my-in-package2 (package-name)
2377 `(eval-when (:compile-toplevel)
2378 (setf *lisp-output* ,package-name))))
2379 (my-in-package2 :cl-user)
2380 3)))))
2381 (declare (ignore js-output))
2382 (fiveam:is (eql :cl-user *lisp-output*))))
2384 (test-ps-js getprop-keyword
2385 (getprop foo :bar)
2386 "foo['bar'];")
2388 (test-ps-js nary-comparison1
2389 (lambda () (< 1 2 3))
2390 "function () {
2391 var _cmp1;
2392 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2393 };")
2395 (test-ps-js chain-getprop1
2396 (chain ($ "foo") (bar x z) frob (baz 5))
2397 "$('foo').bar(x, z).frob.baz(5);")
2399 (test-ps-js chain-getprop2
2400 (chain ($ "foo") bar baz)
2401 "$('foo').bar.baz;")
2403 (test-ps-js chain-getprop3
2404 (chain ($ "foo") bar (x y) baz)
2405 "$('foo').bar.x(y).baz;")
2407 (test-ps-js flet-expression
2408 (1+ (flet ((foo (x) (1+ x)))
2409 (foo 1)))
2410 "(function () {
2411 var foo = function (x) {
2412 return x + 1;
2414 __PS_MV_REG = [];
2415 return foo(1);
2416 })() + 1;")
2418 (test-ps-js flet-lambda-list
2419 (flet ((foo (x &key (y 0))
2420 (+ x y)))
2421 (foo 1 :y 2))
2422 "(function () {
2423 var foo = function (x) {
2424 var _js2 = arguments.length;
2425 for (var n1 = 1; n1 < _js2; n1 += 2) {
2426 switch (arguments[n1]) {
2427 case 'y':
2428 y = arguments[n1 + 1];
2431 var y = 'undefined' === typeof y ? 0 : y;
2432 return x + y;
2434 __PS_MV_REG = [];
2435 return foo(1, 'y', 2);
2436 })();")
2438 (test-ps-js return-case-break-elimination
2439 (defun foo ()
2440 (case 1
2441 (0 1)
2442 (otherwise 2)))
2443 "function foo() {
2444 switch (1) {
2445 case 0:
2446 return 1;
2447 default:
2448 return 2;
2450 };")
2452 (test-ps-js aplusplus
2454 "aplusplus;")
2456 (test-ps-js astarstar
2458 "astarstar;")
2460 (test-ps-js switch-return-fallthrough
2461 (defun foo ()
2462 (switch x
2463 (1 (foo) break)
2464 (2 (bar))
2465 (default 4)))
2466 "function foo() {
2467 switch (x) {
2468 case 1:
2469 __PS_MV_REG = [];
2470 return foo();
2471 case 2:
2472 bar();
2473 default:
2474 __PS_MV_REG = [];
2475 return 4;
2477 };")
2479 (test-ps-js return-last-case
2480 (defun foo ()
2481 (case x
2482 (:a 'eh)
2483 (:b 'bee)))
2484 "function foo() {
2485 switch (x) {
2486 case 'a':
2487 return 'eh';
2488 case 'b':
2489 return 'bee';
2491 };")
2493 (test-ps-js return-macrolet
2494 (defun foo ()
2495 (macrolet ((x () 1))
2496 (case (x)
2497 (:a 'eh)
2498 (:b 'bee))))
2499 "function foo() {
2500 switch (1) {
2501 case 'a':
2502 return 'eh';
2503 case 'b':
2504 return 'bee';
2506 };")
2508 (test-ps-js mv-bind1
2509 (multiple-value-bind (a b)
2510 (progn
2511 (returns-mv)
2512 (doesnt))
2513 (alert a)
2514 (alert b))
2515 "returnsMv();
2516 __PS_MV_REG = [];
2517 (function () {
2518 var a = doesnt();
2519 var b = __PS_MV_REG[0];
2520 alert(a);
2521 __PS_MV_REG = [];
2522 return alert(b);
2523 })();")
2525 (test-ps-js mv-bind2
2526 (multiple-value-bind (a b)
2527 (let ((a 1))
2528 (returns-mv a)
2529 (doesnt b))
2530 (alert a)
2531 (alert b))
2532 "(function () {
2533 var a = 1;
2534 returnsMv(a);
2535 __PS_MV_REG = [];
2536 var a1 = doesnt(b);
2537 var b = __PS_MV_REG[0];
2538 alert(a1);
2539 __PS_MV_REG = [];
2540 return alert(b);
2541 })();")
2543 (test-ps-js multiple-value-bind-simple
2544 (multiple-value-bind (a b) (blah)
2545 (+ a b))
2546 "__PS_MV_REG = [];
2547 (function () {
2548 var a = blah();
2549 var b = __PS_MV_REG[0];
2550 __PS_MV_REG = [];
2551 return a + b;
2552 })();")
2554 (test-ps-js values0
2555 (lambda () (values))
2556 "function () {
2557 return;
2558 };")
2560 (test-ps-js values1
2561 (lambda () (values x))
2562 "function () {
2563 return x;
2564 };")
2566 (test-ps-js values2
2567 (lambda () (values x y))
2568 "function () {
2569 var val1 = x;
2570 __PS_MV_REG = [y];
2571 return val1;
2572 };")
2574 (test-ps-js values3
2575 (lambda () (values x y z))
2576 "function () {
2577 var val1 = x;
2578 __PS_MV_REG = [y, z];
2579 return val1;
2580 };")
2582 (test-ps-js values-return
2583 (defun foo (x y)
2584 (return-from foo (values (* x x) y)))
2585 "function foo(x, y) {
2586 var val1 = x * x;
2587 __PS_MV_REG = [y];
2588 return val1;
2589 };")
2591 (test-ps-js return-macrolet1
2592 (defun foo ()
2593 (symbol-macrolet ((x 2))
2594 (loop do (+ x x))))
2595 "function foo() {
2596 while (true) {
2597 2 + 2;
2599 };")
2601 (test-ps-js return-cond
2602 (defun foo ()
2603 (return-from foo
2604 (cond ((foo? x) (loop for y in x do (foo y)))
2605 ((bar? x) x)
2606 (t 3))))
2607 "function foo() {
2608 if (foowhat(x)) {
2609 var _js2 = x.length;
2610 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2611 var y = x[_js1];
2612 foo(y);
2614 } else if (barwhat(x)) {
2615 __PS_MV_REG = [];
2616 return x;
2617 } else {
2618 __PS_MV_REG = [];
2619 return 3;
2621 };")
2623 (test-ps-js return-case
2624 (defun foo ()
2625 (return-from foo
2626 (case x
2627 (1 (loop for y in x do (foo y)))
2628 (2 x)
2629 ((t) 3))))
2630 "function foo() {
2631 switch (x) {
2632 case 1:
2633 var _js2 = x.length;
2634 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2635 var y = x[_js1];
2636 foo(y);
2638 __PS_MV_REG = [];
2639 return;
2640 case 2:
2641 __PS_MV_REG = [];
2642 return x;
2643 case true:
2644 __PS_MV_REG = [];
2645 return 3;
2647 };")
2649 (test-ps-js return-case1
2650 (defun foo ()
2651 (return-from foo
2652 (case x
2653 (1 (if a 1 2))
2654 (2 x)
2655 ((t) 3))))
2656 "function foo() {
2657 switch (x) {
2658 case 1:
2659 return a ? 1 : 2;
2660 case 2:
2661 return x;
2662 case true:
2663 return 3;
2665 };")
2667 (test-ps-js lambda-loop-if-return
2668 (lambda ()
2669 (if a
2670 (loop for y in x do (foo y))
2672 "function () {
2673 if (a) {
2674 var _js4 = x.length;
2675 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2676 var y = x[_js3];
2677 foo(y);
2679 } else {
2680 __PS_MV_REG = [];
2681 return c;
2683 };")
2685 (test-ps-js lambda-loop-if-return1
2686 (defun baz ()
2687 (foo (lambda ()
2688 (if a
2689 (progn (loop for y in x do (foo y))
2690 (return-from baz))
2691 c))))
2692 "function baz() {
2693 try {
2694 __PS_MV_REG = [];
2695 return foo(function () {
2696 if (a) {
2697 var _js4 = x.length;
2698 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2699 var y = x[_js3];
2700 foo(y);
2702 __PS_MV_REG = [];
2703 throw { '__ps_block_tag' : 'baz',
2704 '__ps_value' : null };
2705 } else {
2706 __PS_MV_REG = [];
2707 return c;
2710 } catch (_ps_err5) {
2711 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2712 __PS_MV_REG = [];
2713 return _ps_err5['__ps_value'];
2714 } else {
2715 throw _ps_err5;
2718 };")
2720 (test-ps-js switch-loop
2721 (defun foo (x)
2722 (case x
2723 (1 (dolist (a b)))))
2724 "function foo(x) {
2725 switch (x) {
2726 case 1:
2727 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2728 a = b[_js_idx1];
2730 return;
2732 };")
2734 (test-ps-js switch-folds-blocks
2735 (defun foo ()
2736 (case x
2737 (1 (loop repeat 3 do (alert "foo")))
2738 (2 "bar")))
2739 "function foo() {
2740 switch (x) {
2741 case 1:
2742 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2743 alert('foo');
2745 __PS_MV_REG = [];
2746 return;
2747 case 2:
2748 __PS_MV_REG = [];
2749 return 'bar';
2751 };")
2753 (test-ps-js setf-places-before-macros
2754 (lambda ()
2755 (defsetf left (el) (offset)
2756 `(setf (@ ,el style left) ,offset))
2757 (macrolet ((left (el)
2758 `(@ ,el offset-left)))
2759 (setf (left x) 10)
2760 (left x)))
2761 "function () {
2762 var _js2 = x;
2763 var _js1 = 10;
2764 _js2.style.left = _js1;
2765 return x.offsetLeft;
2766 };")
2768 (test-ps-js for-return
2769 (lambda () (dolist (arg args) (foo arg)))
2770 "function () {
2771 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2772 arg = args[_js_idx1];
2773 foo(arg);
2775 };")
2777 (test-ps-js try-catch-return
2778 (defun foo ()
2779 (try (foo)
2780 (:catch (e)
2781 (bar))
2782 (:finally
2783 (cleanup))))
2784 "function foo() {
2785 try {
2786 __PS_MV_REG = [];
2787 return foo();
2788 } catch (e) {
2789 __PS_MV_REG = [];
2790 return bar();
2791 } finally {
2792 cleanup();
2794 };")
2796 (test-ps-js let-try
2797 (let ((x (ps:try (+ 1 2)
2798 (:catch (y) 5))))
2800 "(function () {
2801 var x = (function () {
2802 try {
2803 return 1 + 2;
2804 } catch (y) {
2805 return 5;
2807 })();
2808 __PS_MV_REG = [];
2809 return x;
2810 })();")
2812 (test-ps-js try-finally-return-from
2813 (defun xyz ()
2814 (return-from xyz
2815 (ps:try (when (blah) 4)
2816 (:finally (foo))))
2817 (dont-call-me))
2818 "function xyz() {
2819 try {
2820 __PS_MV_REG = [];
2821 return blah() ? 4 : null;
2822 } finally {
2823 foo();
2825 __PS_MV_REG = [];
2826 return dontCallMe();
2827 };")
2829 (test-ps-js defun-setf-optional
2830 (defun (setf foo) (new-value b &optional c)
2831 (setf (aref b (or c 0)) new-value))
2832 "function __setf_foo(newValue, b, c) {
2833 return b[c || 0] = newValue;
2834 };")
2836 (test-ps-js defun-setf-rest
2837 (progn (defun (setf foo) (new-value b &rest foo)
2838 (do-something b foo new-value))
2839 (setf (foo x 1 2 3 4) 5))
2840 "function __setf_foo(newValue, b) {
2841 var foo = Array.prototype.slice.call(arguments, 2);
2842 __PS_MV_REG = [];
2843 return doSomething(b, foo, newValue);
2845 __setf_foo(5, x, 1, 2, 3, 4);")
2847 (test-ps-js return-null
2848 (defun foo () (return-from foo nil))
2849 "function foo() {
2850 return null;
2851 };")
2853 (test-ps-js implicit-return-null
2854 (lambda ()
2856 "function () {
2857 return null;
2858 };")
2860 (test-ps-js implicit-return-null
2861 (lambda ()
2862 nil)
2863 "function () {
2864 return null;
2865 };")
2867 (test-ps-js return-conditional-nested
2868 (defun blep (ss x y)
2869 (when foo?
2870 (let ((pair (bar)))
2871 (unless (null pair)
2872 (destructuring-bind (a b) pair
2873 (unless (or (null a) (null b))
2874 (let ((val (baz a b)))
2875 (unless (null val)
2876 (when (blah val)
2877 (unless (blee)
2878 t))))))))))
2879 "function blep(ss, x, y) {
2880 if (foowhat) {
2881 var pair = bar();
2882 if (pair != null) {
2883 var a = pair[0];
2884 var b = pair[1];
2885 if (!(a == null || b == null)) {
2886 var val = baz(a, b);
2887 if (val != null) {
2888 if (blah(val)) {
2889 __PS_MV_REG = [];
2890 return !blee() ? true : null;
2896 };")
2898 (test-ps-js return-when-returns-broken-return
2899 (defun foo ()
2900 (return-from foo (when x 1))
2901 (+ 2 3))
2902 "function foo() {
2903 return x ? 1 : null;
2904 return 2 + 3;
2905 };")
2907 (test-ps-js return-case-conditional
2908 (defun foo ()
2909 (return-from foo
2910 (case foo
2911 (123 (when (bar) t))
2912 (345 (blah)))))
2913 "function foo() {
2914 switch (foo) {
2915 case 123:
2916 __PS_MV_REG = [];
2917 return bar() ? true : null;
2918 case 345:
2919 __PS_MV_REG = [];
2920 return blah();
2922 };")
2924 (test-ps-js return-try-conditional
2925 (defun foo ()
2926 (return-from foo
2927 (try (when x 1)
2928 (:catch (x) 2)
2929 (:finally (bar)))))
2930 "function foo() {
2931 try {
2932 return x ? 1 : null;
2933 } catch (x) {
2934 return 2;
2935 } finally {
2936 bar();
2938 };")
2940 (test-ps-js function-declare-special
2941 (lambda ()
2942 (declare (special *foo*))
2943 (let ((*foo* 1))
2944 (1+ *foo*)))
2945 "function () {
2946 var FOO_TMPSTACK1;
2947 try {
2948 FOO_TMPSTACK1 = FOO;
2949 FOO = 1;
2950 return FOO + 1;
2951 } finally {
2952 FOO = FOO_TMPSTACK1;
2954 };")
2956 (test-ps-js declare-special-let
2957 (let ((*foo* 123))
2958 (declare (special *foo*))
2959 (blah))
2960 "(function () {
2961 var FOO_TMPSTACK1;
2962 try {
2963 FOO_TMPSTACK1 = FOO;
2964 FOO = 123;
2965 __PS_MV_REG = [];
2966 return blah();
2967 } finally {
2968 FOO = FOO_TMPSTACK1;
2970 })();")
2972 (test-ps-js declare-special-let-scope
2973 (block nil
2974 (let ((*foo* 123))
2975 (declare (special *foo*))
2976 (blah))
2977 (let ((*foo* 456))
2978 (+ 4 5)))
2979 "(function () {
2980 var FOO_TMPSTACK1;
2981 try {
2982 FOO_TMPSTACK1 = FOO;
2983 FOO = 123;
2984 blah();
2985 } finally {
2986 FOO = FOO_TMPSTACK1;
2988 var FOO = 456;
2989 __PS_MV_REG = [];
2990 return 4 + 5;
2991 })();")
2993 (test-ps-js declare-special-let*
2994 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
2995 (declare (special *foo* *bar*))
2996 (blah))
2997 "(function () {
2998 var FOO_TMPSTACK1;
2999 try {
3000 FOO_TMPSTACK1 = FOO;
3001 FOO = 123;
3002 var BAR_TMPSTACK2;
3003 try {
3004 BAR_TMPSTACK2 = BAR;
3005 BAR = FOO + BAR;
3006 __PS_MV_REG = [];
3007 return blah();
3008 } finally {
3009 BAR = BAR_TMPSTACK2;
3011 } finally {
3012 FOO = FOO_TMPSTACK1;
3014 })();")
3016 (test-ps-js defun-multiple-declarations-around-docstring
3017 (defun foo (x y)
3018 (declare (ignorable x y))
3019 (declare (integer x) (float y))
3020 "Fooes X while barring Y."
3021 (declare (special *foo*) (special *bar*))
3022 (let ((*bar* (bar y)))
3023 (funcall *foo* x)))
3024 "/** Fooes X while barring Y. */
3025 function foo(x, y) {
3026 var BAR_TMPSTACK1;
3027 try {
3028 BAR_TMPSTACK1 = BAR;
3029 BAR = bar(y);
3030 __PS_MV_REG = [];
3031 return FOO(x);
3032 } finally {
3033 BAR = BAR_TMPSTACK1;
3035 };")
3037 (test-ps-js macro-null-toplevel
3038 (progn
3039 (defmacro macro-null-toplevel ()
3040 nil)
3041 (macro-null-toplevel))
3044 (test-ps-js define-symbol-macro-let
3045 (progn
3046 (define-symbol-macro test-symbol-macro 1)
3047 (let ((test-symbol-macro 2))
3048 (1+ test-symbol-macro))
3049 (1+ test-symbol-macro))
3050 "(function () {
3051 var testSymbolMacro1 = 2;
3052 return testSymbolMacro1 + 1;
3053 })();
3054 1 + 1;")
3056 (test-ps-js define-symbol-macro-flet
3057 (progn
3058 (define-symbol-macro test-symbol-macro1 1)
3059 (flet ((test-symbol-macro1 () 2))
3060 (foo test-symbol-macro1)
3061 (test-symbol-macro1))
3062 (bar test-symbol-macro1))
3063 "(function () {
3064 var testSymbolMacro1_1 = function () {
3065 return 2;
3067 foo(1);
3068 __PS_MV_REG = [];
3069 return testSymbolMacro1_1();
3070 })();
3071 bar(1);")
3073 (fiveam:test compile-stream-nulls
3074 (fiveam:is
3075 (string=
3076 (with-input-from-string (s "
3077 (defmacro macro-null-toplevel ()
3078 nil)
3079 (macro-null-toplevel)")
3080 (ps-compile-stream s))
3081 "")))
3083 (fiveam:test compile-stream1
3084 (fiveam:is
3085 (string=
3086 (with-input-from-string (s "
3087 (define-symbol-macro test-symbol-macro1 1)
3088 (flet ((test-symbol-macro1 () 2))
3089 (foo test-symbol-macro1)
3090 (test-symbol-macro1))
3091 (bar test-symbol-macro1)")
3092 (ps::with-blank-compilation-environment
3093 (ps-compile-stream s)))
3094 "(function () {
3095 var testSymbolMacro1_1 = function () {
3096 return 2;
3098 foo(1);
3099 __PS_MV_REG = [];
3100 return testSymbolMacro1_1();
3101 })();
3102 bar(1);
3103 ")))
3105 (test-ps-js equality-nary1
3106 (let ((x 10) (y 10) (z 10))
3107 (= x y z))
3108 "(function () {
3109 var _cmp1;
3110 var x = 10;
3111 var y = 10;
3112 var z = 10;
3113 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3114 })();")
3116 (test-ps-js equality1
3117 (progn
3118 (equal a b)
3119 (eql a b)
3120 (eq a b)
3121 (= a b))
3122 "a == b;
3123 a === b;
3124 a === b;
3125 a === b;")
3127 (test-ps-js getprop-quote-reserved
3128 (getprop foo ':break)
3129 "foo['break'];")
3131 (test-ps-js defun-block-return-from
3132 (defun foo (x)
3133 (baz 4)
3134 (return-from foo x)
3135 (bar 5))
3136 "function foo(x) {
3137 baz(4);
3138 __PS_MV_REG = [];
3139 return x;
3140 __PS_MV_REG = [];
3141 return bar(5);
3142 };")
3144 (test-ps-js block-return-from
3145 (block scope
3146 (foo)
3147 (when (bar)
3148 (return-from scope))
3149 (blee))
3150 "(function () {
3151 foo();
3152 if (bar()) {
3153 __PS_MV_REG = [];
3154 return null;
3156 __PS_MV_REG = [];
3157 return blee();
3158 })();")
3160 (test-ps-js block-return-from0
3161 (defun baz ()
3162 (block scope
3163 (foo)
3164 (when (bar)
3165 (return-from scope))
3166 (blee)))
3167 "function baz() {
3168 foo();
3169 if (bar()) {
3170 __PS_MV_REG = [];
3171 return null;
3173 __PS_MV_REG = [];
3174 return blee();
3175 };")
3177 (test-ps-js block-return-from01
3178 (defun baz ()
3179 (block scope
3180 (foo)
3181 (when (bar)
3182 (return-from scope))
3183 (blee))
3185 "function baz() {
3186 scope: {
3187 foo();
3188 if (bar()) {
3189 __PS_MV_REG = [];
3190 break scope;
3192 blee();
3194 __PS_MV_REG = [];
3195 return 2;
3196 };")
3198 (test-ps-js block-return-from02
3199 (defun baz ()
3200 (block scope
3201 (foo)
3202 (when (bar)
3203 (return-from scope (foobar)))
3204 (blee))
3206 "function baz() {
3207 scope: {
3208 foo();
3209 if (bar()) {
3210 __PS_MV_REG = [];
3211 foobar();
3212 break scope;
3214 blee();
3216 __PS_MV_REG = [];
3217 return 2;
3218 };")
3220 (test-ps-js block-return-from1
3221 (lambda ()
3222 (block scope
3223 (foo)
3224 (when (bar)
3225 (return-from scope))
3226 (blee))
3227 (+ 1 2))
3228 "function () {
3229 scope: {
3230 foo();
3231 if (bar()) {
3232 __PS_MV_REG = [];
3233 break scope;
3235 blee();
3237 __PS_MV_REG = [];
3238 return 1 + 2;
3239 };")
3241 (test-ps-js block-return-from2
3242 (lambda ()
3243 (bar 5)
3244 (block scope
3245 (foo)
3246 (when (bar)
3247 (return-from scope 6))
3248 (blee)))
3249 "function () {
3250 bar(5);
3251 foo();
3252 if (bar()) {
3253 __PS_MV_REG = [];
3254 return 6;
3256 __PS_MV_REG = [];
3257 return blee();
3258 };")
3260 (test-ps-js let-funcall
3261 (let ((x foo))
3262 (funcall x)
3263 (let ((x bar))
3264 (funcall x))
3265 (funcall x))
3266 "(function () {
3267 var x = foo;
3268 x();
3269 var x1 = bar;
3270 x1();
3271 return x();
3272 })();")
3274 (test-ps-js symbol-macrolet-funcall
3275 (symbol-macrolet ((foo bar))
3276 (funcall foo 1 2 3))
3277 "bar(1, 2, 3);")
3279 (test-ps-js times-assign
3280 (setf x (* x 1000))
3281 "x *= 1000;")
3283 (test-ps-js vector-literal
3284 #(1 2 3)
3285 "[1, 2, 3];")
3287 (test-ps-js vector-literal1
3288 #(1 2 #(a b) 3)
3289 "[1, 2, ['a', 'b'], 3];")
3291 (test-ps-js rem1
3292 (+ 1 (rem 2 (+ 3 4)))
3293 "1 + 2 % (3 + 4);")
3295 (test-ps-js non-associative
3296 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3297 "1 / (2 / 3) + (1 - (2 - 3));")
3299 (test-ps-js lambda-apply
3300 (lambda (x)
3301 (apply (lambda (y) (bar (1+ y))) x))
3302 "function (x) {
3303 return (function (y) {
3304 __PS_MV_REG = [];
3305 return bar(y + 1);
3306 }).apply(this, x);
3307 };")
3309 (test-ps-js operator-expressions-nested-let
3310 (let ((x (let ((y 1))
3311 y)))
3313 "(function () {
3314 var y;
3315 var x = (y = 1, y);
3316 return x;
3317 })();")
3319 (test-ps-js operator-expressions-array-nested-let
3320 (list (let ((y 1)) y) 2)
3321 "[(function () {
3322 var y = 1;
3323 return y;
3324 })(), 2];")
3326 (test-ps-js add-subtract-precedence
3327 (- x (+ y z))
3328 "x - (y + z);")
3330 (test-ps-js ps-inline-toplevel
3331 (ps-inline (foo))
3332 "'javascript:' + 'foo()';")
3334 (test-ps-js no-clause-progn-exp
3335 (setf x (progn))
3336 "x = null;")
3338 (test-ps-js no-clause-progn-return
3339 (defun foo ()
3340 (return-from foo (progn)))
3341 "function foo() {
3342 return null;
3343 };")
3345 (test-ps-js empty-cond-clause
3346 (setf x (cond ((foo))))
3347 "x = (function () {
3348 var testResult1 = foo();
3349 __PS_MV_REG = [];
3350 return testResult1 ? testResult1 : null;
3351 })();")
3353 (test-ps-js empty-cond-clause1
3354 (setf x (cond ((foo) 123)
3355 ((bar))
3356 (t 456)))
3357 "x = foo() ? 123 :
3358 (function () {
3359 var testResult1 = bar();
3360 if (testResult1) {
3361 __PS_MV_REG = [];
3362 return testResult1;
3363 } else {
3364 if (true) {
3365 __PS_MV_REG = [];
3366 return 456;
3369 })();")
3371 (test-ps-js let-no-body
3372 (defun foo ()
3373 (return-from foo (let ((foo bar)))))
3374 "function foo() {
3375 var foo1 = bar;
3376 return null;
3377 };")
3379 (test-ps-js rename-lexical-dupes
3380 (lambda ()
3381 (list (let ((foo 12)) (* foo 2))
3382 (let ((foo 13)) (* foo 3))))
3383 "function () {
3384 var foo;
3385 var foo1;
3386 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3387 };")
3389 (test-ps-js defun-comment1
3390 (defun foo (x)
3391 "BARBAR is a revolutionary new foobar.
3392 X y and x."
3393 (1+ x))
3394 "/**
3395 * BARBAR is a revolutionary new foobar.
3396 * X y and x.
3398 function foo(x) {
3399 return x + 1;
3400 };")
3402 (test-ps-js var-comment
3403 (var x 1 "foo")
3404 "/** foo */
3405 var x = 1;")
3407 (test-ps-js case-return-break-broken-return
3408 (defun foo ()
3409 (case x
3410 ("bar" (if y (return-from foo t) nil))
3411 ("baz" nil)))
3412 "function foo() {
3413 switch (x) {
3414 case 'bar':
3415 if (y) {
3416 return true;
3417 } else {
3418 return null;
3420 case 'baz':
3421 return null;
3423 };")
3425 (test-ps-js case-return-break1-broken-return
3426 (defun foo ()
3427 (case x
3428 ("bar" (if y (return-from foo t)))
3429 ("baz" nil)))
3430 "function foo() {
3431 switch (x) {
3432 case 'bar':
3433 if (y) {
3434 return true;
3435 } else {
3436 return null;
3438 case 'baz':
3439 return null;
3441 };")
3443 (test-ps-js setf-progn
3444 (setf foo (progn (bar) (baz) 3))
3445 "bar();
3446 baz();
3447 foo = 3;")
3449 (test-ps-js var-progn
3450 (var x (progn (foo) (bar)))
3451 "foo();
3452 var x = bar();")
3454 (test-ps-js implicit-return-loop
3455 (lambda ()
3456 (if baz 7
3457 (progn
3458 (loop :repeat 100 :do (bar))
3459 42)))
3460 "function () {
3461 if (baz) {
3462 return 7;
3463 } else {
3464 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3465 bar();
3467 __PS_MV_REG = [];
3468 return 42;
3470 };")
3472 (test-ps-js loop-closures
3473 (dotimes (i 10) (lambda () (+ i 1)))
3474 "(function () {
3475 for (var i = 0; i < 10; i += 1) {
3476 function () {
3477 return i + 1;
3480 })();")
3482 (test-ps-js loop-closures-let
3483 (dotimes (i 10)
3484 (let ((x (+ i 1)))
3485 (lambda () (+ i x))))
3486 "(function () {
3487 for (var i = 0; i < 10; i += 1) {
3488 (function () {
3489 var x = i + 1;
3490 return function () {
3491 return i + x;
3493 })();
3495 })();")
3497 (test-ps-js loop-closures-flet
3498 (dotimes (i 10)
3499 (flet ((foo (x) (+ i x)))
3500 (lambda () (foo i))))
3501 "(function () {
3502 for (var i = 0; i < 10; i += 1) {
3503 (function () {
3504 var foo = function (x) {
3505 return i + x;
3507 return function () {
3508 __PS_MV_REG = [];
3509 return foo(i);
3511 })();
3513 })();")
3515 (test-ps-js while-closures-let
3516 (loop while (foo) do
3517 (let ((abc (bar)))
3518 (lambda () (+ 1 abc))))
3519 "(function () {
3520 while (foo()) {
3521 (function () {
3522 var abc = bar();
3523 __PS_MV_REG = [];
3524 return function () {
3525 return 1 + abc;
3527 })();
3529 })();")
3531 (test-ps-js dotted-list-form
3532 (defun foo (a)
3533 (when a
3534 (destructuring-bind (b . c)
3536 (list b c))))
3537 "function foo(a) {
3538 if (a) {
3539 var b = bar[0];
3540 var c = bar.length > 1 ? bar.slice(1) : [];
3541 __PS_MV_REG = [];
3542 return [b, c];
3544 };")
3546 (test-ps-js explicit-nil-block
3547 (defun bar ()
3548 (foo 1)
3549 (block nil (return (foo 2)) (+ 1 2))
3551 "function bar() {
3552 foo(1);
3553 nilBlock: {
3554 __PS_MV_REG = [];
3555 foo(2);
3556 break nilBlock;
3557 1 + 2;
3559 __PS_MV_REG = [];
3560 return 2;
3561 };")
3563 (test-ps-js dynamic-extent-function-return
3564 (defun foo ()
3565 ((lambda ()
3566 (return-from foo 6))))
3567 "function foo() {
3568 try {
3569 __PS_MV_REG = [];
3570 return (function () {
3571 throw { '__ps_block_tag' : 'foo', '__ps_value' : 6 };
3572 })();
3573 } catch (_ps_err1) {
3574 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3575 __PS_MV_REG = [];
3576 return _ps_err1['__ps_value'];
3577 } else {
3578 throw _ps_err1;
3581 };")
3583 (test-ps-js dynamic-extent-function-return-nothing
3584 (defun foo ()
3585 ((lambda ()
3586 (return-from foo))))
3587 "function foo() {
3588 try {
3589 __PS_MV_REG = [];
3590 return (function () {
3591 throw { '__ps_block_tag' : 'foo', '__ps_value' : null };
3592 })();
3593 } catch (_ps_err1) {
3594 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3595 __PS_MV_REG = [];
3596 return _ps_err1['__ps_value'];
3597 } else {
3598 throw _ps_err1;
3601 };")
3603 (test-ps-js dynamic-extent-function-return-values
3604 (defun foo ()
3605 ((lambda ()
3606 (return-from foo (values 1 2 3)))))
3607 "function foo() {
3608 try {
3609 __PS_MV_REG = [];
3610 return (function () {
3611 var val1 = 1;
3612 __PS_MV_REG = [2, 3];
3613 throw { '__ps_block_tag' : 'foo',
3614 '__ps_value' : val1 };
3615 })();
3616 } catch (_ps_err2) {
3617 if (_ps_err2 && 'foo' === _ps_err2['__ps_block_tag']) {
3618 return _ps_err2['__ps_value'];
3619 } else {
3620 throw _ps_err2;
3623 };")
3625 (test-ps-js dynamic-extent-function-return-funcall
3626 (defun foo ()
3627 ((lambda ()
3628 (return-from foo (if baz 6 5)))))
3629 "function foo() {
3630 try {
3631 __PS_MV_REG = [];
3632 return (function () {
3633 throw { '__ps_block_tag' : 'foo', '__ps_value' : baz ? 6 : 5 };
3634 })();
3635 } catch (_ps_err1) {
3636 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3637 __PS_MV_REG = [];
3638 return _ps_err1['__ps_value'];
3639 } else {
3640 throw _ps_err1;
3643 };")
3645 (test-ps-js block-dynamic-return
3646 (defvar foo ((lambda ()
3647 (block nil
3648 ((lambda () (return 6)))
3649 (+ 1 2)))))
3650 "if ('undefined' === typeof foo) {
3651 var foo = (function () {
3652 try {
3653 (function () {
3654 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
3655 })();
3656 __PS_MV_REG = [];
3657 return 1 + 2;
3658 } catch (_ps_err1) {
3659 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3660 __PS_MV_REG = [];
3661 return _ps_err1['__ps_value'];
3662 } else {
3663 throw _ps_err1;
3666 })(); };")
3668 (test-ps-js iteration-lambda-capture-no-need
3669 (dolist (x y)
3670 (lambda (x) (1+ x)))
3671 "(function () {
3672 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3673 x = y[_js_idx1];
3674 function (x) {
3675 return x + 1;
3678 })();")
3680 (test-ps-js case-invert1
3681 (encodeURIComponent fooBar)
3682 "encodeURIComponent(fooBar);")
3684 (test-ps-js simple-ash
3685 (+ (ash 4 1) (ash 4 -1))
3686 "(4 << 1) + (4 >> 1);")
3688 (test-ps-js progn-nil-expression
3689 (bar (progn (foo) nil))
3690 "bar((foo(), null));")
3692 (test-ps-js other-progn-nil-exp
3693 (defun blah ()
3694 (or (foo) (progn (bar) nil)))
3695 "function blah() {
3696 __PS_MV_REG = [];
3697 return foo() || (bar(), null);
3698 };")
3700 (test-ps-js lambda-nil-return
3701 (lambda (x)
3702 (block nil
3703 (when x
3704 (return 1))
3706 "function (x) {
3707 if (x) {
3708 return 1;
3710 return 2;
3711 };")
3713 (test-ps-js lambda-nil-return-implicit-nested2
3714 (lambda (x)
3715 (block foo
3716 (if x
3717 (return-from foo 1)
3718 (dotimes (i 4)
3719 (return-from foo i)))
3721 "function (x) {
3722 if (x) {
3723 return 1;
3724 } else {
3725 for (var i = 0; i < 4; i += 1) {
3726 return i;
3729 return 2;
3730 };")
3732 (test-ps-js throw-is-a-statement
3733 (defun blah ()
3734 (let ((result (foo)))
3735 (unless (null result)
3736 (throw result))))
3737 "function blah() {
3738 var result = foo();
3739 if (result != null) {
3740 throw result;
3742 };")
3744 (test-ps-js expressify1
3745 (defun blah ()
3746 (when (some-condition)
3747 (foo)
3748 (bar)
3749 (baz)))
3750 "function blah() {
3751 if (someCondition()) {
3752 foo();
3753 bar();
3754 __PS_MV_REG = [];
3755 return baz();
3757 };")
3759 (test-ps-js case-when-return
3760 (defun blah (a)
3761 (case a
3762 ("a" (when (foo) (return-from blah 111)))
3763 ("b" t)))
3764 "function blah(a) {
3765 switch (a) {
3766 case 'a':
3767 if (foo()) {
3768 __PS_MV_REG = [];
3769 return 111;
3770 } else {
3771 __PS_MV_REG = [];
3772 return null;
3774 case 'b':
3775 __PS_MV_REG = [];
3776 return true;
3778 };")
3780 (test-ps-js flet-return-from
3781 (defun abc ()
3782 (flet ((foo ()
3783 (return-from foo 123)))
3784 (foo)))
3785 "function abc() {
3786 var foo = function () {
3787 return 123;
3789 __PS_MV_REG = [];
3790 return foo();
3791 };")
3793 (test-ps-js flet-return-from1
3794 (flet ((foo ()
3795 (return-from foo 123)))
3796 (foo))
3797 "(function () {
3798 var foo = function () {
3799 return 123;
3801 __PS_MV_REG = [];
3802 return foo();
3803 })();")
3805 (test-ps-js lambda-docstring-declarations
3806 (lambda (x)
3807 "This is a docstring"
3808 (declare (ignore x))
3810 "function (x) {
3811 return 2;
3812 };")
3814 (test-ps-js setf-let-exp
3815 (setf foo (let ((x (+ 1 2)))
3816 (if x 123 456)))
3817 "foo = (function () {
3818 var x = 1 + 2;
3819 return x ? 123 : 456;
3820 })();")
3822 (test-ps-js create-let-exp
3823 (create :abc (let ((x (+ 1 2)))
3824 (if x 123 456)))
3825 "{ 'abc' : (function () {
3826 var x = 1 + 2;
3827 return x ? 123 : 456;
3828 })() };")
3830 (test-ps-js eql-eql-eql-precedence
3831 (unless (equal (= 3 3) (= 3 4))
3832 (chain console (log 1)))
3833 "if ((3 === 3) != (3 === 4)) {
3834 console.log(1);
3835 };")
3837 (test-ps-js case-cond-breaks
3838 (defun blah (x)
3839 (case x
3840 (123 (cond ((foo1)
3841 (when (foo2)
3842 (when (foo3)
3843 (return-from blah nil))
3844 t))))
3845 (456 (foo7))))
3846 "function blah(x) {
3847 switch (x) {
3848 case 123:
3849 if (foo1()) {
3850 if (foo2()) {
3851 if (foo3()) {
3852 __PS_MV_REG = [];
3853 return null;
3855 __PS_MV_REG = [];
3856 return true;
3857 } else {
3858 __PS_MV_REG = [];
3859 return null;
3861 } else {
3862 __PS_MV_REG = [];
3863 return null;
3865 case 456:
3866 __PS_MV_REG = [];
3867 return foo7();
3869 };")
3871 (test-ps-js cond-double-t
3872 (lambda ()
3873 (cond (foo 1)
3874 (t 2)
3875 (t 3)))
3876 "function () {
3877 if (foo) {
3878 return 1;
3879 } else {
3880 return 2;
3882 };")
3884 (test-ps-js let-let-funcall-lambda
3885 (let ((x 5))
3886 (let ((x 7))
3887 (funcall (lambda (x) (+ x 9)) x)))
3888 "(function () {
3889 var x = 5;
3890 var x1 = 7;
3891 return (function (x) {
3892 return x + 9;
3893 })(x1);
3894 })();")
3896 (test-ps-js let-let-lambda
3897 (let ((x 5))
3898 (let ((x 7))
3899 (lambda (x) (+ x 9))))
3900 "(function () {
3901 var x = 5;
3902 var x1 = 7;
3903 return function (x) {
3904 return x + 9;
3906 })();")
3908 (test-ps-js let-lambda
3909 (let ((x 5))
3910 (lambda (x) (+ x 9)))
3911 "(function () {
3912 var x = 5;
3913 return function (x) {
3914 return x + 9;
3916 })();")
3918 (test-ps-js symbol-macrolet-no-shadow-lambda
3919 (symbol-macrolet ((x y))
3920 (lambda (x) (+ x x)))
3921 "function (x) {
3922 return x + x;
3923 };")
3925 (test-ps-js divide-one-arg-reciprocal
3926 (/ 2)
3927 "1 / 2;")
3929 (test-ps-js division-not-associative
3930 (/ a (* b c))
3931 "a / (b * c);")
3933 (test-ps-js divide-expressions
3934 (/ (foo) (bar))
3935 "foo() / bar();")
3937 (test-ps-js divide-expressions1
3938 (floor (1- x) y)
3939 "Math.floor((x - 1) / y);")
3941 (test-ps-js lexical-funargs-shadow1
3942 (lambda (x)
3943 (let ((x 1))
3944 (foo x))
3945 (incf x))
3946 "function (x) {
3947 var x1 = 1;
3948 foo(x1);
3949 __PS_MV_REG = [];
3950 return ++x;
3951 };")
3953 (test-ps-js times-rem
3954 (* x (rem y z))
3955 "x * (y % z);")
3957 (test-ps-js rem-divide
3958 (/ x (rem y z))
3959 "x / (y % z);")
3961 (test-ps-js case-break-return
3962 (lambda () (case x (:foo) (:bar 1)))
3963 "function () {
3964 switch (x) {
3965 case 'foo':
3966 return null;
3967 case 'bar':
3968 return 1;
3970 };")
3972 (test-ps-js trivial-expression-switch
3973 (foobar (case x (1 2)))
3974 "foobar((function () {
3975 switch (x) {
3976 case 1:
3977 return 2;
3979 })());")
3981 (test-ps-js trivial-expression-while
3982 (foobar (loop while (< 0 x) do (decf x)))
3983 "foobar((function () {
3984 while (0 < x) {
3985 --x;
3987 })());")
3989 (test-ps-js funcall-block-expression-loop-lambda
3990 (foobar (loop for i from 0 to 10 do (1+ i)))
3991 "foobar((function () {
3992 for (var i = 0; i <= 10; i += 1) {
3993 i + 1;
3995 })());")
3997 (test-ps-js plus-block-expression-loop-lambda
3998 (1+ (loop for i from 0 to 10 do (1+ i)))
3999 "(function () {
4000 for (var i = 0; i <= 10; i += 1) {
4001 i + 1;
4003 })() + 1;")
4005 (test-ps-js let-closures-rename
4006 (lambda ()
4007 (let ((x 1)) (lambda () (1+ x)))
4008 (let ((x 2)) (lambda () (1+ x))))
4009 "function () {
4010 var x = 1;
4011 function () {
4012 return x + 1;
4014 var x1 = 2;
4015 return function () {
4016 return x1 + 1;
4018 };")
4020 (test-ps-js let-closures-rename1
4021 (lambda ()
4022 (let ((x 1))
4023 (let ((y 2))
4024 (lambda () (+ x y))))
4025 (let ((x 2))
4026 (let ((y 3))
4027 (lambda () (+ x y)))))
4028 "function () {
4029 var x = 1;
4030 var y = 2;
4031 function () {
4032 return x + y;
4034 var x1 = 2;
4035 var y2 = 3;
4036 return function () {
4037 return x1 + y2;
4039 };")
4041 (test-ps-js let-closures-rename2
4042 (defun make-closures ()
4043 (list
4044 (let ((x 1)) (lambda () (1+ x)))
4045 (let ((x 2)) (lambda () (1+ x)))))
4046 "function makeClosures() {
4047 var x;
4048 var x1;
4049 return [(x = 1, function () {
4050 return x + 1;
4051 }), (x1 = 2, function () {
4052 return x1 + 1;
4053 })];
4055 };")
4057 (test-ps-js conditional-not-used-up
4058 (lambda (bar)
4059 (when bar
4060 (let ((x 1))
4061 (1+ x))))
4062 "function (bar) {
4063 if (bar) {
4064 var x = 1;
4065 return x + 1;
4067 };")
4069 (test-ps-js toplevel-local-scope
4070 (create "fn" (let ((x 5)) (lambda () x)))
4071 "{ 'fn' : (function () {
4072 var x = 5;
4073 return function () {
4074 return x;
4076 })() };")
4078 (test-ps-js toplevel-local-scope1
4079 (defparameter foo (create "fn" (let ((x 5)) (lambda () x))))
4080 "var foo = { 'fn' : (function () {
4081 var x = 5;
4082 return function () {
4083 return x;
4085 })() };")
4087 (test-ps-js block-let
4088 (block foobar
4089 (let ((x 1))
4090 (return-from foobar x)
4092 "(function () {
4093 var x = 1;
4094 return x;
4095 return 2;
4096 })();")
4098 (test-ps-js expressionize-if-macroexpand-error
4099 (progn (defmacro xbaz () `(blah))
4101 (defun foo (xbaz)
4102 (unless (blah)
4103 (cond (xbaz (blah))
4104 (t (blahblah))))))
4105 "function foo(xbaz) {
4106 if (!blah()) {
4107 if (xbaz) {
4108 __PS_MV_REG = [];
4109 return blah();
4110 } else {
4111 __PS_MV_REG = [];
4112 return blahblah();
4115 };")
4117 (test-ps-js toplevel-defun-macroexpand
4118 (progn (defmacro defun-js (name lambda-list &body body)
4119 `(defun ,name ,lambda-list ,@body))
4121 (let ((foo 0))
4122 (defun-js bar () (1+ foo))
4123 (defvar baz 2)))
4124 "var foo = 0;
4125 function bar() {
4126 return foo + 1;
4128 if ('undefined' === typeof baz) { var baz = 2; };")
4130 (test-ps-js js-ir-package-unique-symbols
4131 (loop :for i :from 0 :below 5 :do
4132 (let ((block (elt blocks i)))
4133 (foo block)
4134 (lambda () nil)))
4135 "(function () {
4136 for (var i = 0; i < 5; i += 1) {
4137 var block = blocks[i];
4138 foo(block);
4139 function () {
4140 return null;
4143 })();")
4145 (test-ps-js broken-quote-expansion1
4146 (lambda (p)
4147 (with-slots (x y) p
4148 (if (< x 0) y x)))
4149 "function (p) {
4150 return p.x < 0 ? p.y : p.x;
4151 };")
4153 (test-ps-js broken-quote-expansion2
4154 (progn
4155 (define-symbol-macro foo123 (ps:@ a foo123))
4156 (lambda () (when (> foo123 1) 2)))
4157 "function () {
4158 return a.foo123 > 1 ? 2 : null;
4159 };")
4161 (test-ps-js unused-named-block-not-printed1
4162 (block foobar
4163 (+ 1 2 3))
4164 "(function () {
4165 return 1 + 2 + 3;
4166 })();")
4168 (test-ps-js unused-named-block-not-printed2
4169 (block nil
4170 (block nil
4171 (+ 1 2 3)))
4172 "(function () {
4173 return 1 + 2 + 3;
4174 })();")
4176 (test-ps-js unused-named-block-not-printed3
4177 (block foobar
4178 (block nil
4179 (+ 1 2 3)))
4180 "(function () {
4181 return 1 + 2 + 3;
4182 })();")
4184 (test-ps-js unused-named-block-not-printed4
4185 (block nil
4186 (block foobar
4187 (block nil
4188 (+ 1 2 3))))
4189 "(function () {
4190 return 1 + 2 + 3;
4191 })();")
4193 (test-ps-js trig-no-bind1
4194 (cosh 3.14)
4195 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4197 (test-ps-js trig-bind1
4198 (acosh (blah 3.14))
4199 "(function () {
4200 var x1 = blah(3.14);
4201 __PS_MV_REG = [];
4202 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4203 })();")
4205 (test-ps-js double-negation
4206 (or (not foo) (not (not foo)) (not (not (not foo))))
4207 "!foo || foo || !foo;")
4209 (test-ps-js empty-let
4210 (defun foo ()
4211 (let ((a (bar)))))
4212 "function foo() {
4213 var a = bar();
4214 __PS_MV_REG = [];
4215 return null;
4216 };")
4218 (test-ps-js empty-let*
4219 (defun foo ()
4220 (let* ((a (bar)))))
4221 "function foo() {
4222 var a = bar();
4223 __PS_MV_REG = [];
4224 return null;
4225 };")
4227 (test-ps-js defun-no-body-declare
4228 (defun foo () (declare (ignore x)))
4229 "function foo() {
4230 return null;
4231 };")
4233 (test-ps-js defun-no-body-let-declare
4234 (defun foo () (let () (declare (ignore x))))
4235 "function foo() {
4236 return null;
4237 };")
4239 (test-ps-js empty-defun-docstring-declare
4240 (defun foo (x)
4241 "docstring"
4242 (declare (ignore x)))
4243 "/** docstring */
4244 function foo(x) {
4245 return null;
4246 };")
4248 (test-ps-js defun-docstring-string
4249 (defun foo (x)
4250 "docstring"
4251 "abc")
4252 "/** docstring */
4253 function foo(x) {
4254 return 'abc';
4255 };")
4257 (test-ps-js return-object
4258 (defun foo (obj)
4259 (ps:create :abc (let ((x (ps:getprop obj "blah")))
4260 (if x 123 456))))
4261 "function foo(obj) {
4262 var x;
4263 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4264 };")
4266 (test-ps-js unicode-strings
4267 "фоо бар"
4268 "'фоо бар';")
4270 (test-ps-js expressionize-return
4271 (defun next-page (self)
4272 (with-slots (limit offset count)
4273 (@ self state)
4274 (when (and count (< (* limit offset) count))
4275 (set-state self (create x (+ offset 1))))))
4276 "function nextPage(self) {
4277 var object1 = self.state;
4278 __PS_MV_REG = [];
4279 return object1.count && object1.limit * object1.offset < object1.count ? setState(self, { x : object1.offset + 1 }) : null;
4280 };")
4282 (test-ps-js let-defun-toplevel
4283 (progn (let ((foo 0))
4284 (defun bar () foo))
4285 (bar))
4286 "var foo = 0;
4287 function bar() {
4288 return foo;
4290 bar();")
4292 (test-ps-js let-defvar-toplevel
4293 (progn (let ((foo 0))
4294 (defvar bar (1+ foo)))
4295 bar)
4296 "var foo = 0;
4297 if ('undefined' === typeof bar) { var bar = foo + 1; };
4298 bar;")
4300 (test-ps-js setf-side-effects
4301 (let ((x 10))
4302 (defun side-effect()
4303 (setf x 4)
4305 (setf x (+ 2 (side-effect) x 5)))
4306 "var x = 10;
4307 function sideEffect() {
4308 x = 4;
4309 return 3;
4311 x = 2 + sideEffect() + x + 5;")
4313 (test-ps-js stupid-lisp-trick
4314 (alert
4315 (lisp
4316 (progn
4317 (write-string "[1,2,3]" ps::*psw-stream*)
4318 (values))))
4319 "alert([1,2,3]);")
4321 (test-ps-js maybe-once-only-symbol-macrolet
4322 (symbol-macrolet ((x (call-me-once)))
4323 (sinh x))
4325 "(function () {
4326 var x1 = callMeOnce();
4327 __PS_MV_REG = [];
4328 return (Math.exp(x1) - Math.exp(-x1)) / 2;
4329 })();")
4331 (test-ps-js maybe-once-only-symbol-macro
4332 (progn
4333 (define-symbol-macro maybe-once-only-symbol-macro (call-me-once))
4334 (tanh maybe-once-only-symbol-macro))
4336 "(function () {
4337 var x1 = callMeOnce();
4338 __PS_MV_REG = [];
4339 return (Math.exp(x1) - Math.exp(-x1)) / (Math.exp(x1) + Math.exp(-x1));
4340 })();")
4342 (test-ps-js maybe-once-only-evaluation-order
4343 (macrolet
4344 ((A (x y)
4345 (maybe-once-only (x y)
4346 `(+ ,x ,x ,y ,y))))
4347 (A (fun1) (fun2)))
4348 "(function () {
4349 var x1 = fun1();
4350 var y2 = fun2();
4351 __PS_MV_REG = [];
4352 return x1 + x1 + y2 + y2;
4353 })();")
4355 (test-ps-js maybe-once-only-macroexpansion
4356 (macrolet
4357 ((A (x y)
4358 (ps:maybe-once-only (x y)
4359 `(+ ,x ,x ,y ,y)))
4360 (fun1 () 'G)
4361 (fun2 () 6))
4362 (A (fun1) (fun2)))
4363 "G + G + 6 + 6;")
4365 (test-ps-js lambda-block-wrap-for-dynamic-return
4366 (lambda ()
4367 (block X
4368 ((lambda ()
4369 ((lambda ()
4370 (return-from X 1)))
4371 2)))
4373 "function () {
4374 X: {
4375 try {
4376 (function () {
4377 (function () {
4378 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4379 })();
4380 __PS_MV_REG = [];
4381 return 2;
4382 })();
4383 } catch (_ps_err1) {
4384 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4385 __PS_MV_REG = [];
4386 _ps_err1['__ps_value'];
4387 break X;
4388 } else {
4389 throw _ps_err1;
4393 __PS_MV_REG = [];
4394 return 5;
4395 };")
4397 (test-ps-js lambda-progn-block
4398 (lambda ()
4399 (progn
4400 (block X
4401 (lambda ()
4402 (return-from X 1)))))
4403 "function () {
4404 try {
4405 return function () {
4406 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4408 } catch (_ps_err1) {
4409 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4410 return _ps_err1['__ps_value'];
4411 } else {
4412 throw _ps_err1;
4415 };")
4417 (test-ps-js defun-when-if-return
4418 (defun foobar ()
4419 (when (bar)
4420 (loop if (foo) return 10)))
4421 "function foobar() {
4422 if (bar()) {
4423 while (true) {
4424 if (foo()) {
4425 __PS_MV_REG = [];
4426 return 10;
4430 };")
4432 (test-ps-js block-block-return-from-toplevel
4433 (block bar
4434 (block foo
4435 (return-from foo 10)))
4436 "(function () {
4437 return 10;
4438 })();")
4440 ;;; Stuff to fix. Not necessarily wrong, but redundant/could be better
4442 (test-ps-js block-dynamic-return1-redundant
4443 (defparameter foo
4444 ((lambda ()
4445 (block nil
4446 ((lambda () (return 6)))
4447 (+ 1 2))
4448 (+ 4 5))))
4449 ;;; FIXME. Not wrong, but redundant
4450 "var foo = (function () {
4451 nilBlock: {
4452 try {
4453 (function () {
4454 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
4455 })();
4456 1 + 2;
4457 } catch (_ps_err1) {
4458 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
4459 __PS_MV_REG = [];
4460 _ps_err1['__ps_value'];
4461 break nilBlock;
4462 } else {
4463 throw _ps_err1;
4467 __PS_MV_REG = [];
4468 return 4 + 5;
4469 })();")
4471 (test-ps-js block-gratuitous-dynamic-return
4472 (block foo
4473 (block bar
4474 (block nil
4475 (return-from bar 10)))
4476 (foo))
4477 "(function () {
4478 bar: {
4479 try {
4480 throw { '__ps_block_tag' : 'bar', '__ps_value' : 10 };
4481 } catch (_ps_err1) {
4482 if (_ps_err1 && 'bar' === _ps_err1['__ps_block_tag']) {
4483 _ps_err1['__ps_value'];
4484 break bar;
4485 } else {
4486 throw _ps_err1;
4490 __PS_MV_REG = [];
4491 return foo();
4492 })();")
4494 (test-ps-js for-loop-var-init-let
4495 (lambda (y)
4496 (ps:for
4497 ((x (let ((x0 (foo y)))
4498 (bar x0))))
4499 () ()
4500 (xyzzy x)))
4501 "function (y) {
4502 var x0;
4503 for (var x = (x0 = foo(y), bar(x0)); ; ) {
4504 xyzzy(x);
4506 };")