Added NEWS file with initial release timeline
[parenscript.git] / tests / output-tests.lisp
blob9f6589a740fe43d44f33881f454e60a12a3e0cbe
1 ;;;; -*- encoding:utf-8 -*-
3 ;;; Copyright 2005-2006 Henrik Hjelte
4 ;;; Copyright 2007-2012, 2018, 2020 Vladimir Sedach
5 ;;; Copyright 2019 Jason Miller
7 ;;; SPDX-License-Identifier: BSD-3-Clause
9 ;;; Redistribution and use in source and binary forms, with or
10 ;;; without modification, are permitted provided that the following
11 ;;; conditions are met:
13 ;;; 1. Redistributions of source code must retain the above copyright
14 ;;; notice, this list of conditions and the following disclaimer.
16 ;;; 2. Redistributions in binary form must reproduce the above
17 ;;; copyright notice, this list of conditions and the following
18 ;;; disclaimer in the documentation and/or other materials provided
19 ;;; with the distribution.
21 ;;; 3. Neither the name of the copyright holder nor the names of its
22 ;;; contributors may be used to endorse or promote products derived
23 ;;; from this software without specific prior written permission.
25 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
26 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
27 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
30 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
32 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
34 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 ;;; POSSIBILITY OF SUCH DAMAGE.
39 (in-package #:parenscript.tests)
40 (named-readtables:in-readtable :parenscript)
42 (fiveam:in-suite output-tests)
44 (test-ps-js statements-and-expressions-1
45 (+ i (if 1 2 3))
46 "i + (1 ? 2 : 3);")
48 (test-ps-js statements-and-expressions-2
49 (if 1 2 3)
50 "if (1) {
52 } else {
54 };")
56 (test-ps-js symbol-conversion-1
57 !?#@%
58 "bangwhathashatpercent;")
60 (test-ps-js symbol-conversion-2
61 bla-foo-bar
62 "blaFooBar;")
64 (test-ps-js symbol-conversion-3
65 *array
66 "Array;")
68 (test-ps-js symbol-conversion-4
69 *global-array*
70 "GLOBALARRAY;")
72 (test-ps-js symbol-conversion-5
73 encodeURIComponent
74 "encodeURIComponent;")
76 (test-ps-js symbol-conversion-6
77 URI
78 "URI;")
80 (test-ps-js number-literals-1
82 "1;")
84 (test-ps-js number-literals-2
85 123.123
86 "123.123;")
88 (test-ps-js number-literals-3
89 #x10
90 "16;")
92 (test-ps-js string-literals-1
93 "foobar"
94 "'foobar';")
96 (test-ps-js string-literals-2
97 "bratzel bub"
98 "'bratzel bub';")
100 (test-ps-js string-literals-3
102 "'\\t';")
104 (test-ps-js array-literals-1
105 (array)
106 "[];")
108 (test-ps-js array-literals-2
109 (array 1 2 3)
110 "[1, 2, 3];")
112 (test-ps-js array-literals-3
113 (array (array 2 3)
114 (array "foobar" "bratzel bub"))
115 "[[2, 3], ['foobar', 'bratzel bub']];")
117 (test-ps-js array-literals-4
118 (make-array)
119 "new Array();")
121 (test-ps-js array-literals-5
122 (make-array 1 2 3)
123 "new Array(1, 2, 3);")
125 (test-ps-js array-literals-6
126 (make-array
127 (make-array 2 3)
128 (make-array "foobar" "bratzel bub"))
129 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
131 (test-ps-js array-init-1
132 (make-array 2 :initial-contents '(10 20))
133 "(function () {
134 var arr1 = new Array(2);
135 var init2 = [10, 20];
136 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
137 arr1[i4] = init2[i4];
139 __PS_MV_REG = [];
140 return arr1;
141 })();")
143 (test-ps-js array-init-2
144 (make-array 5 :initial-element 10)
145 "(function () {
146 var arr1 = new Array(5);
147 var elt3 = 10;
148 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
149 arr1[i4] = elt3;
151 __PS_MV_REG = [];
152 return arr1;
153 })();")
155 (test-ps-js object-literals-1
156 (create foo "bar" :blorg 1)
157 "{ foo : 'bar', 'blorg' : 1 };")
159 (test-ps-js object-literals-2
160 (create foo "hihi"
161 blorg (array 1 2 3)
162 another-object (create :schtrunz 1))
163 "{ foo : 'hihi',
164 blorg : [1, 2, 3],
165 anotherObject : { 'schtrunz' : 1 } };")
167 (test-ps-js object-literals-3
168 (getprop an-object 'foo)
169 "anObject.foo;")
171 (test-ps-js object-literals-4
172 (@ an-object foo bar)
173 "anObject.foo.bar;")
175 (test-ps-js object-literals-5
176 (with-slots (a b c) this
177 (+ a b c))
178 "this.a + this.b + this.c;")
180 (test-ps-js with-slots-single-eval
181 (lambda () (with-slots (a b) (foo) (+ a b)))
182 "function () {
183 var object1 = foo();
184 __PS_MV_REG = [];
185 return object1.a + object1.b;
186 };")
188 (test-ps-js object-literal-quoted-symbols
189 (create 'test "bang" 'symbol-saved-my-life "parenscript")
190 "{ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' };")
192 (test-ps-js object-literal-property-accessors
193 (defun foo ()
194 (let ((x 10))
195 (create (get x) x
196 (set x v) (setf x v))))
197 "function foo() {
198 var x = 10;
199 return { get x() {
200 return x;
201 }, set x(v) {
202 return x = v;
203 } };
205 :js-target-version "1.8.5")
207 (test-ps-js object-method-apply-1
208 (apply (@ an-object foo) nil)
209 "anObject.foo.apply(anObject, null);")
211 (test-ps-js object-method-apply-2
212 (apply (getprop (make-an-object) foo 'bar) nil)
213 "(function () {
214 var _js1 = makeAnObject()[foo];
215 var _js2 = _js1.bar;
216 __PS_MV_REG = [];
217 return _js2.apply(_js1, null);
218 })();")
220 (test-ps-js object-method-apply-3
221 (apply (@ (make-an-object) foo) (bar))
222 "(function () {
223 var _js1 = makeAnObject();
224 var _js2 = _js1.foo;
225 __PS_MV_REG = [];
226 return _js2.apply(_js1, bar());
227 })();")
229 (test-ps-js regular-expression-literals-1
230 (regex "foobar")
231 "/foobar/;")
233 (test-ps-js regular-expression-literals-2
234 (regex "/foobar/i")
235 "/foobar/i;")
237 (test-ps-js literal-symbols-1
239 "true;")
241 (test-ps-js literal-symbols-2
242 false
243 "false;")
245 (test-ps-js literal-symbols-3
247 "false;")
249 (test-ps-js literal-symbols-4
250 (lambda () nil)
251 "function () {
252 return null;
253 };")
255 (test-ps-js literal-symbols-5
256 undefined
257 "undefined;")
259 (test-ps-js literal-symbols-6
260 this
261 "this;")
263 (test-ps-js variables-1
264 variable
265 "variable;")
267 (test-ps-js variables-2
268 a-variable
269 "aVariable;")
271 (test-ps-js variables-3
272 *math
273 "Math;")
275 (test-ps-js function-calls-and-method-calls-1
276 (blorg 1 2)
277 "blorg(1, 2);")
279 (test-ps-js function-calls-and-method-calls-2
280 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
281 "foobar(blorg(1, 2), blabla(3, 4), [2, 3, 4]);")
283 (test-ps-js function-calls-and-method-calls-3
284 ((getprop this 'blorg) 1 2)
285 "this.blorg(1, 2);")
287 (test-ps-js function-calls-and-method-calls-4
288 ((aref foo i) 1 2)
289 "foo[i](1, 2);")
291 (test-ps-js function-calls-and-method-calls-5
292 ((getprop (aref foobar 1) 'blorg) nil t)
293 "foobar[1].blorg(null, true);")
295 (test-ps-js operator-expressions-1
296 (* 1 2)
297 "1 * 2;")
299 (test-ps-js operator-expressions-2
300 (= 1 2)
301 "1 === 2;")
303 (test-ps-js operator-expressions-3
304 (* 1 (+ 2 3 4) 4 (/ 6 7))
305 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
307 (test-ps-js operator-expressions-4
308 (incf i)
309 "++i;")
311 (test-ps-js operator-expressions-5
312 (decf i)
313 "--i;")
315 (test-ps-js operator-expressions-6
316 (1- i)
317 "i - 1;")
319 (test-ps-js operator-expressions-7
320 (1+ i)
321 "i + 1;")
323 (test-ps-js operator-expressions-8
324 (not (< i 2))
325 "i >= 2;")
327 (test-ps-js body-forms-1
328 (progn (blorg i) (blafoo i))
329 "blorg(i);
330 blafoo(i);")
332 (test-ps-js body-forms-2
333 (+ i (progn (blorg i) (blafoo i)))
334 "i + (blorg(i), blafoo(i));")
336 (test-ps-js function-definition-1
337 (defun a-function (a b)
338 (+ a b))
339 "function aFunction(a, b) {
340 return a + b;
341 };")
343 (test-ps-js lambda-definition-2
344 (lambda (a b) (+ a b))
345 "function (a, b) {
346 return a + b;
347 };")
349 (test-ps-js assignment-1
350 (setf a 1)
351 "a = 1;")
353 (test-ps-js assignment-2
354 (setf a 2 b 3 c 4 x (+ a b c))
355 "a = 2;
356 b = 3;
357 c = 4;
358 x = a + b + c;")
360 (test-ps-js assignment-3
361 (setf a (+ a 2 3 4 a))
362 "a = a + 2 + 3 + 4 + a;")
364 (test-ps-js assignment-4
365 (setf a (- 1 a))
366 "a = 1 - a;")
368 (test-ps-js assignment-5
369 (let ((a 1) (b 2))
370 (psetf a b b a))
371 "(function () {
372 var a = 1;
373 var b = 2;
374 var _js3 = b;
375 var _js4 = a;
376 a = _js3;
377 return b = _js4;
378 })();")
380 (test-ps-js assignment-6
381 (setq a 1)
382 "a = 1;")
384 (test-ps-js assignment-8
385 (progn
386 (defun (setf color) (new-color el)
387 (setf (getprop (getprop el 'style) 'color) new-color))
388 (setf (color some-div) (+ 23 "em")))
389 "function __setf_color(newColor, el) {
390 return el.style.color = newColor;
392 __setf_color(23 + 'em', someDiv);")
394 (test-ps-js assignment-10
395 (progn
396 (defsetf left (el) (offset)
397 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
398 (setf (left some-div) (+ 123 "px")))
399 "(function () {
400 var _js2 = someDiv;
401 var _js1 = 123 + 'px';
402 return _js2.style.left = _js1;
403 })();")
405 (test-ps-js assignment-12
406 (macrolet ((left (el)
407 `(getprop ,el 'offset-left)))
408 (left some-div))
409 "someDiv.offsetLeft;")
411 (test-ps-js nil-block-return-1
412 (block nil (return) 1)
413 "(function () {
414 return null;
415 return 1;
416 })();")
418 (test-ps-js single-argument-statements-2
419 (throw "foobar")
420 "throw 'foobar';")
422 (test-ps-js single-argument-expression-1
423 (delete (new (*foobar 2 3 4)))
424 "delete new Foobar(2, 3, 4);")
426 (test-ps-js single-argument-expression-2
427 (if (= (typeof blorg) *string)
428 (alert (+ "blorg is a string: " blorg))
429 (alert "blorg is not a string"))
430 "if (typeof blorg === String) {
431 alert('blorg is a string: ' + blorg);
432 } else {
433 alert('blorg is not a string');
434 };")
436 (test-ps-js conditional-statements-1
437 (defun foo ()
438 (if ((@ blorg is-correct))
439 (progn (carry-on) (return-from foo i))
440 (alert "blorg is not correct!")))
441 "function foo() {
442 if (blorg.isCorrect()) {
443 carryOn();
444 __PS_MV_REG = [];
445 return i;
446 } else {
447 __PS_MV_REG = [];
448 return alert('blorg is not correct!');
450 };")
452 (test-ps-js conditional-statements-2
453 (+ i (if ((@ blorg add-one)) 1 2))
454 "i + (blorg.addOne() ? 1 : 2);")
456 (test-ps-js conditional-statements-3
457 (defun foo ()
458 (when ((@ blorg is-correct))
459 (carry-on)
460 (return-from foo i)))
461 "function foo() {
462 if (blorg.isCorrect()) {
463 carryOn();
464 __PS_MV_REG = [];
465 return i;
467 };")
469 (test-ps-js conditional-statements-4
470 (unless ((@ blorg is-correct))
471 (alert "blorg is not correct!"))
472 "if (!blorg.isCorrect()) {
473 alert('blorg is not correct!');
474 };")
476 (test-ps-js variable-declaration-1
477 (defvar *a* (array 1 2 3))
478 "if ('undefined' === typeof A) { var A = [1, 2, 3]; };")
480 (test-ps-js variable-declaration-2
481 (progn (defvar *a* 4)
482 (let ((x 1)
483 (*a* 2))
484 (let* ((y (+ x 1))
485 (x (+ x y)))
486 (+ *a* x y))))
487 "if ('undefined' === typeof A) { var A = 4; };
488 (function () {
489 var x = 1;
490 var A_TMPSTACK1;
491 try {
492 A_TMPSTACK1 = A;
493 A = 2;
494 var y = x + 1;
495 var x2 = x + y;
496 return A + x2 + y;
497 } finally {
498 A = A_TMPSTACK1;
500 })();")
502 (test-ps-js variable-declaration-3
503 (defparameter A 987)
504 "var A = 987;")
506 (test-ps-js variable-declaration-4
507 (progn (defparameter *a* 4)
508 (let ((x 1)
509 (*a* 2))
510 (let* ((y (+ x 1))
511 (x (+ x y)))
512 (+ *a* x y))))
513 "var A = 4;
514 (function () {
515 var x = 1;
516 var A_TMPSTACK1;
517 try {
518 A_TMPSTACK1 = A;
519 A = 2;
520 var y = x + 1;
521 var x2 = x + y;
522 return A + x2 + y;
523 } finally {
524 A = A_TMPSTACK1;
526 })();")
528 (test-ps-js variable-declaration-5
529 (defvar BAZ)
530 "var BAZ;")
532 (test-ps-js iteration-constructs-1
533 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
534 (d 0 (1+ d))
535 (e (aref c d) (aref c d)))
536 ((or (= d (@ c length)) (string= e "x")))
537 (setf a d b e)
538 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
539 "(function () {
540 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
541 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
542 a = d;
543 b = e;
544 document.write('a: ' + a + ' b: ' + b + '<br/>');
546 })();")
548 (test-ps-js iteration-constructs-2
549 (do ((i 0 (1+ i))
550 (s 0 (+ s i (1+ i))))
551 ((> i 10))
552 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
553 "(function () {
554 var i = 0;
555 var s = 0;
556 for (; i <= 10; ) {
557 document.write('i: ' + i + ' s: ' + s + '<br/>');
558 var _js1 = i + 1;
559 var _js2 = s + i + (i + 1);
560 i = _js1;
561 s = _js2;
563 })();")
565 (test-ps-js iteration-constructs-3
566 (do* ((i 0 (1+ i))
567 (s 0 (+ s i (1- i))))
568 ((> i 10))
569 ((@ document write) (+ "i: " i " s: " s "<br/>")))
570 "(function () {
571 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
572 document.write('i: ' + i + ' s: ' + s + '<br/>');
574 })();")
576 (test-ps-js iteration-constructs-4
577 (let ((arr (array "a" "b" "c" "d" "e")))
578 (dotimes (i (@ arr length))
579 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
580 "(function () {
581 var arr = ['a', 'b', 'c', 'd', 'e'];
582 for (var i = 0; i < arr.length; i += 1) {
583 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
585 })();")
587 (test-ps-js iteration-constructs-5
588 (let ((res 0))
589 (alert (+ "Summation to 10 is "
590 (dotimes (i 10 res)
591 (incf res (1+ i))))))
592 "(function () {
593 var res = 0;
594 __PS_MV_REG = [];
595 return alert('Summation to 10 is ' + (function () {
596 for (var i = 0; i < 10; i += 1) {
597 res += i + 1;
599 var i = null;
600 return res;
601 })());
602 })();")
604 (test-ps-js iteration-constructs-6
605 (let ((l (list 1 2 4 8 16 32)))
606 (dolist (c l)
607 ((@ document write) (+ "c: " c "<br/>"))))
608 "(function () {
609 var l = [1, 2, 4, 8, 16, 32];
610 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
611 c = l[_js_idx2];
612 document.write('c: ' + c + '<br/>');
614 })();")
616 (test-ps-js iteration-constructs-7
617 (let ((l '(1 2 4 8 16 32))
618 (s 0))
619 (alert (+ "Sum of " l " is: "
620 (dolist (c l s)
621 (incf s c)))))
622 "(function () {
623 var l = [1, 2, 4, 8, 16, 32];
624 var s = 0;
625 __PS_MV_REG = [];
626 return alert('Sum of ' + l + ' is: ' + (function () {
627 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
628 c = l[_js_idx1];
629 s += c;
631 var c = null;
632 return s;
633 })());
634 })();")
636 (test-ps-js iteration-constructs-8
637 (let ((obj (create a 1 b 2 c 3)))
638 (for-in (i obj)
639 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
640 "(function () {
641 var obj = { a : 1, b : 2, c : 3 };
642 for (var i in obj) {
643 document.write(i + ': ' + obj[i] + '<br/>');
645 })();")
647 (test-ps-js iteration-constructs-9
648 (loop while (funcall (@ film is-not-finished)) do
649 (funcall (@ this eat) (new *popcorn)))
650 "(function () {
651 while (film.isNotFinished()) {
652 this.eat(new Popcorn);
654 }).call(this);")
656 (test-ps-js iteration-constructs-10
657 (loop for i from 1 while (foo))
658 "(function () {
659 for (var i = 1; foo(); i += 1) {
661 })();")
663 (test-ps-js iteration-constructs-11
664 (loop for i from 1)
665 "(function () {
666 for (var i = 1; true; i += 1) {
668 })();")
670 (test-ps-js loop-for-bindings
671 (loop :for ((a b) (:c :d)) :in arr :do (foo a b c d))
672 "(function () {
673 var _js2 = arr.length;
674 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
675 var _db4 = arr[_js1];
676 var _db5 = _db4[0];
677 var a = _db5[0];
678 var b = _db5[1];
679 var _js3 = _db4[1];
680 var c = _js3['c'];
681 var d = _js3['d'];
682 foo(a, b, c, d);
684 })();")
686 (test-ps-js loop-for-on
687 (loop :for (k v) :on plist :by 2 :do (foo k v))
688 "(function () {
689 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
690 var k = _js1[0];
691 var v = _js1[1];
692 foo(k, v);
694 })();")
696 (test-ps-js loop-for-keys-of
697 (loop :for k :of obj :do (foo k))
698 "(function () {
699 for (var k in obj) {
700 foo(k);
702 })();")
704 (test-ps-js loop-for-key-val-pairs-of
705 (loop :for (k v) :of obj :do (foo k v))
706 "(function () {
707 for (var k in obj) {
708 var v = obj[k];
709 foo(k, v);
711 })();")
713 (test-ps-js loop-for-key-val-pairs-of-with-bindings
714 (loop :for (k (a b)) :of obj :do (foo k a b))
715 "(function () {
716 for (var k in obj) {
717 var _db1 = obj[k];
718 var a = _db1[0];
719 var b = _db1[1];
720 foo(k, a, b);
722 })();")
724 (test-ps-js loop-for-just-vals-of
725 (loop :for (nil v) :of obj :do (foo k v))
726 "(function () {
727 for (var _js1 in obj) {
728 var v = obj[_js1];
729 foo(k, v);
731 })();")
733 (test-ps-js loop-map-to
734 (loop :for str :in strs :map str :to (length str))
735 "(function () {
736 var _js2 = strs.length;
737 var map3 = { };
738 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
739 var str = strs[_js1];
740 map3[str] = str.length;
742 return map3;
743 })();")
745 (test-ps-js loop-for-of-map-to
746 (loop :for k :of obj :map k :to (foo k))
747 "(function () {
748 var map1 = { };
749 for (var k in obj) {
750 map1[k] = foo(k);
752 __PS_MV_REG = [];
753 return map1;
754 })();")
756 (test-ps-js loop-for-of-when
757 (loop :for k :of obj :when (foo k) :map k :to (bar k))
758 "(function () {
759 var map1 = { };
760 for (var k in obj) {
761 if (foo(k)) {
762 map1[k] = bar(k);
765 __PS_MV_REG = [];
766 return map1;
767 })();")
769 (test-ps-js loop-for-in-until-when
770 (loop :for a :in b :until (> a 100) :when (< a 50) :do (foo a))
771 "(function () {
772 var _js2 = b.length;
773 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
774 var a = b[_js1];
775 if (a > 100) {
776 break;
778 if (a < 50) {
779 foo(a);
782 })();")
784 (test-ps-js loop-with-for-when
785 (loop :with c = c1 :for d :from c1 :below c2
786 :when (foo c d) :do (setf c d)
787 :do (bar d))
788 "(function () {
789 var c = c1;
790 for (var d = c1; d < c2; d += 1) {
791 if (foo(c, d)) {
792 c = d;
794 bar(d);
796 })();")
798 (test-ps-js loop-for-then-for-in-while
799 (defun blah (c)
800 (loop :for a = (foo) :then (bar) :for b :in c :while b :do (foo a b c)))
801 "function blah(c) {
802 var _js2 = c.length;
803 var FIRST3 = true;
804 for (var a = foo(); true; a = bar()) {
805 var _js1 = FIRST3 ? 0 : _js1 + 1;
806 if (_js1 >= _js2) {
807 break;
809 var b = c[_js1];
810 if (!b) {
811 break;
813 foo(a, b, c);
814 FIRST3 = null;
816 };")
818 (test-ps-js loop-while-when
819 (loop :for a = (pop stack) :while a :for (b c) = (foo a) :when b :do (bar c))
820 "(function () {
821 for (var a = pop(stack); a; a = pop(stack)) {
822 var _db1 = foo(a);
823 var b = _db1[0];
824 var c = _db1[1];
825 if (b) {
826 bar(c);
829 })();")
831 (test-ps-js loop-for-of-for-in
832 (defun blah (obj b)
833 (loop :for k :of obj :for a :in b :do (foo k a)))
834 "function blah(obj, b) {
835 var _js2 = b.length;
836 var FIRST3 = true;
837 for (var k in obj) {
838 var _js1 = FIRST3 ? 0 : _js1 + 1;
839 if (_js1 >= _js2) {
840 break;
842 var a = b[_js1];
843 foo(k, a);
844 FIRST3 = null;
846 };")
848 (test-ps-js loop-for-dot
849 (loop :for (op . args) :in expr :do (foo op args))
850 "(function () {
851 var _js2 = expr.length;
852 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
853 var _db3 = expr[_js1];
854 var op = _db3[0];
855 var args = _db3.length > 1 ? _db3.slice(1) : [];
856 foo(op, args);
858 })();")
860 (test-ps-js loop-for-rest
861 (loop :for (op &rest args) :in expr :do (foo op args))
862 "(function () {
863 var _js2 = expr.length;
864 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
865 var _db3 = expr[_js1];
866 var op = _db3[0];
867 var args = _db3.length > 1 ? _db3.slice(1) : [];
868 foo(op, args);
870 })();")
872 (test-ps-js loop-collect
873 (setf x (loop :for a :in b :collect (foo a)))
874 "x = (function () {
875 var _js2 = b.length;
876 var collect3 = [];
877 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
878 var a = b[_js1];
879 collect3.push(foo(a));
881 __PS_MV_REG = [];
882 return collect3;
883 })();")
885 (test-ps-js loop-collect-twice
886 (loop collect x collect (1+ x))
887 "(function () {
888 var collect1 = [];
889 while (true) {
890 collect1.push(x);
891 collect1.push(x + 1);
893 __PS_MV_REG = [];
894 return collect1;
895 })();")
897 (test-ps-js loop-append
898 (loop :for a :in b :append a)
899 "(function () {
900 var _js2 = b.length;
901 var append3 = [];
902 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
903 var a = b[_js1];
904 append3 = append3.concat(a);
906 __PS_MV_REG = [];
907 return append3;
908 })();")
910 (test-ps-js the-case-statement-1
911 (case (aref blorg i)
912 ((1 "one") (alert "one"))
913 (2 (alert "two"))
914 (t (alert "default clause")))
915 "switch (blorg[i]) {
916 case 1:
917 case 'one':
918 alert('one');
919 break;
920 case 2:
921 alert('two');
922 break;
923 default:
924 alert('default clause');
925 };")
927 (test-ps-js the-case-statement-2
928 (switch (aref blorg i)
929 (1 (alert "If I get here"))
930 (2 (alert "I also get here"))
931 (default (alert "I always get here")))
932 "switch (blorg[i]) {
933 case 1: alert('If I get here');
934 case 2: alert('I also get here');
935 default: alert('I always get here');
936 };")
938 (test-ps-js the-try-statement-1
939 (try (throw "i")
940 (:catch (error)
941 (alert (+ "an error happened: " error)))
942 (:finally
943 (alert "Leaving the try form")))
944 "try {
945 throw 'i';
946 } catch (error) {
947 alert('an error happened: ' + error);
948 } finally {
949 alert('Leaving the try form');
950 };")
952 (test-ps-js the-html-generator-1
953 (ps-html ((:a :href "foobar") "blorg"))
954 "'<a href=\\\"foobar\\\">blorg</a>';")
956 (test-ps-js the-html-generator-2
957 (ps-html ((:a :href (generate-a-link)) "blorg"))
958 "['<a href=\\\"', generateALink(), '\\\">blorg</a>'].join('');")
960 (test-ps-js the-html-generator-3
961 (funcall (getprop document 'write)
962 (ps-html ((:a :href "#"
963 :onclick (ps-inline (transport))) "link")))
964 "document.write(['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">link</a>'].join(''));")
966 (test-ps-js the-html-generator-4
967 (let ((disabled nil)
968 (authorized t))
969 (setf (getprop element 'inner-h-t-m-l)
970 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
971 "Edit me"))))
972 "(function () {
973 var disabled = null;
974 var authorized = true;
975 return element.innerHTML = ['<textarea', disabled || !authorized ? [' disabled=\\\"', 'disabled', '\\\"'].join('') : '', '>Edit me</textarea>'].join('');
976 })();")
978 (test-ps-js plus-is-not-commutative
979 (setf x (+ "before" x "after"))
980 "x = 'before' + x + 'after';")
982 (test-ps-js plus-works-if-first
983 (setf x (+ x "middle" "after"))
984 "x = x + 'middle' + 'after';")
986 (test-ps-js method-call-op-form
987 (funcall (getprop (+ "" x) 'to-string))
988 "('' + x).toString();")
990 (test-ps-js method-call-op-form-args
991 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
992 "('' + x).foo(1, 2, 'baz', 3);")
994 (test-ps-js method-call-string
995 ((getprop "hi" 'to-string))
996 "'hi'.toString();")
998 (test-ps-js method-call-conditional
999 ((if a x y) 1)
1000 "(a ? x : y)(1);")
1002 (test-ps-js method-call-variable
1003 ((@ x to-string))
1004 "x.toString();")
1006 (test-ps-js method-call-array
1007 ((@ (list 10 20) to-string))
1008 "[10, 20].toString();")
1010 (test-ps-js method-call-lambda-call
1011 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
1012 "(function (x) { return x; })(10).toString();")
1014 (fiveam:test no-whitespace-before-dot
1015 (let ((str (ps* '((@ ((lambda (x) x) 10) to-string)))))
1016 (fiveam:is (char= #\) (elt str (1- (position #\. str)))))))
1018 (test-ps-js simple-getprop
1019 (let ((foo (create a 1)))
1020 (alert (getprop foo 'a)))
1021 "(function () {
1022 var foo = { a : 1 };
1023 __PS_MV_REG = [];
1024 return alert(foo.a);
1025 })();")
1027 (test-ps-js buggy-getprop
1028 (getprop foo slot-name)
1029 "foo[slotName];")
1031 (test-ps-js buggy-getprop-two
1032 (getprop foo (get-slot-name))
1033 "foo[getSlotName()];")
1035 (test-ps-js old-case-is-now-switch
1036 ;; Switch was "case" before, but that was very non-lispish.
1037 ;; For example, this code makes three messages and not one
1038 ;; which may have been expected. This is because a switch
1039 ;; statment must have a break statement for it to return
1040 ;; after the alert. Otherwise it continues on the next
1041 ;; clause.
1042 (switch (aref blorg i)
1043 (1 (alert "one"))
1044 (2 (alert "two"))
1045 (default (alert "default clause")))
1046 "switch (blorg[i]) {
1047 case 1: alert('one');
1048 case 2: alert('two');
1049 default: alert('default clause');
1050 };")
1052 (test-ps-js lisp-like-case
1053 (case (aref blorg i)
1054 (1 (alert "one"))
1055 (2 (alert "two"))
1056 (t (alert "default clause")))
1057 "switch (blorg[i]) {
1058 case 1:
1059 alert('one');
1060 break;
1061 case 2:
1062 alert('two');
1063 break;
1064 default: alert('default clause');
1065 };")
1068 (test-ps-js even-lispier-case
1069 (case (aref blorg i)
1070 ((1 2) (alert "Below three"))
1071 (3 (alert "Three"))
1072 (t (alert "Something else")))
1073 "switch (blorg[i]) {
1074 case 1:
1075 case 2:
1076 alert('Below three');
1077 break;
1078 case 3:
1079 alert('Three');
1080 break;
1081 default: alert('Something else');
1082 };")
1084 (test-ps-js otherwise-case
1085 (case (aref blorg i)
1086 (1 (alert "one"))
1087 (otherwise (alert "default clause")))
1088 "switch (blorg[i]) {
1089 case 1:
1090 alert('one');
1091 break;
1092 default: alert('default clause');
1093 };")
1095 (fiveam:test escape-sequences-in-string
1096 (let ((escapes
1097 `((#\\ . #\\)
1098 (#\b . #\Backspace)
1099 (#\f . ,(code-char 12))
1100 ("u000B" . ,(code-char #xB)) ; vertical tab
1101 (#\n . #\Newline)
1102 (#\r . #\Return)
1103 (#\' . #\')
1104 (#\" . #\")
1105 (#\t . #\Tab)
1106 ("u001F" . ,(code-char #x1F)) ; character below 32
1107 ("u0080" . ,(code-char 128)) ; character over 127
1108 ("u00A0" . ,(code-char 160)) ; non-breaking space
1109 ("u00AD" . ,(code-char 173)) ; soft hyphen
1110 ("u200B" . ,(code-char #x200B)) ; zero-width space
1111 ("u200C" . ,(code-char #x200C)) ; zero-width non-joiner
1113 (loop for (js-escape . lisp-char) in escapes
1114 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
1115 for wanted = (format nil "'hello\\~ahi';" js-escape)
1116 do (fiveam:is (string= generated wanted)))))
1118 (fiveam:test escape-doublequotes
1119 (let ((*js-string-delimiter* #\"))
1120 (fiveam:is (string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1122 (test-ps-js getprop-setf
1123 (setf (getprop x 'y) (+ (+ a 3) 4))
1124 "x.y = (a + 3) + 4;")
1126 (test-ps-js getprop-conditional1
1127 (getprop (if zoo foo bar) 'x)
1128 "(zoo ? foo : bar).x;")
1130 (test-ps-js getprop-conditional2
1131 (getprop (if (not zoo) foo bar) 'x)
1132 "(!zoo ? foo : bar).x;")
1134 (fiveam:test script-star-eval1
1135 (fiveam:is (string=
1136 (normalize-js-output (ps* '(setf x 1) '(setf y 2)))
1137 "x = 1; y = 2;")))
1139 (fiveam:test script-star-eval2
1140 (fiveam:is (string=
1141 (normalize-js-output (ps* '(setf x 1)))
1142 "x = 1;")))
1144 (test-ps-js list-with-single-nil
1145 (array nil)
1146 "[null];")
1148 (test-ps-js quoted-nil-is-array
1149 'nil
1150 "[];")
1152 (test-ps-js quoted-nil-is-array1
1154 "[];")
1156 (test-ps-js literal-nil
1157 (foo ())
1158 "foo(null);")
1160 (test-ps-js quoted-quoted-nil
1161 '(())
1162 "[null];")
1164 (test-ps-js quoted-quoted-nil1
1165 '(1 ())
1166 "[1, null];")
1168 (test-ps-js defsetf1
1169 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1170 (setf (baz 1 2) 3))
1171 "(function () {
1172 var _js2 = 1;
1173 var _js3 = 2;
1174 var _js1 = 3;
1175 __PS_MV_REG = [];
1176 return setBaz(_js2, _js3, _js1);
1177 })();")
1179 (test-ps-js setf-macroexpands1
1180 (macrolet ((bar (x y)
1181 `(aref ,x ,y 1)))
1182 (setf (bar foo 2) 3))
1183 "foo[2][1] = 3;")
1185 (test-ps-js defsetf-short
1186 (progn (defsetf baz set-baz "docstring")
1187 (setf (baz 1 2 3) "foo"))
1188 "setBaz(1, 2, 3, 'foo');")
1190 (test-ps-js defun-setf1
1191 (progn (defun (setf some-thing) (new-val i1 i2)
1192 (setf (aref *some-thing* i1 i2) new-val))
1193 (setf (some-thing 1 2) "foo"))
1194 "function __setf_someThing(newVal, i1, i2) {
1195 return SOMETHING[i1][i2] = newVal;
1197 __setf_someThing('foo', 1, 2);")
1199 (test-ps-js defun-optional1
1200 (defun test-opt (&optional x)
1201 (if x "yes" "no"))
1202 "function testOpt(x) {
1203 return x ? 'yes' : 'no';
1204 };")
1206 (test-ps-js defun-optional2
1207 (defun foo (x &optional y)
1208 (+ x y))
1209 "function foo(x, y) {
1210 return x + y;
1211 };")
1213 (test-ps-js defun-optional3
1214 (defun blah (&optional (x 0))
1216 "function blah(x) {
1217 if (x === undefined) {
1218 x = 0;
1220 return x;
1221 };")
1223 (test-ps-js arglist-optional4
1224 (lambda (&optional (x 0 supplied?))
1226 "function (x) {
1227 var suppliedwhat = x !== undefined;
1228 if (!suppliedwhat) {
1229 x = 0;
1231 return x;
1232 };")
1234 (test-ps-js return-nothing
1235 (defun foo () (return-from foo))
1236 "function foo() {
1237 return;
1238 };")
1240 (test-ps-js return-values
1241 (defun foo ()
1242 (return-from foo (values 1 2 3)))
1243 "function foo() {
1244 var val1 = 1;
1245 __PS_MV_REG = [2, 3];
1246 return val1;
1247 };")
1249 (test-ps-js set-timeout
1250 (set-timeout (lambda () (alert "foo")) 10)
1251 "setTimeout(function () { __PS_MV_REG = []; return alert('foo'); }, 10);")
1253 (test-ps-js operator-precedence
1254 (* 3 (+ 4 5) 6)
1255 "3 * (4 + 5) * 6;")
1257 (test-ps-js operators-1
1258 (in prop obj)
1259 "prop in obj;")
1261 (test-ps-js incf1
1262 (incf foo bar)
1263 "foo += bar;")
1265 (test-ps-js decf1
1266 (decf foo bar)
1267 "foo -= bar;")
1269 (test-ps-js incf2
1270 (incf x 5)
1271 "x += 5;")
1273 (test-ps-js decf2
1274 (decf y 10)
1275 "y -= 10;")
1277 (test-ps-js setf-conditional
1278 (setf foo (if x 1 2))
1279 "foo = x ? 1 : 2;")
1281 (test-ps-js obj-literal-numbers
1282 (create 1 "foo")
1283 "{ 1 : 'foo' };")
1285 (test-ps-js obj-literal-strings
1286 (create "foo" 2)
1287 "{ 'foo' : 2 };")
1289 (test-ps-js getprop-string
1290 (getprop foo "bar")
1291 "foo['bar'];")
1293 (test-ps-js getprop-string1
1294 (getprop "bar" 'length)
1295 "'bar'.length;")
1297 (test-ps-js getprop-progn
1298 (getprop (progn (some-fun "abc") "123") "length")
1299 "(someFun('abc'), '123')['length'];")
1301 (test-ps-js getprop-multi1
1302 (getprop foo 1 "two" three 'bar 1 2)
1303 "foo[1]['two'][three].bar[1][2];")
1305 (test-ps-js method-call-block
1306 ((@ (progn (some-fun "abc") "123") to-string))
1307 "(someFun('abc'), '123').toString();")
1309 (test-ps-js create-blank
1310 (create)
1311 "{ };")
1313 (test-ps-js blank-object-literal
1315 "{ };")
1317 (test-ps-js array-literal1
1319 "[];")
1321 (test-ps-js array-literal2
1322 ([])
1323 "[];")
1325 (test-ps-js array-literal3
1326 ([] 1 2 3)
1327 "[1, 2, 3];")
1329 (test-ps-js array-literal4
1330 ([] 1 (2 3))
1331 "[1, [2, 3]];")
1333 (test-ps-js array-literal5
1334 ([] (1 2) ("a" "b"))
1335 "[[1, 2], ['a', 'b']];")
1337 (test-ps-js defun-rest1
1338 (defun foo (&rest bar)
1339 (alert (aref bar 1)))
1340 "function foo() {
1341 var bar = Array.prototype.slice.call(arguments, 0);
1342 __PS_MV_REG = [];
1343 return alert(bar[1]);
1344 };")
1346 (test-ps-js defun-rest2
1347 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1348 "function foo(baz) {
1349 var bar = Array.prototype.slice.call(arguments, 1);
1350 __PS_MV_REG = [];
1351 return baz + bar[1];
1352 };")
1354 (test-ps-js defun-keyword1
1355 (defun zoo (foo bar &key baz) (+ foo bar baz))
1356 "function zoo(foo, bar) {
1357 var _js2 = arguments.length;
1358 for (var n1 = 2; n1 < _js2; n1 += 2) {
1359 switch (arguments[n1]) {
1360 case 'baz':
1361 baz = arguments[n1 + 1];
1364 var baz;
1365 return foo + bar + baz;
1366 };")
1368 (test-ps-js defun-keyword2
1369 (defun zoo (&key baz) (* baz baz))
1370 "function zoo() {
1371 var _js2 = arguments.length;
1372 for (var n1 = 0; n1 < _js2; n1 += 2) {
1373 switch (arguments[n1]) {
1374 case 'baz':
1375 baz = arguments[n1 + 1];
1378 var baz;
1379 return baz * baz;
1380 };")
1382 (test-ps-js defun-keyword3
1383 (defun zoo (&key baz (bar 4)) (* baz bar))
1384 "function zoo() {
1385 var _js2 = arguments.length;
1386 for (var n1 = 0; n1 < _js2; n1 += 2) {
1387 switch (arguments[n1]) {
1388 case 'baz':
1389 baz = arguments[n1 + 1];
1390 break;
1391 case 'bar':
1392 bar = arguments[n1 + 1];
1395 var baz;
1396 var bar = 'undefined' === typeof bar ? 4 : bar;
1397 return baz * bar;
1398 };")
1400 (test-ps-js defun-keyword4
1401 (defun hello-world (&key ((:my-name-key my-name) 1))
1402 my-name)
1403 "function helloWorld() {
1404 var _js2 = arguments.length;
1405 for (var n1 = 0; n1 < _js2; n1 += 2) {
1406 switch (arguments[n1]) {
1407 case 'my-name-key':
1408 myName = arguments[n1 + 1];
1411 var myName = 'undefined' === typeof myName ? 1 : myName;
1412 return myName;
1413 };")
1415 (test-ps-js arglist-keyword-supplied
1416 (lambda (&key (foo 1 supplied?))
1417 foo)
1418 "function () {
1419 var _js2 = arguments.length;
1420 for (var n1 = 0; n1 < _js2; n1 += 2) {
1421 switch (arguments[n1]) {
1422 case 'foo':
1423 foo = arguments[n1 + 1];
1424 suppliedwhat = true;
1427 var suppliedwhat;
1428 var foo = 'undefined' === typeof foo ? 1 : foo;
1429 return foo;
1430 };")
1432 (test-ps-js keyword-funcall1
1433 (func :baz 1)
1434 "func('baz', 1);")
1436 (test-ps-js keyword-funcall2
1437 (func :baz 1 :bar foo)
1438 "func('baz', 1, 'bar', foo);")
1440 (test-ps-js keyword-funcall3
1441 (fun a b :baz c)
1442 "fun(a, b, 'baz', c);")
1444 (test-ps-js cond1
1445 (cond ((= x 1) 1))
1446 "if (x === 1) {
1448 };")
1450 (test-ps-js cond2
1451 (cond ((= x 1) 2)
1452 ((= y (* x 4)) (foo "blah") (* x y)))
1453 "if (x === 1) {
1455 } else if (y === x * 4) {
1456 foo('blah');
1457 x * y;
1458 };")
1460 (test-ps-js if-exp-without-else-return
1461 (defun foo () (return-from foo (if x 1)))
1462 "function foo() {
1463 return x ? 1 : null;
1464 };")
1466 (test-ps-js progn-expression-single-statement
1467 (defun foo () (return-from foo (progn (* x y))))
1468 "function foo() {
1469 return x * y;
1470 };")
1472 (test-ps-js cond-expression1
1473 (defun foo ()
1474 (cond ((< 1 2) (bar "foo") (* 4 5))))
1475 "function foo() {
1476 if (1 < 2) {
1477 bar('foo');
1478 __PS_MV_REG = [];
1479 return 4 * 5;
1481 };")
1483 (test-ps-js cond-expression2
1484 (defun foo ()
1485 (cond ((< 2 1) "foo")
1486 ((= 7 7) "bar")))
1487 "function foo() {
1488 if (2 < 1) {
1489 return 'foo';
1490 } else if (7 === 7) {
1491 return 'bar';
1493 };")
1495 (test-ps-js cond-expression-final-t-clause
1496 (defun foo ()
1497 (cond ((< 1 2) (bar "foo") (* 4 5))
1498 ((= a b) (+ c d))
1499 ((< 1 2 3 4 5) x)
1500 (t "foo")))
1501 "function foo() {
1502 var _cmp1;
1503 var _cmp2;
1504 var _cmp3;
1505 if (1 < 2) {
1506 bar('foo');
1507 __PS_MV_REG = [];
1508 return 4 * 5;
1509 } else if (a === b) {
1510 __PS_MV_REG = [];
1511 return c + d;
1512 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1513 __PS_MV_REG = [];
1514 return x;
1515 } else {
1516 __PS_MV_REG = [];
1517 return 'foo';
1519 };")
1521 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1522 (defun foo ()
1523 (cond ((< 2 1) 5)
1524 (t "foo")
1525 ((< 1 2) "bar")))
1526 "function foo() {
1527 if (2 < 1) {
1528 return 5;
1529 } else {
1530 return 'foo';
1532 };")
1534 (test-ps-js funcall-if-expression
1535 (funcall (getprop document 'write)
1536 (if (= *linkornot* 1)
1537 (ps-html ((:a :href "#"
1538 :onclick (ps-inline (transport)))
1539 img))
1540 img))
1541 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1543 (test-ps-js negate-number-literal
1544 (- 1)
1545 "-1;")
1547 (fiveam:test macro-environment1
1548 (fiveam:is
1549 (string=
1550 (normalize-js-output
1551 (let* ((macroname (gensym)))
1552 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1553 `(defun test1 ()
1554 (macrolet ((,macroname (x) `(aref data ,x)))
1555 (when (,macroname x)
1556 (setf (,macroname x) 123)))))))
1557 (normalize-js-output
1558 "function test1() {
1559 return data[x] ? (data[x] = 123) : null;
1560 };"))))
1562 (fiveam:test macro-environment2
1563 (fiveam:is
1564 (string=
1565 (let ((outer-lexical-variable 1))
1566 (defpsmacro macro-environment2-macro (x)
1567 `(+ ,outer-lexical-variable ,x))
1568 (ps* '(macro-environment2-macro 2)))
1569 "1 + 2;")))
1571 (test-ps-js ampersand-whole-1
1572 (macrolet ((foo (&whole foo bar baz)
1573 (declare (ignore bar baz))
1574 (with-standard-io-syntax
1575 (let ((*print-case* :downcase))
1576 (format nil "~a" foo)))))
1577 (foo 1 2))
1578 "'(foo 1 2)';")
1580 (test-ps-js ampersand-whole-2
1581 (macrolet ((foo (&whole foo bar baz)
1582 `(+ ,bar ,baz)))
1583 (foo 1 2))
1584 "1 + 2;")
1586 (test-ps-js keyword-consistent
1588 "'x';")
1590 (test-ps-js simple-symbol-macrolet
1591 (symbol-macrolet ((x 1)) x)
1592 "1;")
1594 (test-ps-js compound-symbol-macrolet
1595 (symbol-macrolet ((x 123)
1596 (y (* 2 x)))
1598 "2 * 123;")
1600 (test-ps-js define-symbol-macro
1601 (progn (define-symbol-macro tst-sym-macro 2)
1602 tst-sym-macro)
1603 "2;")
1605 (test-ps-js define-symbol-macro1
1606 (progn (define-symbol-macro tst-sym-macro1 2)
1607 (foo tst-sym-macro1))
1608 "foo(2);")
1610 (test-ps-js define-symbol-macro2
1611 (progn (define-symbol-macro tst-sym-macro2 3)
1612 (list tst-sym-macro2))
1613 "[3];")
1615 (test-ps-js define-symbol-macro3
1616 (progn (define-symbol-macro tst-sym-macro3 4)
1617 (setq foo (create tst-sym-macro3 tst-sym-macro3)))
1618 "foo = { tstSymMacro3 : 4 };")
1620 (test-ps-js define-symbol-macro4
1621 (progn (define-symbol-macro tst-sym-macro4 5)
1622 (setq foo (if (baz) tst-sym-macro4 bar)))
1623 "foo = baz() ? 5 : bar;")
1625 (test-ps-js expression-progn
1626 (1+ (progn (foo) (if x 1 2)))
1627 "(foo(), x ? 1 : 2) + 1;")
1629 (test-ps-js let-decl-in-expression
1630 (defun f (x)
1631 (if x 1 (let* ((foo x)) foo)))
1632 "function f(x) {
1633 if (x) {
1634 return 1;
1635 } else {
1636 var foo = x;
1637 return foo;
1639 };")
1641 (test-ps-js special-var1
1642 (progn (defvar *foo*)
1643 (let* ((*foo* 2))
1644 (* *foo* 2)))
1645 "var FOO;
1646 (function () {
1647 var FOO_TMPSTACK1;
1648 try {
1649 FOO_TMPSTACK1 = FOO;
1650 FOO = 2;
1651 return FOO * 2;
1652 } finally {
1653 FOO = FOO_TMPSTACK1;
1655 })();")
1657 (test-ps-js special-var2
1658 (progn (defparameter *foo*)
1659 (let* ((*baz* 3)
1660 (*foo* 2))
1661 (* *foo* 2 *baz*)))
1662 "var FOO;
1663 (function () {
1664 var BAZ = 3;
1665 var FOO_TMPSTACK1;
1666 try {
1667 FOO_TMPSTACK1 = FOO;
1668 FOO = 2;
1669 return FOO * 2 * BAZ;
1670 } finally {
1671 FOO = FOO_TMPSTACK1;
1673 })();")
1675 (test-ps-js literal1
1676 (setf x undefined)
1677 "x = undefined;")
1679 (test-ps-js literal2
1680 (aref this x)
1681 "this[x];")
1683 (test-ps-js setf-dec1
1684 (setf x (- 1 x 2))
1685 "x = 1 - x - 2;")
1687 (test-ps-js setf-dec2
1688 (setf x (- x 1 2))
1689 "x = x - 1 - 2;")
1691 (test-ps-js special-char-equals
1692 blah=
1693 "blahequals;")
1695 (test-ps-js setf-operator-priority
1696 (defun foo ()
1697 (or (getprop cache id)
1698 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1699 "function foo() {
1700 __PS_MV_REG = [];
1701 return cache[id] || (cache[id] = document.getElementById(id));
1702 };")
1704 (test-ps-js aref-operator-priority
1705 (aref (if (and x (> (length x) 0))
1706 (aref x 0)
1709 "(x && x.length > 0 ? x[0] : y)[z];")
1711 (test-ps-js aref-operator-priority1
1712 (aref (or (getprop x 'y)
1713 (getprop a 'b))
1715 "(x.y || a.b)[z];")
1717 (test-ps-js aref-operator-priority2
1718 (aref (if a b c) 0)
1719 "(a ? b : c)[0];")
1721 (test-ps-js negate-operator-priority
1722 (- (if x y z))
1723 "-(x ? y : z);")
1725 (test-ps-js op-p1
1726 (new (or a b))
1727 "new (a || b);")
1729 (test-ps-js op-p2
1730 (delete (if a (or b c) d))
1731 "delete (a ? b || c : d);")
1733 (test-ps-js op-p3
1734 (not (if (or x (not y)) z))
1735 "!(x || !y ? z : null);")
1737 (test-ps-js op-p4
1738 (- (- (* 1 2) 3))
1739 "-(1 * 2 - 3);")
1741 (test-ps-js op-p5
1742 (instanceof (or a b) (if x y z))
1743 "((a || b) instanceof (x ? y : z));")
1745 (test-ps-js op-p7
1746 (or x (if (= x 0) "zero" "empty"))
1747 "x || (x === 0 ? 'zero' : 'empty');")
1749 (test-ps-js named-op-expression
1750 (throw (if a b c))
1751 "throw a ? b : c;")
1753 (test-ps-js named-op-expression1
1754 (typeof (or x y))
1755 "typeof (x || y);")
1757 (test-ps-js aref-array-expression
1758 (aref (or a b c) 0)
1759 "(a || b || c)[0];")
1761 (test-ps-js getprop-operator
1762 (getprop (or a b c) 'd)
1763 "(a || b || c).d;")
1765 (test-ps-js getprop-parens
1766 (getprop (getprop foo 'bar) 'baz)
1767 "foo.bar.baz;")
1769 (test-ps-js funcall-funcall
1770 ((foo))
1771 "foo()();")
1773 (test-ps-js expression-funcall
1774 ((or (@ window eval) eval) foo nil)
1775 "(window.eval || eval)(foo, null);")
1777 (test-ps-js expression-funcall1
1778 (((or (@ window eval) eval) foo nil))
1779 "(window.eval || eval)(foo, null)();")
1781 (test-ps-js expression-funcall2
1782 (((or (@ window eval) eval)) foo nil)
1783 "(window.eval || eval)()(foo, null);")
1785 (test-ps-js who-html1
1786 (who-ps-html (:span :class "ticker-symbol"
1787 :ticker-symbol symbol
1788 (:a :href "http://foo.com"
1789 symbol)
1790 (:span :class "ticker-symbol-popup")))
1791 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1793 (test-ps-js who-html2
1794 (who-ps-html (:p "t0" (:span "t1")))
1795 "'<p>t0<span>t1</span></p>';")
1797 (test-ps-js flet1
1798 ((lambda () (flet ((foo (x)
1799 (1+ x)))
1800 (foo 1))))
1801 "(function () {
1802 var foo = function (x) {
1803 return x + 1;
1805 __PS_MV_REG = [];
1806 return foo(1);
1807 })();")
1809 (test-ps-js flet2
1810 (flet ((foo (x) (1+ x))
1811 (bar (y) (+ 2 y)))
1812 (bar (foo 1)))
1813 "(function () {
1814 var foo = function (x) {
1815 return x + 1;
1817 var bar = function (y) {
1818 return 2 + y;
1820 __PS_MV_REG = [];
1821 return bar(foo(1));
1822 })();")
1824 (test-ps-js flet3
1825 (flet ((foo (x) (+ 2 x)))
1826 (flet ((foo (x) (1+ x))
1827 (bar (y) (+ 2 (foo y))))
1828 (bar (foo 1))))
1829 "(function () {
1830 var foo = function (x) {
1831 return 2 + x;
1833 var foo1 = function (x) {
1834 return x + 1;
1836 var bar = function (y) {
1837 __PS_MV_REG = [];
1838 return 2 + foo(y);
1840 __PS_MV_REG = [];
1841 return bar(foo1(1));
1842 })();")
1844 (test-ps-js labels1
1845 ((lambda () (labels ((foo (x)
1846 (if (= 0 x)
1848 (+ x (foo (1- x))))))
1849 (foo 3))))
1850 "(function () {
1851 var foo = function (x) {
1852 __PS_MV_REG = [];
1853 return 0 === x ? 0 : x + foo(x - 1);
1855 __PS_MV_REG = [];
1856 return foo(3);
1857 })();")
1859 (test-ps-js labels2
1860 (labels ((foo (x) (1+ (bar x)))
1861 (bar (y) (+ 2 (foo y))))
1862 (bar (foo 1)))
1863 "(function () {
1864 var foo = function (x) {
1865 __PS_MV_REG = [];
1866 return bar(x) + 1;
1868 var bar = function (y) {
1869 __PS_MV_REG = [];
1870 return 2 + foo(y);
1872 __PS_MV_REG = [];
1873 return bar(foo(1));
1874 })();")
1876 (test-ps-js labels3
1877 (labels ((foo (x) (1+ x))
1878 (bar (y) (+ 2 (foo y))))
1879 (bar (foo 1)))
1880 "(function () {
1881 var foo = function (x) {
1882 return x + 1;
1884 var bar = function (y) {
1885 __PS_MV_REG = [];
1886 return 2 + foo(y);
1888 __PS_MV_REG = [];
1889 return bar(foo(1));
1890 })();")
1892 (test-ps-js labels-lambda-list
1893 (labels ((foo (x &optional (y 0))
1894 (+ x y)))
1895 (foo 1))
1896 "(function () {
1897 var foo = function (x, y) {
1898 if (y === undefined) {
1899 y = 0;
1901 return x + y;
1903 __PS_MV_REG = [];
1904 return foo(1);
1905 })();")
1907 (test-ps-js for-loop-var-init-exp
1908 ((lambda (x)
1909 (do* ((y (if x 0 1) (1+ y))
1910 (z 0 (1+ z)))
1911 ((= y 3) z)))
1913 "(function (x) {
1914 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1916 return z;
1917 })(true);")
1919 (test-ps-js math-pi
1921 "Math.PI;")
1923 (test-ps-js literal-array
1924 '(1 2 3)
1925 "[1, 2, 3];")
1927 (test-ps-js literal-array-1
1928 '(1 foo 3)
1929 "[1, 'foo', 3];")
1931 (test-ps-js literal-array-literal
1933 "[];")
1935 (test-ps-js literal-array-literal1
1936 '(1 [])
1937 "[1, []];")
1939 (fiveam:test ps-lisp-expands-in-lexical-environment
1940 (fiveam:is (string= (let ((x 5)) (ps (lisp x)))
1941 "5;")))
1943 (fiveam:test ps-lisp-expands-in-lexical-environment1
1944 (fiveam:is (string= (let ((x 5)) (ps (+ 1 (lisp x))))
1945 "1 + 5;")))
1947 (fiveam:test ps-lisp-expands-in-lexical-environment2
1948 (fiveam:is (string= (let ((x 2)) (ps (+ 1 (lisp x) 3)))
1949 "1 + 2 + 3;")))
1951 (fiveam:test ps*-lisp-expands-in-null-lexical-environment
1952 (fiveam:signals unbound-variable
1953 (let ((x 5))
1954 (declare (ignore x))
1955 (ps* '(lisp x)))))
1957 (fiveam:test ps*-lisp-expands-in-dynamic-environment
1958 (fiveam:is (string=
1959 (let ((foo 2))
1960 (declare (special foo))
1961 (ps* '(+ 1 (lisp (locally (declare (special foo))
1962 foo)))))
1963 "1 + 2;")))
1965 (fiveam:test ps-lisp-dynamic-environment
1966 (fiveam:is (string=
1967 (let ((foo 2))
1968 (declare (special foo))
1969 (ps (+ 1 (lisp foo))))
1970 "1 + 2;")))
1972 (test-ps-js nested-if-expressions1
1973 (defun foo ()
1974 (return-from foo (if (if x y z) a b)))
1975 "function foo() {
1976 if (x ? y : z) {
1977 return a;
1978 } else {
1979 return b;
1981 };")
1983 (test-ps-js nested-if-expressions2
1984 (defun foo ()
1985 (if x y (if z a b)))
1986 "function foo() {
1987 if (x) {
1988 return y;
1989 } else {
1990 return z ? a : b;
1992 };")
1994 (test-ps-js nested-if-expressions3
1995 (foo (if (if x y z) a b)
1996 (if x y (if z a b)))
1997 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
1999 (test-ps-js let1
2000 (let (x)
2001 (+ x x))
2002 "(function () {
2003 var x = null;
2004 return x + x;
2005 })();")
2007 (test-ps-js let2
2008 (let ((x 1))
2009 (+ x x))
2010 "(function () {
2011 var x = 1;
2012 return x + x;
2013 })();")
2015 (test-ps-js let-x-x
2016 (let ((x (1+ x)))
2017 (+ x x))
2018 "(function () {
2019 var x1 = x + 1;
2020 return x1 + x1;
2021 })();")
2023 (test-ps-js let3
2024 (let ((x 1)
2025 (y 2))
2026 (+ x x))
2027 "(function () {
2028 var x = 1;
2029 var y = 2;
2030 return x + x;
2031 })();")
2033 (test-ps-js let4
2034 (let ((x 1)
2035 (y (1+ x)))
2036 (+ x y))
2037 "(function () {
2038 var x1 = 1;
2039 var y = x + 1;
2040 return x1 + y;
2041 })();")
2043 (test-ps-js let5
2044 (let ((x 1))
2045 (+ x 1)
2046 (let ((x (+ x 5)))
2047 (+ x 1))
2048 (+ x 1))
2049 "(function () {
2050 var x = 1;
2051 x + 1;
2052 var x1 = x + 5;
2053 x1 + 1;
2054 return x + 1;
2055 })();")
2057 (test-ps-js let6
2058 (let ((x 2))
2059 (let ((x 1)
2060 (y (1+ x)))
2061 (+ x y)))
2062 "(function () {
2063 var x = 2;
2064 var x1 = 1;
2065 var y = x + 1;
2066 return x1 + y;
2067 })();")
2069 (test-ps-js let-exp1
2070 (lambda ()
2071 (let (x)
2072 (+ x x)))
2073 "function () {
2074 var x = null;
2075 return x + x;
2076 };")
2078 (test-ps-js let*1
2079 (let* ((x 1))
2080 (+ x x))
2081 "(function () {
2082 var x = 1;
2083 return x + x;
2084 })();")
2086 (test-ps-js let*2
2087 (let* ((x 1)
2088 (y (+ x 2)))
2089 (+ x y))
2090 "(function () {
2091 var x = 1;
2092 var y = x + 2;
2093 return x + y;
2094 })();")
2096 (test-ps-js let*3
2097 (let ((x 3))
2098 (let* ((x 1)
2099 (y (+ x 2)))
2100 (+ x y)))
2101 "(function () {
2102 var x = 3;
2103 var x1 = 1;
2104 var y = x1 + 2;
2105 return x1 + y;
2106 })();")
2108 (test-ps-js let*4
2109 (let ((x 3))
2110 (let* ((y (+ x 2))
2111 (x 1))
2112 (+ x y)))
2113 "(function () {
2114 var x = 3;
2115 var y = x + 2;
2116 var x1 = 1;
2117 return x1 + y;
2118 })();")
2120 (test-ps-js symbol-macrolet-var
2121 (symbol-macrolet ((x y))
2122 (var x))
2123 "var y;")
2125 (test-ps-js setf-conditional1
2126 (setf x (unless (null a) (1+ a)))
2127 "x = a != null ? a + 1 : null;")
2129 (test-ps-js setf-let1
2130 (setf x (let ((a 1)) a))
2131 "x = (function () {
2132 var a = 1;
2133 return a;
2134 })();")
2136 (test-ps-js setf-let2
2137 (setf x (let ((a (foo)))
2138 (unless (null a)
2139 (1+ a))))
2140 "x = (function () {
2141 var a = foo();
2142 __PS_MV_REG = [];
2143 return a != null ? a + 1 : null;
2144 })();")
2146 (test-ps-js symbol-macro-env1
2147 (symbol-macrolet ((bar 1))
2148 (macrolet ((bar (x y) `(+ ,x ,y)))
2149 (bar bar bar)))
2150 "1 + 1;")
2152 (test-ps-js symbol-macrolet-fun1
2153 (symbol-macrolet ((baz +))
2154 (baz 1 2))
2155 "baz(1, 2);")
2157 (test-ps-js lisp2-namespaces1
2158 (let ((list nil))
2159 (setf list (list 1 2 3)))
2160 "(function () {
2161 var list = null;
2162 return list = [1, 2, 3];
2163 })();")
2165 (test-ps-js let-shadows-symbol-macrolet
2166 (symbol-macrolet ((x y))
2167 (let ((x 1))
2168 (+ x x))
2169 (+ x x))
2170 "(function () {
2171 var x1 = 1;
2172 return x1 + x1;
2173 })();
2174 y + y;")
2176 (test-ps-js let-rename-optimization1
2177 (let ((x 1))
2178 (+ x x))
2179 "(function () {
2180 var x = 1;
2181 return x + x;
2182 })();")
2184 (test-ps-js let-rename-optimization2
2185 (lambda (x)
2186 (let ((x (+ 1 x)))
2188 "function (x) {
2189 var x1 = 1 + x;
2190 return x1;
2191 };")
2193 (test-ps-js symbol-macro-array
2194 (symbol-macrolet ((x 1))
2195 (list x))
2196 "[1];")
2198 (test-ps-js symbol-macro-obj
2199 (symbol-macrolet ((x (+ 1 2)))
2200 (create x 1))
2201 "{ x : 1 };")
2203 (test-ps-js symbol-macro-obj1
2204 (symbol-macrolet ((x (+ 1 2)))
2205 (ps:create x x))
2206 "{ x : 1 + 2 };")
2208 (test-ps-js symbol-macro-getprop1
2209 (symbol-macrolet ((x (+ 1 2)))
2210 (ps:getprop a x))
2211 "a[1 + 2];")
2213 (test-ps-js symbol-macro-getprop1
2214 (symbol-macrolet ((x (+ 1 2)))
2215 (ps:getprop a 'x))
2216 "a.x;")
2218 (test-ps-js let-let-create
2219 (let ((a 99))
2220 (let ((a 22))
2221 (create a 33)))
2222 "(function () {
2223 var a = 99;
2224 var a1 = 22;
2225 return { a : 33 };
2226 })();")
2228 (test-ps-js symbol-macro-conditional1
2229 (symbol-macrolet ((x y))
2230 (if x x x))
2231 "if (y) {
2233 } else {
2235 };")
2237 (test-ps-js symbol-macro-conditional2
2238 (symbol-macrolet ((x y))
2239 (1+ (if x x x)))
2240 "(y ? y : y) + 1;")
2242 (test-ps-js preserve-this
2243 (defun foo ()
2244 (let ((y (block nil (bar this))))
2245 (baz y)))
2246 "function foo() {
2247 var y = (function () {
2248 __PS_MV_REG = [];
2249 return bar(this);
2250 }).call(this);
2251 __PS_MV_REG = [];
2252 return baz(y);
2253 };")
2255 (test-ps-js flet-apply
2256 (flet ((foo () 'bar))
2257 (apply (function foo) nil))
2258 "(function () {
2259 var foo = function () {
2260 return 'bar';
2262 return foo.apply(this, null);
2263 }).call(this);")
2265 (test-ps-js let-apply
2266 (let ((foo (lambda () 1)))
2267 (let ((foo (lambda () 2)))
2268 (apply foo nil)))
2269 "(function () {
2270 var foo = function () {
2271 return 1;
2273 var foo1 = function () {
2274 return 2;
2276 return foo1.apply(this, null);
2277 }).call(this);")
2279 (test-ps-js flet-let
2280 (flet ((x (x) (1+ x)))
2281 (let ((x 2))
2282 (x x)))
2283 "(function () {
2284 var x = function (x) {
2285 return x + 1;
2287 var x1 = 2;
2288 __PS_MV_REG = [];
2289 return x(x1);
2290 })();")
2292 (test-ps-js let-flet
2293 (let ((x 2))
2294 (flet ((x (x) (1+ x)))
2295 (x x)))
2296 "(function () {
2297 var x = 2;
2298 var x1 = function (x) {
2299 return x + 1;
2301 __PS_MV_REG = [];
2302 return x1(x);
2303 })();")
2305 (test-ps-js labels-let
2306 (labels ((x (x) (1+ x)))
2307 (let ((x 2))
2308 (x x)))
2309 "(function () {
2310 var x = function (x) {
2311 return x + 1;
2313 var x1 = 2;
2314 __PS_MV_REG = [];
2315 return x(x1);
2316 })();")
2318 (test-ps-js let-labels
2319 (let ((x 2))
2320 (labels ((x (x) (1+ x)))
2321 (x x)))
2322 "(function () {
2323 var x = 2;
2324 var x1 = function (x) {
2325 return x + 1;
2327 __PS_MV_REG = [];
2328 return x1(x);
2329 })();")
2331 (test-ps-js macrolet-let-inteference
2332 (macrolet ((a (n) `(+ ,n 5)))
2333 (let ((a (a 1)))
2334 (let ((b (a (- a 4))))
2335 (+ a b))))
2336 "(function () {
2337 var a = 1 + 5;
2338 var b = (a - 4) + 5;
2339 return a + b;
2340 })();")
2342 (test-ps-js let-subtract-add
2343 (let ((x 1))
2344 (let ((x 2))
2345 (- x x)
2346 (- x)
2347 (decf x)
2348 (incf x)))
2349 "(function () {
2350 var x = 1;
2351 var x1 = 2;
2352 x1 - x1;
2353 -x1;
2354 --x1;
2355 return ++x1;
2356 })();")
2358 (test-ps-js create-reserved-word
2359 (create :default 1)
2360 "{ 'default' : 1 };")
2362 (test-ps-js getprop-reserved-word
2363 (getprop foo :default)
2364 "foo['default'];")
2366 (test-ps-js getprop-reserved-word1
2367 (getprop foo 'default)
2368 "foo['default'];")
2370 (test-ps-js eval-when-ps-side
2371 (eval-when (:execute)
2373 "5;")
2375 (defvar *lisp-output* nil)
2377 (fiveam:test eval-when-lisp-side ()
2378 (setf *lisp-output* 'original-value)
2379 (let ((js-output
2380 (normalize-js-output
2381 (ps-doc* `(eval-when (:compile-toplevel)
2382 (setf *lisp-output* 'it-works))))))
2383 (fiveam:is (eql 'it-works *lisp-output*))
2384 (fiveam:is (string= "" js-output))))
2386 (defpsmacro my-in-package (package-name)
2387 `(eval-when (:compile-toplevel)
2388 (setf *lisp-output* ,package-name)))
2390 (fiveam:test eval-when-macro-expansion ()
2391 (setf *lisp-output* 'original-value)
2392 (let ((js-output
2393 (normalize-js-output
2394 (ps-doc* `(progn
2395 (my-in-package :cl-user)
2396 3)))))
2397 (declare (ignore js-output))
2398 (fiveam:is (eql :cl-user *lisp-output*))))
2400 (fiveam:test eval-when-macrolet-expansion ()
2401 (setf *lisp-output* 'original-value)
2402 (let ((js-output
2403 (normalize-js-output
2404 (ps-doc*
2405 `(macrolet ((my-in-package2 (package-name)
2406 `(eval-when (:compile-toplevel)
2407 (setf *lisp-output* ,package-name))))
2408 (my-in-package2 :cl-user)
2409 3)))))
2410 (declare (ignore js-output))
2411 (fiveam:is (eql :cl-user *lisp-output*))))
2413 (test-ps-js getprop-keyword
2414 (getprop foo :bar)
2415 "foo['bar'];")
2417 (test-ps-js nary-comparison1
2418 (lambda () (< 1 2 3))
2419 "function () {
2420 var _cmp1;
2421 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2422 };")
2424 (test-ps-js chain-getprop1
2425 (chain ($ "foo") (bar x z) frob (baz 5))
2426 "$('foo').bar(x, z).frob.baz(5);")
2428 (test-ps-js chain-getprop2
2429 (chain ($ "foo") bar baz)
2430 "$('foo').bar.baz;")
2432 (test-ps-js chain-getprop3
2433 (chain ($ "foo") bar (x y) baz)
2434 "$('foo').bar.x(y).baz;")
2436 (test-ps-js flet-expression
2437 (1+ (flet ((foo (x) (1+ x)))
2438 (foo 1)))
2439 "(function () {
2440 var foo = function (x) {
2441 return x + 1;
2443 __PS_MV_REG = [];
2444 return foo(1);
2445 })() + 1;")
2447 (test-ps-js flet-lambda-list
2448 (flet ((foo (x &key (y 0))
2449 (+ x y)))
2450 (foo 1 :y 2))
2451 "(function () {
2452 var foo = function (x) {
2453 var _js2 = arguments.length;
2454 for (var n1 = 1; n1 < _js2; n1 += 2) {
2455 switch (arguments[n1]) {
2456 case 'y':
2457 y = arguments[n1 + 1];
2460 var y = 'undefined' === typeof y ? 0 : y;
2461 return x + y;
2463 __PS_MV_REG = [];
2464 return foo(1, 'y', 2);
2465 })();")
2467 (test-ps-js return-case-break-elimination
2468 (defun foo ()
2469 (case 1
2470 (0 1)
2471 (otherwise 2)))
2472 "function foo() {
2473 switch (1) {
2474 case 0:
2475 return 1;
2476 default:
2477 return 2;
2479 };")
2481 (test-ps-js aplusplus
2483 "aplusplus;")
2485 (test-ps-js astarstar
2487 "astarstar;")
2489 (test-ps-js switch-return-fallthrough
2490 (defun foo ()
2491 (switch x
2492 (1 (foo) break)
2493 (2 (bar))
2494 (default 4)))
2495 "function foo() {
2496 switch (x) {
2497 case 1:
2498 __PS_MV_REG = [];
2499 return foo();
2500 case 2:
2501 bar();
2502 default:
2503 __PS_MV_REG = [];
2504 return 4;
2506 };")
2508 (test-ps-js return-last-case
2509 (defun foo ()
2510 (case x
2511 (:a 'eh)
2512 (:b 'bee)))
2513 "function foo() {
2514 switch (x) {
2515 case 'a':
2516 return 'eh';
2517 case 'b':
2518 return 'bee';
2520 };")
2522 (test-ps-js return-macrolet
2523 (defun foo ()
2524 (macrolet ((x () 1))
2525 (case (x)
2526 (:a 'eh)
2527 (:b 'bee))))
2528 "function foo() {
2529 switch (1) {
2530 case 'a':
2531 return 'eh';
2532 case 'b':
2533 return 'bee';
2535 };")
2537 (test-ps-js mv-bind1
2538 (multiple-value-bind (a b)
2539 (progn
2540 (returns-mv)
2541 (doesnt))
2542 (alert a)
2543 (alert b))
2544 "returnsMv();
2545 __PS_MV_REG = [];
2546 (function () {
2547 var a = doesnt();
2548 var b = __PS_MV_REG[0];
2549 alert(a);
2550 __PS_MV_REG = [];
2551 return alert(b);
2552 })();")
2554 (test-ps-js mv-bind2
2555 (multiple-value-bind (a b)
2556 (let ((a 1))
2557 (returns-mv a)
2558 (doesnt b))
2559 (alert a)
2560 (alert b))
2561 "(function () {
2562 var a = 1;
2563 returnsMv(a);
2564 __PS_MV_REG = [];
2565 var a1 = doesnt(b);
2566 var b = __PS_MV_REG[0];
2567 alert(a1);
2568 __PS_MV_REG = [];
2569 return alert(b);
2570 })();")
2572 (test-ps-js multiple-value-bind-simple
2573 (multiple-value-bind (a b) (blah)
2574 (+ a b))
2575 "__PS_MV_REG = [];
2576 (function () {
2577 var a = blah();
2578 var b = __PS_MV_REG[0];
2579 __PS_MV_REG = [];
2580 return a + b;
2581 })();")
2583 (test-ps-js values0
2584 (lambda () (values))
2585 "function () {
2586 return;
2587 };")
2589 (test-ps-js values1
2590 (lambda () (values x))
2591 "function () {
2592 return x;
2593 };")
2595 (test-ps-js values2
2596 (lambda () (values x y))
2597 "function () {
2598 var val1 = x;
2599 __PS_MV_REG = [y];
2600 return val1;
2601 };")
2603 (test-ps-js values3
2604 (lambda () (values x y z))
2605 "function () {
2606 var val1 = x;
2607 __PS_MV_REG = [y, z];
2608 return val1;
2609 };")
2611 (test-ps-js values-return
2612 (defun foo (x y)
2613 (return-from foo (values (* x x) y)))
2614 "function foo(x, y) {
2615 var val1 = x * x;
2616 __PS_MV_REG = [y];
2617 return val1;
2618 };")
2620 (test-ps-js return-macrolet1
2621 (defun foo ()
2622 (symbol-macrolet ((x 2))
2623 (loop do (+ x x))))
2624 "function foo() {
2625 while (true) {
2626 2 + 2;
2628 };")
2630 (test-ps-js return-cond
2631 (defun foo ()
2632 (return-from foo
2633 (cond ((foo? x) (loop for y in x do (foo y)))
2634 ((bar? x) x)
2635 (t 3))))
2636 "function foo() {
2637 if (foowhat(x)) {
2638 var _js2 = x.length;
2639 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2640 var y = x[_js1];
2641 foo(y);
2643 } else if (barwhat(x)) {
2644 __PS_MV_REG = [];
2645 return x;
2646 } else {
2647 __PS_MV_REG = [];
2648 return 3;
2650 };")
2652 (test-ps-js return-case
2653 (defun foo ()
2654 (return-from foo
2655 (case x
2656 (1 (loop for y in x do (foo y)))
2657 (2 x)
2658 ((t) 3))))
2659 "function foo() {
2660 switch (x) {
2661 case 1:
2662 var _js2 = x.length;
2663 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2664 var y = x[_js1];
2665 foo(y);
2667 __PS_MV_REG = [];
2668 return;
2669 case 2:
2670 __PS_MV_REG = [];
2671 return x;
2672 case true:
2673 __PS_MV_REG = [];
2674 return 3;
2676 };")
2678 (test-ps-js return-case1
2679 (defun foo ()
2680 (return-from foo
2681 (case x
2682 (1 (if a 1 2))
2683 (2 x)
2684 ((t) 3))))
2685 "function foo() {
2686 switch (x) {
2687 case 1:
2688 return a ? 1 : 2;
2689 case 2:
2690 return x;
2691 case true:
2692 return 3;
2694 };")
2696 (test-ps-js lambda-loop-if-return
2697 (lambda ()
2698 (if a
2699 (loop for y in x do (foo y))
2701 "function () {
2702 if (a) {
2703 var _js4 = x.length;
2704 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2705 var y = x[_js3];
2706 foo(y);
2708 } else {
2709 __PS_MV_REG = [];
2710 return c;
2712 };")
2714 (test-ps-js lambda-loop-if-return1
2715 (defun baz ()
2716 (foo (lambda ()
2717 (if a
2718 (progn (loop for y in x do (foo y))
2719 (return-from baz))
2720 c))))
2721 "function baz() {
2722 try {
2723 __PS_MV_REG = [];
2724 return foo(function () {
2725 if (a) {
2726 var _js4 = x.length;
2727 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2728 var y = x[_js3];
2729 foo(y);
2731 __PS_MV_REG = [];
2732 throw { '__ps_block_tag' : 'baz',
2733 '__ps_value' : null };
2734 } else {
2735 __PS_MV_REG = [];
2736 return c;
2739 } catch (_ps_err5) {
2740 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2741 return _ps_err5['__ps_value'];
2742 } else {
2743 throw _ps_err5;
2746 };")
2748 (test-ps-js switch-loop
2749 (defun foo (x)
2750 (case x
2751 (1 (dolist (a b)))))
2752 "function foo(x) {
2753 switch (x) {
2754 case 1:
2755 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2756 a = b[_js_idx1];
2758 return;
2760 };")
2762 (test-ps-js switch-folds-blocks
2763 (defun foo ()
2764 (case x
2765 (1 (loop repeat 3 do (alert "foo")))
2766 (2 "bar")))
2767 "function foo() {
2768 switch (x) {
2769 case 1:
2770 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2771 alert('foo');
2773 __PS_MV_REG = [];
2774 return;
2775 case 2:
2776 __PS_MV_REG = [];
2777 return 'bar';
2779 };")
2781 (test-ps-js setf-places-before-macros
2782 (lambda ()
2783 (defsetf left (el) (offset)
2784 `(setf (@ ,el style left) ,offset))
2785 (macrolet ((left (el)
2786 `(@ ,el offset-left)))
2787 (setf (left x) 10)
2788 (left x)))
2789 "function () {
2790 var _js2 = x;
2791 var _js1 = 10;
2792 _js2.style.left = _js1;
2793 return x.offsetLeft;
2794 };")
2796 (test-ps-js for-return
2797 (lambda () (dolist (arg args) (foo arg)))
2798 "function () {
2799 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2800 arg = args[_js_idx1];
2801 foo(arg);
2803 };")
2805 (test-ps-js try-catch-return
2806 (defun foo ()
2807 (try (foo)
2808 (:catch (e)
2809 (bar))
2810 (:finally
2811 (cleanup))))
2812 "function foo() {
2813 try {
2814 __PS_MV_REG = [];
2815 return foo();
2816 } catch (e) {
2817 __PS_MV_REG = [];
2818 return bar();
2819 } finally {
2820 cleanup();
2822 };")
2824 (test-ps-js let-try
2825 (let ((x (ps:try (+ 1 2)
2826 (:catch (y) 5))))
2828 "(function () {
2829 var x = (function () {
2830 try {
2831 return 1 + 2;
2832 } catch (y) {
2833 return 5;
2835 })();
2836 __PS_MV_REG = [];
2837 return x;
2838 })();")
2840 (test-ps-js try-finally-return-from
2841 (defun xyz ()
2842 (return-from xyz
2843 (ps:try (when (blah) 4)
2844 (:finally (foo))))
2845 (dont-call-me))
2846 "function xyz() {
2847 try {
2848 __PS_MV_REG = [];
2849 return blah() ? 4 : null;
2850 } finally {
2851 foo();
2853 __PS_MV_REG = [];
2854 return dontCallMe();
2855 };")
2857 (test-ps-js defun-setf-optional
2858 (defun (setf foo) (new-value b &optional c)
2859 (setf (aref b (or c 0)) new-value))
2860 "function __setf_foo(newValue, b, c) {
2861 return b[c || 0] = newValue;
2862 };")
2864 (test-ps-js defun-setf-rest
2865 (progn (defun (setf foo) (new-value b &rest foo)
2866 (do-something b foo new-value))
2867 (setf (foo x 1 2 3 4) 5))
2868 "function __setf_foo(newValue, b) {
2869 var foo = Array.prototype.slice.call(arguments, 2);
2870 __PS_MV_REG = [];
2871 return doSomething(b, foo, newValue);
2873 __setf_foo(5, x, 1, 2, 3, 4);")
2875 (test-ps-js return-null
2876 (defun foo () (return-from foo nil))
2877 "function foo() {
2878 return null;
2879 };")
2881 (test-ps-js implicit-return-null
2882 (lambda ()
2884 "function () {
2885 return null;
2886 };")
2888 (test-ps-js implicit-return-null
2889 (lambda ()
2890 nil)
2891 "function () {
2892 return null;
2893 };")
2895 (test-ps-js return-conditional-nested
2896 (defun blep (ss x y)
2897 (when foo?
2898 (let ((pair (bar)))
2899 (unless (null pair)
2900 (destructuring-bind (a b) pair
2901 (unless (or (null a) (null b))
2902 (let ((val (baz a b)))
2903 (unless (null val)
2904 (when (blah val)
2905 (unless (blee)
2906 t))))))))))
2907 "function blep(ss, x, y) {
2908 if (foowhat) {
2909 var pair = bar();
2910 if (pair != null) {
2911 var a = pair[0];
2912 var b = pair[1];
2913 if (!(a == null || b == null)) {
2914 var val = baz(a, b);
2915 if (val != null) {
2916 if (blah(val)) {
2917 __PS_MV_REG = [];
2918 return !blee() ? true : null;
2924 };")
2926 (test-ps-js return-when-returns-broken-return
2927 (defun foo ()
2928 (return-from foo (when x 1))
2929 (+ 2 3))
2930 "function foo() {
2931 return x ? 1 : null;
2932 return 2 + 3;
2933 };")
2935 (test-ps-js return-case-conditional
2936 (defun foo ()
2937 (return-from foo
2938 (case foo
2939 (123 (when (bar) t))
2940 (345 (blah)))))
2941 "function foo() {
2942 switch (foo) {
2943 case 123:
2944 __PS_MV_REG = [];
2945 return bar() ? true : null;
2946 case 345:
2947 __PS_MV_REG = [];
2948 return blah();
2950 };")
2952 (test-ps-js return-try-conditional
2953 (defun foo ()
2954 (return-from foo
2955 (try (when x 1)
2956 (:catch (x) 2)
2957 (:finally (bar)))))
2958 "function foo() {
2959 try {
2960 return x ? 1 : null;
2961 } catch (x) {
2962 return 2;
2963 } finally {
2964 bar();
2966 };")
2968 (test-ps-js function-declare-special
2969 (lambda ()
2970 (declare (special *foo*))
2971 (let ((*foo* 1))
2972 (1+ *foo*)))
2973 "function () {
2974 var FOO_TMPSTACK1;
2975 try {
2976 FOO_TMPSTACK1 = FOO;
2977 FOO = 1;
2978 return FOO + 1;
2979 } finally {
2980 FOO = FOO_TMPSTACK1;
2982 };")
2984 (test-ps-js declare-special-let
2985 (let ((*foo* 123))
2986 (declare (special *foo*))
2987 (blah))
2988 "(function () {
2989 var FOO_TMPSTACK1;
2990 try {
2991 FOO_TMPSTACK1 = FOO;
2992 FOO = 123;
2993 __PS_MV_REG = [];
2994 return blah();
2995 } finally {
2996 FOO = FOO_TMPSTACK1;
2998 })();")
3000 (test-ps-js declare-special-let-scope
3001 (block nil
3002 (let ((*foo* 123))
3003 (declare (special *foo*))
3004 (blah))
3005 (let ((*foo* 456))
3006 (+ 4 5)))
3007 "(function () {
3008 var FOO_TMPSTACK1;
3009 try {
3010 FOO_TMPSTACK1 = FOO;
3011 FOO = 123;
3012 blah();
3013 } finally {
3014 FOO = FOO_TMPSTACK1;
3016 var FOO = 456;
3017 __PS_MV_REG = [];
3018 return 4 + 5;
3019 })();")
3021 (test-ps-js declare-special-let*
3022 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
3023 (declare (special *foo* *bar*))
3024 (blah))
3025 "(function () {
3026 var FOO_TMPSTACK1;
3027 try {
3028 FOO_TMPSTACK1 = FOO;
3029 FOO = 123;
3030 var BAR_TMPSTACK2;
3031 try {
3032 BAR_TMPSTACK2 = BAR;
3033 BAR = FOO + BAR;
3034 __PS_MV_REG = [];
3035 return blah();
3036 } finally {
3037 BAR = BAR_TMPSTACK2;
3039 } finally {
3040 FOO = FOO_TMPSTACK1;
3042 })();")
3044 (test-ps-js defun-multiple-declarations-around-docstring
3045 (defun foo (x y)
3046 (declare (ignorable x y))
3047 (declare (integer x) (float y))
3048 "Fooes X while barring Y."
3049 (declare (special *foo*) (special *bar*))
3050 (let ((*bar* (bar y)))
3051 (funcall *foo* x)))
3052 "/** Fooes X while barring Y. */
3053 function foo(x, y) {
3054 var BAR_TMPSTACK1;
3055 try {
3056 BAR_TMPSTACK1 = BAR;
3057 BAR = bar(y);
3058 __PS_MV_REG = [];
3059 return FOO(x);
3060 } finally {
3061 BAR = BAR_TMPSTACK1;
3063 };")
3065 (test-ps-js macro-null-toplevel
3066 (progn
3067 (defmacro macro-null-toplevel ()
3068 nil)
3069 (macro-null-toplevel))
3072 (test-ps-js define-symbol-macro-let
3073 (progn
3074 (define-symbol-macro test-symbol-macro 1)
3075 (let ((test-symbol-macro 2))
3076 (1+ test-symbol-macro))
3077 (1+ test-symbol-macro))
3078 "(function () {
3079 var testSymbolMacro1 = 2;
3080 return testSymbolMacro1 + 1;
3081 })();
3082 1 + 1;")
3084 (test-ps-js define-symbol-macro-flet
3085 (progn
3086 (define-symbol-macro test-symbol-macro1 1)
3087 (flet ((test-symbol-macro1 () 2))
3088 (foo test-symbol-macro1)
3089 (test-symbol-macro1))
3090 (bar test-symbol-macro1))
3091 "(function () {
3092 var testSymbolMacro1_1 = function () {
3093 return 2;
3095 foo(1);
3096 __PS_MV_REG = [];
3097 return testSymbolMacro1_1();
3098 })();
3099 bar(1);")
3101 (fiveam:test compile-stream-nulls
3102 (fiveam:is
3103 (string=
3104 (with-input-from-string (s "
3105 (defmacro macro-null-toplevel ()
3106 nil)
3107 (macro-null-toplevel)")
3108 (ps-compile-stream s))
3109 "")))
3111 (fiveam:test compile-stream1
3112 (fiveam:is
3113 (string=
3114 (with-input-from-string (s "
3115 (define-symbol-macro test-symbol-macro1 1)
3116 (flet ((test-symbol-macro1 () 2))
3117 (foo test-symbol-macro1)
3118 (test-symbol-macro1))
3119 (bar test-symbol-macro1)")
3120 (ps::with-blank-compilation-environment
3121 (ps-compile-stream s)))
3122 "(function () {
3123 var testSymbolMacro1_1 = function () {
3124 return 2;
3126 foo(1);
3127 __PS_MV_REG = [];
3128 return testSymbolMacro1_1();
3129 })();
3130 bar(1);
3131 ")))
3133 (test-ps-js equality-nary1
3134 (let ((x 10) (y 10) (z 10))
3135 (= x y z))
3136 "(function () {
3137 var _cmp1;
3138 var x = 10;
3139 var y = 10;
3140 var z = 10;
3141 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3142 })();")
3144 (test-ps-js equality1
3145 (progn
3146 (equal a b)
3147 (eql a b)
3148 (eq a b)
3149 (= a b))
3150 "a == b;
3151 a === b;
3152 a === b;
3153 a === b;")
3155 (test-ps-js getprop-quote-reserved
3156 (getprop foo ':break)
3157 "foo['break'];")
3159 (test-ps-js defun-block-return-from
3160 (defun foo (x)
3161 (baz 4)
3162 (return-from foo x)
3163 (bar 5))
3164 "function foo(x) {
3165 baz(4);
3166 __PS_MV_REG = [];
3167 return x;
3168 __PS_MV_REG = [];
3169 return bar(5);
3170 };")
3172 (test-ps-js block-return-from
3173 (block scope
3174 (foo)
3175 (when (bar)
3176 (return-from scope))
3177 (blee))
3178 "(function () {
3179 foo();
3180 if (bar()) {
3181 __PS_MV_REG = [];
3182 return;
3184 __PS_MV_REG = [];
3185 return blee();
3186 })();")
3188 (test-ps-js block-return-from0
3189 (defun baz ()
3190 (block scope
3191 (foo)
3192 (when (bar)
3193 (return-from scope))
3194 (blee)))
3195 "function baz() {
3196 foo();
3197 if (bar()) {
3198 __PS_MV_REG = [];
3199 return;
3201 __PS_MV_REG = [];
3202 return blee();
3203 };")
3205 (test-ps-js block-return-from01
3206 (defun baz ()
3207 (block scope
3208 (foo)
3209 (when (bar)
3210 (return-from scope))
3211 (blee))
3213 "function baz() {
3214 scope: {
3215 foo();
3216 if (bar()) {
3217 __PS_MV_REG = [];
3218 break scope;
3220 blee();
3222 __PS_MV_REG = [];
3223 return 2;
3224 };")
3226 (test-ps-js block-return-from02
3227 (defun baz ()
3228 (block scope
3229 (foo)
3230 (when (bar)
3231 (return-from scope (foobar)))
3232 (blee))
3234 "function baz() {
3235 scope: {
3236 foo();
3237 if (bar()) {
3238 __PS_MV_REG = [];
3239 foobar();
3240 break scope;
3242 blee();
3244 __PS_MV_REG = [];
3245 return 2;
3246 };")
3248 (test-ps-js block-return-from1
3249 (lambda ()
3250 (block scope
3251 (foo)
3252 (when (bar)
3253 (return-from scope))
3254 (blee))
3255 (+ 1 2))
3256 "function () {
3257 scope: {
3258 foo();
3259 if (bar()) {
3260 __PS_MV_REG = [];
3261 break scope;
3263 blee();
3265 __PS_MV_REG = [];
3266 return 1 + 2;
3267 };")
3269 (test-ps-js block-return-from2
3270 (lambda ()
3271 (bar 5)
3272 (block scope
3273 (foo)
3274 (when (bar)
3275 (return-from scope 6))
3276 (blee)))
3277 "function () {
3278 bar(5);
3279 foo();
3280 if (bar()) {
3281 __PS_MV_REG = [];
3282 return 6;
3284 __PS_MV_REG = [];
3285 return blee();
3286 };")
3288 (test-ps-js let-funcall
3289 (let ((x foo))
3290 (funcall x)
3291 (let ((x bar))
3292 (funcall x))
3293 (funcall x))
3294 "(function () {
3295 var x = foo;
3296 x();
3297 var x1 = bar;
3298 x1();
3299 return x();
3300 })();")
3302 (test-ps-js symbol-macrolet-funcall
3303 (symbol-macrolet ((foo bar))
3304 (funcall foo 1 2 3))
3305 "bar(1, 2, 3);")
3307 (test-ps-js times-assign
3308 (setf x (* x 1000))
3309 "x *= 1000;")
3311 (test-ps-js vector-literal
3312 #(1 2 3)
3313 "[1, 2, 3];")
3315 (test-ps-js vector-literal1
3316 #(1 2 #(a b) 3)
3317 "[1, 2, ['a', 'b'], 3];")
3319 (test-ps-js rem1
3320 (+ 1 (rem 2 (+ 3 4)))
3321 "1 + 2 % (3 + 4);")
3323 (test-ps-js non-associative
3324 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3325 "1 / (2 / 3) + (1 - (2 - 3));")
3327 (test-ps-js lambda-apply
3328 (lambda (x)
3329 (apply (lambda (y) (bar (1+ y))) x))
3330 "function (x) {
3331 return (function (y) {
3332 __PS_MV_REG = [];
3333 return bar(y + 1);
3334 }).apply(this, x);
3335 };")
3337 (test-ps-js operator-expressions-nested-let
3338 (let ((x (let ((y 1))
3339 y)))
3341 "(function () {
3342 var y;
3343 var x = (y = 1, y);
3344 return x;
3345 })();")
3347 (test-ps-js operator-expressions-array-nested-let
3348 (list (let ((y 1)) y) 2)
3349 "[(function () {
3350 var y = 1;
3351 return y;
3352 })(), 2];")
3354 (test-ps-js add-subtract-precedence
3355 (- x (+ y z))
3356 "x - (y + z);")
3358 (test-ps-js ps-inline-toplevel
3359 (ps-inline (foo))
3360 "'javascript:' + 'foo()';")
3362 (test-ps-js no-clause-progn-exp
3363 (setf x (progn))
3364 "x = null;")
3366 (test-ps-js no-clause-progn-return
3367 (defun foo ()
3368 (return-from foo (progn)))
3369 "function foo() {
3370 return null;
3371 };")
3373 (test-ps-js empty-cond-clause
3374 (setf x (cond ((foo))))
3375 "x = (function () {
3376 var testResult1 = foo();
3377 __PS_MV_REG = [];
3378 return testResult1 ? testResult1 : null;
3379 })();")
3381 (test-ps-js empty-cond-clause1
3382 (setf x (cond ((foo) 123)
3383 ((bar))
3384 (t 456)))
3385 "x = foo() ? 123 :
3386 (function () {
3387 var testResult1 = bar();
3388 if (testResult1) {
3389 __PS_MV_REG = [];
3390 return testResult1;
3391 } else {
3392 if (true) {
3393 __PS_MV_REG = [];
3394 return 456;
3397 })();")
3399 (test-ps-js let-no-body
3400 (defun foo ()
3401 (return-from foo (let ((foo bar)))))
3402 "function foo() {
3403 var foo1 = bar;
3404 return null;
3405 };")
3407 (test-ps-js rename-lexical-dupes
3408 (lambda ()
3409 (list (let ((foo 12)) (* foo 2))
3410 (let ((foo 13)) (* foo 3))))
3411 "function () {
3412 var foo;
3413 var foo1;
3414 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3415 };")
3417 (test-ps-js defun-comment1
3418 (defun foo (x)
3419 "BARBAR is a revolutionary new foobar.
3420 X y and x."
3421 (1+ x))
3422 "/**
3423 * BARBAR is a revolutionary new foobar.
3424 * X y and x.
3426 function foo(x) {
3427 return x + 1;
3428 };")
3430 (test-ps-js var-comment
3431 (var x 1 "foo")
3432 "/** foo */
3433 var x = 1;")
3435 (test-ps-js case-return-break-broken-return
3436 (defun foo ()
3437 (case x
3438 ("bar" (if y (return-from foo t) nil))
3439 ("baz" nil)))
3440 "function foo() {
3441 switch (x) {
3442 case 'bar':
3443 if (y) {
3444 return true;
3445 } else {
3446 return null;
3448 case 'baz':
3449 return null;
3451 };")
3453 (test-ps-js case-return-break1-broken-return
3454 (defun foo ()
3455 (case x
3456 ("bar" (if y (return-from foo t)))
3457 ("baz" nil)))
3458 "function foo() {
3459 switch (x) {
3460 case 'bar':
3461 if (y) {
3462 return true;
3463 } else {
3464 return null;
3466 case 'baz':
3467 return null;
3469 };")
3471 (test-ps-js setf-progn
3472 (setf foo (progn (bar) (baz) 3))
3473 "bar();
3474 baz();
3475 foo = 3;")
3477 (test-ps-js var-progn
3478 (var x (progn (foo) (bar)))
3479 "foo();
3480 var x = bar();")
3482 (test-ps-js implicit-return-loop
3483 (lambda ()
3484 (if baz 7
3485 (progn
3486 (loop :repeat 100 :do (bar))
3487 42)))
3488 "function () {
3489 if (baz) {
3490 return 7;
3491 } else {
3492 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3493 bar();
3495 __PS_MV_REG = [];
3496 return 42;
3498 };")
3500 (test-ps-js loop-closures
3501 (dotimes (i 10) (lambda () (+ i 1)))
3502 "(function () {
3503 for (var i = 0; i < 10; i += 1) {
3504 function () {
3505 return i + 1;
3508 })();")
3510 (test-ps-js loop-closures-let
3511 (dotimes (i 10)
3512 (let ((x (+ i 1)))
3513 (lambda () (+ i x))))
3514 "(function () {
3515 for (var i = 0; i < 10; i += 1) {
3516 (function () {
3517 var x = i + 1;
3518 return function () {
3519 return i + x;
3521 })();
3523 })();")
3525 (test-ps-js loop-closures-flet
3526 (dotimes (i 10)
3527 (flet ((foo (x) (+ i x)))
3528 (lambda () (foo i))))
3529 "(function () {
3530 for (var i = 0; i < 10; i += 1) {
3531 (function () {
3532 var foo = function (x) {
3533 return i + x;
3535 return function () {
3536 __PS_MV_REG = [];
3537 return foo(i);
3539 })();
3541 })();")
3543 (test-ps-js while-closures-let
3544 (loop while (foo) do
3545 (let ((abc (bar)))
3546 (lambda () (+ 1 abc))))
3547 "(function () {
3548 while (foo()) {
3549 (function () {
3550 var abc = bar();
3551 __PS_MV_REG = [];
3552 return function () {
3553 return 1 + abc;
3555 })();
3557 })();")
3559 (test-ps-js dotted-list-form
3560 (defun foo (a)
3561 (when a
3562 (destructuring-bind (b . c)
3564 (list b c))))
3565 "function foo(a) {
3566 if (a) {
3567 var b = bar[0];
3568 var c = bar.length > 1 ? bar.slice(1) : [];
3569 __PS_MV_REG = [];
3570 return [b, c];
3572 };")
3574 (test-ps-js explicit-nil-block
3575 (defun bar ()
3576 (foo 1)
3577 (block nil (return (foo 2)) (+ 1 2))
3579 "function bar() {
3580 foo(1);
3581 nilBlock: {
3582 __PS_MV_REG = [];
3583 foo(2);
3584 break nilBlock;
3585 1 + 2;
3587 __PS_MV_REG = [];
3588 return 2;
3589 };")
3591 (test-ps-js dynamic-extent-function-return
3592 (defun foo ()
3593 ((lambda ()
3594 (return-from foo 6))))
3595 "function foo() {
3596 try {
3597 __PS_MV_REG = [];
3598 return (function () {
3599 __PS_MV_REG = [];
3600 throw { '__ps_block_tag' : 'foo', '__ps_value' : 6 };
3601 })();
3602 } catch (_ps_err1) {
3603 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3604 return _ps_err1['__ps_value'];
3605 } else {
3606 throw _ps_err1;
3609 };")
3611 (test-ps-js dynamic-extent-function-return-nothing
3612 (defun foo ()
3613 ((lambda ()
3614 (return-from foo))))
3615 "function foo() {
3616 try {
3617 __PS_MV_REG = [];
3618 return (function () {
3619 __PS_MV_REG = [];
3620 throw { '__ps_block_tag' : 'foo', '__ps_value' : null };
3621 })();
3622 } catch (_ps_err1) {
3623 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3624 return _ps_err1['__ps_value'];
3625 } else {
3626 throw _ps_err1;
3629 };")
3631 (test-ps-js dynamic-extent-function-return-values
3632 (defun foo ()
3633 ((lambda ()
3634 (return-from foo (values 1 2 3)))))
3635 "function foo() {
3636 try {
3637 __PS_MV_REG = [];
3638 return (function () {
3639 var val1 = 1;
3640 __PS_MV_REG = [2, 3];
3641 throw { '__ps_block_tag' : 'foo',
3642 '__ps_value' : val1 };
3643 })();
3644 } catch (_ps_err2) {
3645 if (_ps_err2 && 'foo' === _ps_err2['__ps_block_tag']) {
3646 return _ps_err2['__ps_value'];
3647 } else {
3648 throw _ps_err2;
3651 };")
3653 (test-ps-js dynamic-extent-function-return-funcall
3654 (defun foo ()
3655 ((lambda ()
3656 (return-from foo (if baz 6 5)))))
3657 "function foo() {
3658 try {
3659 __PS_MV_REG = [];
3660 return (function () {
3661 __PS_MV_REG = [];
3662 throw { '__ps_block_tag' : 'foo', '__ps_value' : baz ? 6 : 5 };
3663 })();
3664 } catch (_ps_err1) {
3665 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3666 return _ps_err1['__ps_value'];
3667 } else {
3668 throw _ps_err1;
3671 };")
3673 (test-ps-js block-dynamic-return
3674 (defvar foo ((lambda ()
3675 (block nil
3676 ((lambda () (return 6)))
3677 (+ 1 2)))))
3678 "if ('undefined' === typeof foo) {
3679 var foo = (function () {
3680 try {
3681 (function () {
3682 __PS_MV_REG = [];
3683 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
3684 })();
3685 __PS_MV_REG = [];
3686 return 1 + 2;
3687 } catch (_ps_err1) {
3688 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3689 return _ps_err1['__ps_value'];
3690 } else {
3691 throw _ps_err1;
3694 })(); };")
3696 (test-ps-js iteration-lambda-capture-no-need
3697 (dolist (x y)
3698 (lambda (x) (1+ x)))
3699 "(function () {
3700 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3701 x = y[_js_idx1];
3702 function (x) {
3703 return x + 1;
3706 })();")
3708 (test-ps-js case-invert1
3709 (encodeURIComponent fooBar)
3710 "encodeURIComponent(fooBar);")
3712 (test-ps-js simple-ash
3713 (+ (ash 4 1) (ash 4 -1))
3714 "(4 << 1) + (4 >> 1);")
3716 (test-ps-js progn-nil-expression
3717 (bar (progn (foo) nil))
3718 "bar((foo(), null));")
3720 (test-ps-js other-progn-nil-exp
3721 (defun blah ()
3722 (or (foo) (progn (bar) nil)))
3723 "function blah() {
3724 __PS_MV_REG = [];
3725 return foo() || (bar(), null);
3726 };")
3728 (test-ps-js lambda-nil-return
3729 (lambda (x)
3730 (block nil
3731 (when x
3732 (return 1))
3734 "function (x) {
3735 if (x) {
3736 return 1;
3738 return 2;
3739 };")
3741 (test-ps-js lambda-nil-return-implicit-nested2
3742 (lambda (x)
3743 (block foo
3744 (if x
3745 (return-from foo 1)
3746 (dotimes (i 4)
3747 (return-from foo i)))
3749 "function (x) {
3750 if (x) {
3751 return 1;
3752 } else {
3753 for (var i = 0; i < 4; i += 1) {
3754 return i;
3757 return 2;
3758 };")
3760 (test-ps-js throw-is-a-statement
3761 (defun blah ()
3762 (let ((result (foo)))
3763 (unless (null result)
3764 (throw result))))
3765 "function blah() {
3766 var result = foo();
3767 if (result != null) {
3768 throw result;
3770 };")
3772 (test-ps-js expressify1
3773 (defun blah ()
3774 (when (some-condition)
3775 (foo)
3776 (bar)
3777 (baz)))
3778 "function blah() {
3779 if (someCondition()) {
3780 foo();
3781 bar();
3782 __PS_MV_REG = [];
3783 return baz();
3785 };")
3787 (test-ps-js case-when-return
3788 (defun blah (a)
3789 (case a
3790 ("a" (when (foo) (return-from blah 111)))
3791 ("b" t)))
3792 "function blah(a) {
3793 switch (a) {
3794 case 'a':
3795 if (foo()) {
3796 __PS_MV_REG = [];
3797 return 111;
3798 } else {
3799 __PS_MV_REG = [];
3800 return null;
3802 case 'b':
3803 __PS_MV_REG = [];
3804 return true;
3806 };")
3808 (test-ps-js flet-return-from
3809 (defun abc ()
3810 (flet ((foo ()
3811 (return-from foo 123)))
3812 (foo)))
3813 "function abc() {
3814 var foo = function () {
3815 return 123;
3817 __PS_MV_REG = [];
3818 return foo();
3819 };")
3821 (test-ps-js flet-return-from1
3822 (flet ((foo ()
3823 (return-from foo 123)))
3824 (foo))
3825 "(function () {
3826 var foo = function () {
3827 return 123;
3829 __PS_MV_REG = [];
3830 return foo();
3831 })();")
3833 (test-ps-js lambda-docstring-declarations
3834 (lambda (x)
3835 "This is a docstring"
3836 (declare (ignore x))
3838 "function (x) {
3839 return 2;
3840 };")
3842 (test-ps-js setf-let-exp
3843 (setf foo (let ((x (+ 1 2)))
3844 (if x 123 456)))
3845 "foo = (function () {
3846 var x = 1 + 2;
3847 return x ? 123 : 456;
3848 })();")
3850 (test-ps-js create-let-exp
3851 (create :abc (let ((x (+ 1 2)))
3852 (if x 123 456)))
3853 "{ 'abc' : (function () {
3854 var x = 1 + 2;
3855 return x ? 123 : 456;
3856 })() };")
3858 (test-ps-js eql-eql-eql-precedence
3859 (unless (equal (= 3 3) (= 3 4))
3860 (chain console (log 1)))
3861 "if ((3 === 3) != (3 === 4)) {
3862 console.log(1);
3863 };")
3865 (test-ps-js case-cond-breaks
3866 (defun blah (x)
3867 (case x
3868 (123 (cond ((foo1)
3869 (when (foo2)
3870 (when (foo3)
3871 (return-from blah nil))
3872 t))))
3873 (456 (foo7))))
3874 "function blah(x) {
3875 switch (x) {
3876 case 123:
3877 if (foo1()) {
3878 if (foo2()) {
3879 if (foo3()) {
3880 __PS_MV_REG = [];
3881 return null;
3883 __PS_MV_REG = [];
3884 return true;
3885 } else {
3886 __PS_MV_REG = [];
3887 return null;
3889 } else {
3890 __PS_MV_REG = [];
3891 return null;
3893 case 456:
3894 __PS_MV_REG = [];
3895 return foo7();
3897 };")
3899 (test-ps-js cond-double-t
3900 (lambda ()
3901 (cond (foo 1)
3902 (t 2)
3903 (t 3)))
3904 "function () {
3905 if (foo) {
3906 return 1;
3907 } else {
3908 return 2;
3910 };")
3912 (test-ps-js let-let-funcall-lambda
3913 (let ((x 5))
3914 (let ((x 7))
3915 (funcall (lambda (x) (+ x 9)) x)))
3916 "(function () {
3917 var x = 5;
3918 var x1 = 7;
3919 return (function (x) {
3920 return x + 9;
3921 })(x1);
3922 })();")
3924 (test-ps-js let-let-lambda
3925 (let ((x 5))
3926 (let ((x 7))
3927 (lambda (x) (+ x 9))))
3928 "(function () {
3929 var x = 5;
3930 var x1 = 7;
3931 return function (x) {
3932 return x + 9;
3934 })();")
3936 (test-ps-js let-lambda
3937 (let ((x 5))
3938 (lambda (x) (+ x 9)))
3939 "(function () {
3940 var x = 5;
3941 return function (x) {
3942 return x + 9;
3944 })();")
3946 (test-ps-js symbol-macrolet-no-shadow-lambda
3947 (symbol-macrolet ((x y))
3948 (lambda (x) (+ x x)))
3949 "function (x) {
3950 return x + x;
3951 };")
3953 (test-ps-js divide-one-arg-reciprocal
3954 (/ 2)
3955 "1 / 2;")
3957 (test-ps-js division-not-associative
3958 (/ a (* b c))
3959 "a / (b * c);")
3961 (test-ps-js divide-expressions
3962 (/ (foo) (bar))
3963 "foo() / bar();")
3965 (test-ps-js divide-expressions1
3966 (floor (1- x) y)
3967 "Math.floor((x - 1) / y);")
3969 (test-ps-js lexical-funargs-shadow1
3970 (lambda (x)
3971 (let ((x 1))
3972 (foo x))
3973 (incf x))
3974 "function (x) {
3975 var x1 = 1;
3976 foo(x1);
3977 __PS_MV_REG = [];
3978 return ++x;
3979 };")
3981 (test-ps-js times-rem
3982 (* x (rem y z))
3983 "x * (y % z);")
3985 (test-ps-js rem-divide
3986 (/ x (rem y z))
3987 "x / (y % z);")
3989 (test-ps-js case-break-return
3990 (lambda () (case x (:foo) (:bar 1)))
3991 "function () {
3992 switch (x) {
3993 case 'foo':
3994 return null;
3995 case 'bar':
3996 return 1;
3998 };")
4000 (test-ps-js trivial-expression-switch
4001 (foobar (case x (1 2)))
4002 "foobar((function () {
4003 switch (x) {
4004 case 1:
4005 return 2;
4007 })());")
4009 (test-ps-js trivial-expression-while
4010 (foobar (loop while (< 0 x) do (decf x)))
4011 "foobar((function () {
4012 while (0 < x) {
4013 --x;
4015 })());")
4017 (test-ps-js funcall-block-expression-loop-lambda
4018 (foobar (loop for i from 0 to 10 do (1+ i)))
4019 "foobar((function () {
4020 for (var i = 0; i <= 10; i += 1) {
4021 i + 1;
4023 })());")
4025 (test-ps-js plus-block-expression-loop-lambda
4026 (1+ (loop for i from 0 to 10 do (1+ i)))
4027 "(function () {
4028 for (var i = 0; i <= 10; i += 1) {
4029 i + 1;
4031 })() + 1;")
4033 (test-ps-js let-closures-rename
4034 (lambda ()
4035 (let ((x 1)) (lambda () (1+ x)))
4036 (let ((x 2)) (lambda () (1+ x))))
4037 "function () {
4038 var x = 1;
4039 function () {
4040 return x + 1;
4042 var x1 = 2;
4043 return function () {
4044 return x1 + 1;
4046 };")
4048 (test-ps-js let-closures-rename1
4049 (lambda ()
4050 (let ((x 1))
4051 (let ((y 2))
4052 (lambda () (+ x y))))
4053 (let ((x 2))
4054 (let ((y 3))
4055 (lambda () (+ x y)))))
4056 "function () {
4057 var x = 1;
4058 var y = 2;
4059 function () {
4060 return x + y;
4062 var x1 = 2;
4063 var y2 = 3;
4064 return function () {
4065 return x1 + y2;
4067 };")
4069 (test-ps-js let-closures-rename2
4070 (defun make-closures ()
4071 (list
4072 (let ((x 1)) (lambda () (1+ x)))
4073 (let ((x 2)) (lambda () (1+ x)))))
4074 "function makeClosures() {
4075 var x;
4076 var x1;
4077 return [(x = 1, function () {
4078 return x + 1;
4079 }), (x1 = 2, function () {
4080 return x1 + 1;
4081 })];
4083 };")
4085 (test-ps-js conditional-not-used-up
4086 (lambda (bar)
4087 (when bar
4088 (let ((x 1))
4089 (1+ x))))
4090 "function (bar) {
4091 if (bar) {
4092 var x = 1;
4093 return x + 1;
4095 };")
4097 (test-ps-js toplevel-local-scope
4098 (create "fn" (let ((x 5)) (lambda () x)))
4099 "{ 'fn' : (function () {
4100 var x = 5;
4101 return function () {
4102 return x;
4104 })() };")
4106 (test-ps-js toplevel-local-scope1
4107 (defparameter foo (create "fn" (let ((x 5)) (lambda () x))))
4108 "var foo = { 'fn' : (function () {
4109 var x = 5;
4110 return function () {
4111 return x;
4113 })() };")
4115 (test-ps-js block-let
4116 (block foobar
4117 (let ((x 1))
4118 (return-from foobar x)
4120 "(function () {
4121 var x = 1;
4122 return x;
4123 return 2;
4124 })();")
4126 (test-ps-js expressionize-if-macroexpand-error
4127 (progn (defmacro xbaz () `(blah))
4129 (defun foo (xbaz)
4130 (unless (blah)
4131 (cond (xbaz (blah))
4132 (t (blahblah))))))
4133 "function foo(xbaz) {
4134 if (!blah()) {
4135 if (xbaz) {
4136 __PS_MV_REG = [];
4137 return blah();
4138 } else {
4139 __PS_MV_REG = [];
4140 return blahblah();
4143 };")
4145 (test-ps-js toplevel-defun-macroexpand
4146 (progn (defmacro defun-js (name lambda-list &body body)
4147 `(defun ,name ,lambda-list ,@body))
4149 (let ((foo 0))
4150 (defun-js bar () (1+ foo))
4151 (defvar baz 2)))
4152 "var foo = 0;
4153 function bar() {
4154 return foo + 1;
4156 if ('undefined' === typeof baz) { var baz = 2; };")
4158 (test-ps-js js-ir-package-unique-symbols
4159 (loop :for i :from 0 :below 5 :do
4160 (let ((block (elt blocks i)))
4161 (foo block)
4162 (lambda () nil)))
4163 "(function () {
4164 for (var i = 0; i < 5; i += 1) {
4165 var block = blocks[i];
4166 foo(block);
4167 function () {
4168 return null;
4171 })();")
4173 (test-ps-js broken-quote-expansion1
4174 (lambda (p)
4175 (with-slots (x y) p
4176 (if (< x 0) y x)))
4177 "function (p) {
4178 return p.x < 0 ? p.y : p.x;
4179 };")
4181 (test-ps-js broken-quote-expansion2
4182 (progn
4183 (define-symbol-macro foo123 (ps:@ a foo123))
4184 (lambda () (when (> foo123 1) 2)))
4185 "function () {
4186 return a.foo123 > 1 ? 2 : null;
4187 };")
4189 (test-ps-js unused-named-block-not-printed1
4190 (block foobar
4191 (+ 1 2 3))
4192 "(function () {
4193 return 1 + 2 + 3;
4194 })();")
4196 (test-ps-js unused-named-block-not-printed2
4197 (block nil
4198 (block nil
4199 (+ 1 2 3)))
4200 "(function () {
4201 return 1 + 2 + 3;
4202 })();")
4204 (test-ps-js unused-named-block-not-printed3
4205 (block foobar
4206 (block nil
4207 (+ 1 2 3)))
4208 "(function () {
4209 return 1 + 2 + 3;
4210 })();")
4212 (test-ps-js unused-named-block-not-printed4
4213 (block nil
4214 (block foobar
4215 (block nil
4216 (+ 1 2 3))))
4217 "(function () {
4218 return 1 + 2 + 3;
4219 })();")
4221 (test-ps-js trig-no-bind1
4222 (cosh 3.14)
4223 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4225 (test-ps-js trig-bind1
4226 (acosh (blah 3.14))
4227 "(function () {
4228 var x1 = blah(3.14);
4229 __PS_MV_REG = [];
4230 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4231 })();")
4233 (test-ps-js double-negation
4234 (or (not foo) (not (not foo)) (not (not (not foo))))
4235 "!foo || foo || !foo;")
4237 (test-ps-js empty-let
4238 (defun foo ()
4239 (let ((a (bar)))))
4240 "function foo() {
4241 var a = bar();
4242 __PS_MV_REG = [];
4243 return null;
4244 };")
4246 (test-ps-js empty-let*
4247 (defun foo ()
4248 (let* ((a (bar)))))
4249 "function foo() {
4250 var a = bar();
4251 __PS_MV_REG = [];
4252 return null;
4253 };")
4255 (test-ps-js defun-no-body-declare
4256 (defun foo () (declare (ignore x)))
4257 "function foo() {
4258 return null;
4259 };")
4261 (test-ps-js defun-no-body-let-declare
4262 (defun foo () (let () (declare (ignore x))))
4263 "function foo() {
4264 return null;
4265 };")
4267 (test-ps-js empty-defun-docstring-declare
4268 (defun foo (x)
4269 "docstring"
4270 (declare (ignore x)))
4271 "/** docstring */
4272 function foo(x) {
4273 return null;
4274 };")
4276 (test-ps-js defun-docstring-string
4277 (defun foo (x)
4278 "docstring"
4279 "abc")
4280 "/** docstring */
4281 function foo(x) {
4282 return 'abc';
4283 };")
4285 (test-ps-js return-object
4286 (defun foo (obj)
4287 (ps:create :abc (let ((x (ps:getprop obj "blah")))
4288 (if x 123 456))))
4289 "function foo(obj) {
4290 var x;
4291 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4292 };")
4294 (test-ps-js unicode-strings
4295 "фоо бар"
4296 "'фоо бар';")
4298 (test-ps-js expressionize-return
4299 (defun next-page (self)
4300 (with-slots (limit offset count)
4301 (@ self state)
4302 (when (and count (< (* limit offset) count))
4303 (set-state self (create x (+ offset 1))))))
4304 "function nextPage(self) {
4305 var object1 = self.state;
4306 __PS_MV_REG = [];
4307 return object1.count && object1.limit * object1.offset < object1.count ? setState(self, { x : object1.offset + 1 }) : null;
4308 };")
4310 (test-ps-js let-defun-toplevel
4311 (progn (let ((foo 0))
4312 (defun bar () foo))
4313 (bar))
4314 "var foo = 0;
4315 function bar() {
4316 return foo;
4318 bar();")
4320 (test-ps-js let-defvar-toplevel
4321 (progn (let ((foo 0))
4322 (defvar bar (1+ foo)))
4323 bar)
4324 "var foo = 0;
4325 if ('undefined' === typeof bar) { var bar = foo + 1; };
4326 bar;")
4328 (test-ps-js setf-side-effects
4329 (let ((x 10))
4330 (defun side-effect()
4331 (setf x 4)
4333 (setf x (+ 2 (side-effect) x 5)))
4334 "var x = 10;
4335 function sideEffect() {
4336 x = 4;
4337 return 3;
4339 x = 2 + sideEffect() + x + 5;")
4341 (test-ps-js stupid-lisp-trick
4342 (alert
4343 (lisp
4344 (progn
4345 (write-string "[1,2,3]" ps::*psw-stream*)
4346 (values))))
4347 "alert([1,2,3]);")
4349 (test-ps-js maybe-once-only-symbol-macrolet
4350 (symbol-macrolet ((x (call-me-once)))
4351 (sinh x))
4353 "(function () {
4354 var x1 = callMeOnce();
4355 __PS_MV_REG = [];
4356 return (Math.exp(x1) - Math.exp(-x1)) / 2;
4357 })();")
4359 (test-ps-js maybe-once-only-symbol-macro
4360 (progn
4361 (define-symbol-macro maybe-once-only-symbol-macro (call-me-once))
4362 (tanh maybe-once-only-symbol-macro))
4364 "(function () {
4365 var x1 = callMeOnce();
4366 __PS_MV_REG = [];
4367 return (Math.exp(x1) - Math.exp(-x1)) / (Math.exp(x1) + Math.exp(-x1));
4368 })();")
4370 (test-ps-js maybe-once-only-evaluation-order
4371 (macrolet
4372 ((A (x y)
4373 (maybe-once-only (x y)
4374 `(+ ,x ,x ,y ,y))))
4375 (A (fun1) (fun2)))
4376 "(function () {
4377 var x1 = fun1();
4378 var y2 = fun2();
4379 __PS_MV_REG = [];
4380 return x1 + x1 + y2 + y2;
4381 })();")
4383 (test-ps-js maybe-once-only-macroexpansion
4384 (macrolet
4385 ((A (x y)
4386 (ps:maybe-once-only (x y)
4387 `(+ ,x ,x ,y ,y)))
4388 (fun1 () 'G)
4389 (fun2 () 6))
4390 (A (fun1) (fun2)))
4391 "G + G + 6 + 6;")
4393 (test-ps-js lambda-block-wrap-for-dynamic-return
4394 (lambda ()
4395 (block X
4396 ((lambda ()
4397 ((lambda ()
4398 (return-from X 1)))
4399 2)))
4401 "function () {
4402 X: {
4403 try {
4404 (function () {
4405 (function () {
4406 __PS_MV_REG = [];
4407 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4408 })();
4409 __PS_MV_REG = [];
4410 return 2;
4411 })();
4412 } catch (_ps_err1) {
4413 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4414 _ps_err1['__ps_value'];
4415 break X;
4416 } else {
4417 throw _ps_err1;
4421 __PS_MV_REG = [];
4422 return 5;
4423 };")
4425 (test-ps-js lambda-progn-block
4426 (lambda ()
4427 (progn
4428 (block X
4429 (lambda ()
4430 (return-from X 1)))))
4431 "function () {
4432 try {
4433 return function () {
4434 __PS_MV_REG = [];
4435 throw { '__ps_block_tag' : 'X', '__ps_value' : 1 };
4437 } catch (_ps_err1) {
4438 if (_ps_err1 && 'X' === _ps_err1['__ps_block_tag']) {
4439 return _ps_err1['__ps_value'];
4440 } else {
4441 throw _ps_err1;
4444 };")
4446 (test-ps-js defun-when-if-return
4447 (defun foobar ()
4448 (when (bar)
4449 (loop if (foo) return 10)))
4450 "function foobar() {
4451 if (bar()) {
4452 while (true) {
4453 if (foo()) {
4454 __PS_MV_REG = [];
4455 return 10;
4459 };")
4461 (test-ps-js block-block-return-from-toplevel
4462 (block bar
4463 (block foo
4464 (return-from foo 10)))
4465 "(function () {
4466 return 10;
4467 })();")
4469 ;;; Stuff to fix. Not necessarily wrong, but redundant/could be better
4471 (test-ps-js block-dynamic-return1-redundant
4472 (defparameter foo
4473 ((lambda ()
4474 (block nil
4475 ((lambda () (return 6)))
4476 (+ 1 2))
4477 (+ 4 5))))
4478 ;;; FIXME. Not wrong, but redundant
4479 "var foo = (function () {
4480 nilBlock: {
4481 try {
4482 (function () {
4483 __PS_MV_REG = [];
4484 throw { '__ps_block_tag' : 'nilBlock', '__ps_value' : 6 };
4485 })();
4486 1 + 2;
4487 } catch (_ps_err1) {
4488 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
4489 _ps_err1['__ps_value'];
4490 break nilBlock;
4491 } else {
4492 throw _ps_err1;
4496 __PS_MV_REG = [];
4497 return 4 + 5;
4498 })();")
4500 (test-ps-js block-gratuitous-dynamic-return
4501 (block foo
4502 (block bar
4503 (block nil
4504 (return-from bar 10)))
4505 (foo))
4506 "(function () {
4507 bar: {
4508 try {
4509 __PS_MV_REG = [];
4510 throw { '__ps_block_tag' : 'bar', '__ps_value' : 10 };
4511 } catch (_ps_err1) {
4512 if (_ps_err1 && 'bar' === _ps_err1['__ps_block_tag']) {
4513 _ps_err1['__ps_value'];
4514 break bar;
4515 } else {
4516 throw _ps_err1;
4520 __PS_MV_REG = [];
4521 return foo();
4522 })();")
4524 (test-ps-js for-loop-var-init-let
4525 (lambda (y)
4526 (ps:for
4527 ((x (let ((x0 (foo y)))
4528 (bar x0))))
4529 () ()
4530 (xyzzy x)))
4531 "function (y) {
4532 var x0;
4533 for (var x = (x0 = foo(y), bar(x0)); ; ) {
4534 xyzzy(x);
4536 };")