Better output of Unicode strings
[parenscript.git] / tests / output-tests.lisp
blob93129f9263510b24fb7813be6cb832cb94a62884
1 ;;; Copyright 2005-2006 Henrik Hjelte
2 ;;; Copyright 2007-2012 Vladimir Sedach
4 ;;; SPDX-License-Identifier: BSD-3-Clause
6 ;;; Redistribution and use in source and binary forms, with or
7 ;;; without modification, are permitted provided that the following
8 ;;; conditions are met:
10 ;;; 1. Redistributions of source code must retain the above copyright
11 ;;; notice, this list of conditions and the following disclaimer.
13 ;;; 2. Redistributions in binary form must reproduce the above
14 ;;; copyright notice, this list of conditions and the following
15 ;;; disclaimer in the documentation and/or other materials provided
16 ;;; with the distribution.
18 ;;; 3. Neither the name of the copyright holder nor the names of its
19 ;;; contributors may be used to endorse or promote products derived
20 ;;; from this software without specific prior written permission.
22 ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 ;;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 ;;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 ;;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 ;;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
27 ;;; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 ;;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 ;;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 ;;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
31 ;;; ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 ;;; OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 ;;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 ;;; POSSIBILITY OF SUCH DAMAGE.
36 (in-package #:parenscript.tests)
37 (named-readtables:in-readtable :parenscript)
39 (fiveam:in-suite output-tests)
41 (test-ps-js statements-and-expressions-1
42 (+ i (if 1 2 3))
43 "i + (1 ? 2 : 3);")
45 (test-ps-js statements-and-expressions-2
46 (if 1 2 3)
47 "if (1) {
49 } else {
51 };")
53 (test-ps-js symbol-conversion-1
54 !?#@%
55 "bangwhathashatpercent;")
57 (test-ps-js symbol-conversion-2
58 bla-foo-bar
59 "blaFooBar;")
61 (test-ps-js symbol-conversion-3
62 *array
63 "Array;")
65 (test-ps-js symbol-conversion-4
66 *global-array*
67 "GLOBALARRAY;")
69 (test-ps-js symbol-conversion-5
70 encodeURIComponent
71 "encodeURIComponent;")
73 (test-ps-js symbol-conversion-6
74 URI
75 "URI;")
77 (test-ps-js number-literals-1
79 "1;")
81 (test-ps-js number-literals-2
82 123.123
83 "123.123;")
85 (test-ps-js number-literals-3
86 #x10
87 "16;")
89 (test-ps-js string-literals-1
90 "foobar"
91 "'foobar';")
93 (test-ps-js string-literals-2
94 "bratzel bub"
95 "'bratzel bub';")
97 (test-ps-js string-literals-3
98 " "
99 "'\\t';")
101 (test-ps-js array-literals-1
102 (array)
103 "[];")
105 (test-ps-js array-literals-2
106 (array 1 2 3)
107 "[1, 2, 3];")
109 (test-ps-js array-literals-3
110 (array (array 2 3)
111 (array "foobar" "bratzel bub"))
112 "[[2, 3], ['foobar', 'bratzel bub']];")
114 (test-ps-js array-literals-4
115 (make-array)
116 "new Array();")
118 (test-ps-js array-literals-5
119 (make-array 1 2 3)
120 "new Array(1, 2, 3);")
122 (test-ps-js array-literals-6
123 (make-array
124 (make-array 2 3)
125 (make-array "foobar" "bratzel bub"))
126 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
128 (test-ps-js array-init-1
129 (make-array 2 :initial-contents '(10 20))
130 "(function () {
131 var arr1 = new Array(2);
132 var init2 = [10, 20];
133 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
134 arr1[i4] = init2[i4];
136 return arr1;
137 })();")
139 (test-ps-js array-init-2
140 (make-array 5 :initial-element 10)
141 "(function () {
142 var arr1 = new Array(5);
143 var elt3 = 10;
144 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
145 arr1[i4] = elt3;
147 return arr1;
148 })();")
150 (test-ps-js object-literals-1
151 (create foo "bar" :blorg 1)
152 "({ foo : 'bar', 'blorg' : 1 });")
154 (test-ps-js object-literals-2
155 (create foo "hihi"
156 blorg (array 1 2 3)
157 another-object (create :schtrunz 1))
158 "({ foo : 'hihi',
159 blorg : [1, 2, 3],
160 anotherObject : { 'schtrunz' : 1 } });")
162 (test-ps-js object-literals-3
163 (getprop an-object 'foo)
164 "anObject.foo;")
166 (test-ps-js object-literals-4
167 (@ an-object foo bar)
168 "anObject.foo.bar;")
170 (test-ps-js object-literals-5
171 (with-slots (a b c) this
172 (+ a b c))
173 "this.a + this.b + this.c;")
175 (test-ps-js with-slots-single-eval
176 (lambda () (with-slots (a b) (foo) (+ a b)))
177 "(function () {
178 var object1 = foo();
179 return object1.a + object1.b;
180 });")
182 (test-ps-js object-literal-quoted-symbols
183 (create 'test "bang" 'symbol-saved-my-life "parenscript")
184 "({ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' });")
186 (test-ps-js object-literal-property-accessors
187 (defun foo ()
188 (let ((x 10))
189 (create (get x) x
190 (set x v) (setf x v))))
191 "function foo() {
192 var x = 10;
193 return { get x() {
194 return x;
195 }, set x(v) {
196 return x = v;
197 } };
199 :js-target-version "1.8.5")
201 (test-ps-js object-method-apply-1
202 (apply (@ an-object foo) nil)
203 "anObject.foo.apply(anObject, null);")
205 (test-ps-js object-method-apply-2
206 (apply (getprop (make-an-object) foo 'bar) nil)
207 "(function () {
208 var _js1 = makeAnObject()[foo];
209 var _js2 = _js1.bar;
210 return _js2.apply(_js1, null);
211 })();")
213 (test-ps-js object-method-apply-3
214 (apply (@ (make-an-object) foo) (bar))
215 "(function () {
216 var _js1 = makeAnObject();
217 var _js2 = _js1.foo;
218 return _js2.apply(_js1, bar());
219 })();")
221 (test-ps-js regular-expression-literals-1
222 (regex "foobar")
223 "/foobar/;")
225 (test-ps-js regular-expression-literals-2
226 (regex "/foobar/i")
227 "/foobar/i;")
229 (test-ps-js literal-symbols-1
231 "true;")
233 (test-ps-js literal-symbols-2
234 false
235 "false;")
237 (test-ps-js literal-symbols-3
239 "false;")
241 (test-ps-js literal-symbols-4
242 (lambda () nil)
243 "(function () {
244 return null;
245 });")
247 (test-ps-js literal-symbols-5
248 undefined
249 "undefined;")
251 (test-ps-js literal-symbols-6
252 this
253 "this;")
255 (test-ps-js variables-1
256 variable
257 "variable;")
259 (test-ps-js variables-2
260 a-variable
261 "aVariable;")
263 (test-ps-js variables-3
264 *math
265 "Math;")
267 (test-ps-js function-calls-and-method-calls-1
268 (blorg 1 2)
269 "blorg(1, 2);")
271 (test-ps-js function-calls-and-method-calls-2
272 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
273 "foobar(blorg(1, 2), blabla(3, 4), [2, 3, 4]);")
275 (test-ps-js function-calls-and-method-calls-3
276 ((getprop this 'blorg) 1 2)
277 "this.blorg(1, 2);")
279 (test-ps-js function-calls-and-method-calls-4
280 ((aref foo i) 1 2)
281 "foo[i](1, 2);")
283 (test-ps-js function-calls-and-method-calls-5
284 ((getprop (aref foobar 1) 'blorg) nil t)
285 "foobar[1].blorg(null, true);")
287 (test-ps-js operator-expressions-1
288 (* 1 2)
289 "1 * 2;")
291 (test-ps-js operator-expressions-2
292 (= 1 2)
293 "1 === 2;")
295 (test-ps-js operator-expressions-3
296 (* 1 (+ 2 3 4) 4 (/ 6 7))
297 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
299 (test-ps-js operator-expressions-4
300 (incf i)
301 "++i;")
303 (test-ps-js operator-expressions-5
304 (decf i)
305 "--i;")
307 (test-ps-js operator-expressions-6
308 (1- i)
309 "i - 1;")
311 (test-ps-js operator-expressions-7
312 (1+ i)
313 "i + 1;")
315 (test-ps-js operator-expressions-8
316 (not (< i 2))
317 "i >= 2;")
319 (test-ps-js body-forms-1
320 (progn (blorg i) (blafoo i))
321 "blorg(i);
322 blafoo(i);")
324 (test-ps-js body-forms-2
325 (+ i (progn (blorg i) (blafoo i)))
326 "i + (blorg(i), blafoo(i));")
328 (test-ps-js function-definition-1
329 (defun a-function (a b)
330 (+ a b))
331 "function aFunction(a, b) {
332 return a + b;
333 };")
335 (test-ps-js lambda-definition-2
336 (lambda (a b) (+ a b))
337 "(function (a, b) {
338 return a + b;
339 });")
341 (test-ps-js assignment-1
342 (setf a 1)
343 "a = 1;")
345 (test-ps-js assignment-2
346 (setf a 2 b 3 c 4 x (+ a b c))
347 "a = 2;
348 b = 3;
349 c = 4;
350 x = a + b + c;")
352 (test-ps-js assignment-3
353 (setf a (+ a 2 3 4 a))
354 "a = a + 2 + 3 + 4 + a;")
356 (test-ps-js assignment-4
357 (setf a (- 1 a))
358 "a = 1 - a;")
360 (test-ps-js assignment-5
361 (let ((a 1) (b 2))
362 (psetf a b b a))
363 "(function () {
364 var a = 1;
365 var b = 2;
366 var _js3 = b;
367 var _js4 = a;
368 a = _js3;
369 return b = _js4;
370 })();")
372 (test-ps-js assignment-6
373 (setq a 1)
374 "a = 1;")
376 (test-ps-js assignment-8
377 (progn
378 (defun (setf color) (new-color el)
379 (setf (getprop (getprop el 'style) 'color) new-color))
380 (setf (color some-div) (+ 23 "em")))
381 "function __setf_color(newColor, el) {
382 return el.style.color = newColor;
384 __setf_color(23 + 'em', someDiv);")
386 (test-ps-js assignment-10
387 (progn
388 (defsetf left (el) (offset)
389 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
390 (setf (left some-div) (+ 123 "px")))
391 "(function () {
392 var _js2 = someDiv;
393 var _js1 = 123 + 'px';
394 return _js2.style.left = _js1;
395 })();")
397 (test-ps-js assignment-12
398 (macrolet ((left (el)
399 `(getprop ,el 'offset-left)))
400 (left some-div))
401 "someDiv.offsetLeft;")
403 (test-ps-js nil-block-return-1
404 (block nil (return) 1)
405 "(function () {
406 return null;
407 return 1;
408 })();")
410 (test-ps-js single-argument-statements-2
411 (throw "foobar")
412 "throw 'foobar';")
414 (test-ps-js single-argument-expression-1
415 (delete (new (*foobar 2 3 4)))
416 "delete new Foobar(2, 3, 4);")
418 (test-ps-js single-argument-expression-2
419 (if (= (typeof blorg) *string)
420 (alert (+ "blorg is a string: " blorg))
421 (alert "blorg is not a string"))
422 "if (typeof blorg === String) {
423 alert('blorg is a string: ' + blorg);
424 } else {
425 alert('blorg is not a string');
426 };")
428 (test-ps-js conditional-statements-1
429 (defun foo ()
430 (if ((@ blorg is-correct))
431 (progn (carry-on) (return-from foo i))
432 (alert "blorg is not correct!")))
433 "function foo() {
434 if (blorg.isCorrect()) {
435 carryOn();
436 return i;
437 } else {
438 return alert('blorg is not correct!');
440 };")
442 (test-ps-js conditional-statements-2
443 (+ i (if ((@ blorg add-one)) 1 2))
444 "i + (blorg.addOne() ? 1 : 2);")
446 (test-ps-js conditional-statements-3
447 (defun foo ()
448 (when ((@ blorg is-correct))
449 (carry-on)
450 (return-from foo i)))
451 "function foo() {
452 if (blorg.isCorrect()) {
453 carryOn();
454 return i;
456 };")
458 (test-ps-js conditional-statements-4
459 (unless ((@ blorg is-correct))
460 (alert "blorg is not correct!"))
461 "if (!blorg.isCorrect()) {
462 alert('blorg is not correct!');
463 };")
465 (test-ps-js variable-declaration-1
466 (defvar *a* (array 1 2 3))
467 "var A = [1, 2, 3];")
469 (test-ps-js variable-declaration-2
470 (progn (defvar *a* 4)
471 (let ((x 1)
472 (*a* 2))
473 (let* ((y (+ x 1))
474 (x (+ x y)))
475 (+ *a* x y))))
476 "var A = 4;
477 (function () {
478 var x = 1;
479 var A_TMPSTACK1;
480 try {
481 A_TMPSTACK1 = A;
482 A = 2;
483 var y = x + 1;
484 var x2 = x + y;
485 return A + x2 + y;
486 } finally {
487 A = A_TMPSTACK1;
489 })();")
491 (test-ps-js iteration-constructs-1
492 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
493 (d 0 (1+ d))
494 (e (aref c d) (aref c d)))
495 ((or (= d (@ c length)) (string= e "x")))
496 (setf a d b e)
497 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
498 "(function () {
499 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
500 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
501 a = d;
502 b = e;
503 document.write('a: ' + a + ' b: ' + b + '<br/>');
505 })();")
507 (test-ps-js iteration-constructs-2
508 (do ((i 0 (1+ i))
509 (s 0 (+ s i (1+ i))))
510 ((> i 10))
511 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
512 "(function () {
513 var i = 0;
514 var s = 0;
515 for (; i <= 10; ) {
516 document.write('i: ' + i + ' s: ' + s + '<br/>');
517 var _js1 = i + 1;
518 var _js2 = s + i + (i + 1);
519 i = _js1;
520 s = _js2;
522 })();")
524 (test-ps-js iteration-constructs-3
525 (do* ((i 0 (1+ i))
526 (s 0 (+ s i (1- i))))
527 ((> i 10))
528 ((@ document write) (+ "i: " i " s: " s "<br/>")))
529 "(function () {
530 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
531 document.write('i: ' + i + ' s: ' + s + '<br/>');
533 })();")
535 (test-ps-js iteration-constructs-4
536 (let ((arr (array "a" "b" "c" "d" "e")))
537 (dotimes (i (@ arr length))
538 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
539 "(function () {
540 var arr = ['a', 'b', 'c', 'd', 'e'];
541 for (var i = 0; i < arr.length; i += 1) {
542 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
544 })();")
546 (test-ps-js iteration-constructs-5
547 (let ((res 0))
548 (alert (+ "Summation to 10 is "
549 (dotimes (i 10 res)
550 (incf res (1+ i))))))
551 "(function () {
552 var res = 0;
553 return alert('Summation to 10 is ' + (function () {
554 for (var i = 0; i < 10; i += 1) {
555 res += i + 1;
557 return res;
558 })());
559 })();")
561 (test-ps-js iteration-constructs-6
562 (let ((l (list 1 2 4 8 16 32)))
563 (dolist (c l)
564 ((@ document write) (+ "c: " c "<br/>"))))
565 "(function () {
566 var l = [1, 2, 4, 8, 16, 32];
567 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
568 c = l[_js_idx2];
569 document.write('c: ' + c + '<br/>');
571 })();")
573 (test-ps-js iteration-constructs-7
574 (let ((l '(1 2 4 8 16 32))
575 (s 0))
576 (alert (+ "Sum of " l " is: "
577 (dolist (c l s)
578 (incf s c)))))
579 "(function () {
580 var l = [1, 2, 4, 8, 16, 32];
581 var s = 0;
582 return alert('Sum of ' + l + ' is: ' + (function () {
583 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
584 c = l[_js_idx1];
585 s += c;
587 return s;
588 })());
589 })();")
591 (test-ps-js iteration-constructs-8
592 (let ((obj (create a 1 b 2 c 3)))
593 (for-in (i obj)
594 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
595 "(function () {
596 var obj = { a : 1, b : 2, c : 3 };
597 for (var i in obj) {
598 document.write(i + ': ' + obj[i] + '<br/>');
600 })();")
602 (test-ps-js iteration-constructs-9
603 (while ((@ film is-not-finished))
604 ((@ this eat) (new *popcorn)))
605 "while (film.isNotFinished()) {
606 this.eat(new Popcorn);
607 };")
609 (test-ps-js loop-for-bindings
610 (loop :for ((a b) (:c :d)) :in arr :do (foo a b c d))
611 "(function () {
612 var _js2 = arr.length;
613 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
614 var _db4 = arr[_js1];
615 var _db5 = _db4[0];
616 var a = _db5[0];
617 var b = _db5[1];
618 var _js3 = _db4[1];
619 var c = _js3['c'];
620 var d = _js3['d'];
621 foo(a, b, c, d);
623 })();")
625 (test-ps-js loop-for-on
626 (loop :for (k v) :on plist :by 2 :do (foo k v))
627 "(function () {
628 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
629 var k = _js1[0];
630 var v = _js1[1];
631 foo(k, v);
633 })();")
635 (test-ps-js loop-for-keys-of
636 (loop :for k :of obj :do (foo k))
637 "(function () {
638 for (var k in obj) {
639 foo(k);
641 })();")
643 (test-ps-js loop-for-key-val-pairs-of
644 (loop :for (k v) :of obj :do (foo k v))
645 "(function () {
646 for (var k in obj) {
647 var v = obj[k];
648 foo(k, v);
650 })();")
652 (test-ps-js loop-for-key-val-pairs-of-with-bindings
653 (loop :for (k (a b)) :of obj :do (foo k a b))
654 "(function () {
655 for (var k in obj) {
656 var _db1 = obj[k];
657 var a = _db1[0];
658 var b = _db1[1];
659 foo(k, a, b);
661 })();")
663 (test-ps-js loop-for-just-vals-of
664 (loop :for (nil v) :of obj :do (foo k v))
665 "(function () {
666 for (var _js1 in obj) {
667 var v = obj[_js1];
668 foo(k, v);
670 })();")
672 (test-ps-js loop-map-to
673 (loop :for str :in strs :map str :to (length str))
674 "(function () {
675 var _js2 = strs.length;
676 var map3 = { };
677 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
678 var str = strs[_js1];
679 map3[str] = str.length;
681 return map3;
682 })();")
684 (test-ps-js loop-for-of-map-to
685 (loop :for k :of obj :map k :to (foo k))
686 "(function () {
687 var map1 = { };
688 for (var k in obj) {
689 map1[k] = foo(k);
691 return map1;
692 })();")
694 (test-ps-js loop-for-of-when
695 (loop :for k :of obj :when (foo k) :map k :to (bar k))
696 "(function () {
697 var map1 = { };
698 for (var k in obj) {
699 if (foo(k)) {
700 map1[k] = bar(k);
703 return map1;
704 })();")
706 (test-ps-js loop-for-in-until-when
707 (loop :for a :in b :until (> a 100) :when (< a 50) :do (foo a))
708 "(function () {
709 var _js2 = b.length;
710 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
711 var a = b[_js1];
712 if (a > 100) {
713 break;
715 if (a < 50) {
716 foo(a);
719 })();")
721 (test-ps-js loop-with-for-when
722 (loop :with c = c1 :for d :from c1 :below c2
723 :when (foo c d) :do (setf c d)
724 :do (bar d))
725 "(function () {
726 var c = c1;
727 for (var d = c1; d < c2; d += 1) {
728 if (foo(c, d)) {
729 c = d;
731 bar(d);
733 })();")
735 (test-ps-js loop-for-then-for-in-while
736 (defun blah (c)
737 (loop :for a = (foo) :then (bar) :for b :in c :while b :do (foo a b c)))
738 "function blah(c) {
739 var _js2 = c.length;
740 var FIRST3 = true;
741 for (var a = foo(); true; a = bar()) {
742 var _js1 = FIRST3 ? 0 : _js1 + 1;
743 if (_js1 >= _js2) {
744 break;
746 var b = c[_js1];
747 if (!b) {
748 break;
750 foo(a, b, c);
751 FIRST3 = null;
753 };")
755 (test-ps-js loop-while-when
756 (loop :for a = (pop stack) :while a :for (b c) = (foo a) :when b :do (bar c))
757 "(function () {
758 for (var a = pop(stack); a; a = pop(stack)) {
759 var _db1 = foo(a);
760 var b = _db1[0];
761 var c = _db1[1];
762 if (b) {
763 bar(c);
766 })();")
768 (test-ps-js loop-for-of-for-in
769 (defun blah (obj b)
770 (loop :for k :of obj :for a :in b :do (foo k a)))
771 "function blah(obj, b) {
772 var _js2 = b.length;
773 var FIRST3 = true;
774 for (var k in obj) {
775 var _js1 = FIRST3 ? 0 : _js1 + 1;
776 if (_js1 >= _js2) {
777 break;
779 var a = b[_js1];
780 foo(k, a);
781 FIRST3 = null;
783 };")
785 (test-ps-js loop-for-dot
786 (loop :for (op . args) :in expr :do (foo op args))
787 "(function () {
788 var _js2 = expr.length;
789 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
790 var _db3 = expr[_js1];
791 var op = _db3[0];
792 var args = _db3.length > 1 ? _db3.slice(1) : [];
793 foo(op, args);
795 })();")
797 (test-ps-js loop-for-rest
798 (loop :for (op &rest args) :in expr :do (foo op args))
799 "(function () {
800 var _js2 = expr.length;
801 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
802 var _db3 = expr[_js1];
803 var op = _db3[0];
804 var args = _db3.length > 1 ? _db3.slice(1) : [];
805 foo(op, args);
807 })();")
809 (test-ps-js loop-collect
810 (setf x (loop :for a :in b :collect (foo a)))
811 "x = (function () {
812 var _js2 = b.length;
813 var collect3 = [];
814 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
815 var a = b[_js1];
816 collect3.push(foo(a));
818 return collect3;
819 })();")
821 (test-ps-js loop-append
822 (loop :for a :in b :append a)
823 "(function () {
824 var _js2 = b.length;
825 var append3 = [];
826 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
827 var a = b[_js1];
828 append3 = append3.concat(a);
830 return append3;
831 })();")
833 (test-ps-js the-case-statement-1
834 (case (aref blorg i)
835 ((1 "one") (alert "one"))
836 (2 (alert "two"))
837 (t (alert "default clause")))
838 "switch (blorg[i]) {
839 case 1:
840 case 'one':
841 alert('one');
842 break;
843 case 2:
844 alert('two');
845 break;
846 default:
847 alert('default clause');
848 };")
850 (test-ps-js the-case-statement-2
851 (switch (aref blorg i)
852 (1 (alert "If I get here"))
853 (2 (alert "I also get here"))
854 (default (alert "I always get here")))
855 "switch (blorg[i]) {
856 case 1: alert('If I get here');
857 case 2: alert('I also get here');
858 default: alert('I always get here');
859 };")
861 (test-ps-js the-try-statement-1
862 (try (throw "i")
863 (:catch (error)
864 (alert (+ "an error happened: " error)))
865 (:finally
866 (alert "Leaving the try form")))
867 "try {
868 throw 'i';
869 } catch (error) {
870 alert('an error happened: ' + error);
871 } finally {
872 alert('Leaving the try form');
873 };")
875 (test-ps-js the-html-generator-1
876 (ps-html ((:a :href "foobar") "blorg"))
877 "'<a href=\\\"foobar\\\">blorg</a>';")
879 (test-ps-js the-html-generator-2
880 (ps-html ((:a :href (generate-a-link)) "blorg"))
881 "['<a href=\\\"', generateALink(), '\\\">blorg</a>'].join('');")
883 (test-ps-js the-html-generator-3
884 (funcall (getprop document 'write)
885 (ps-html ((:a :href "#"
886 :onclick (ps-inline (transport))) "link")))
887 "document.write(['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">link</a>'].join(''));")
889 (test-ps-js the-html-generator-4
890 (let ((disabled nil)
891 (authorized t))
892 (setf (getprop element 'inner-h-t-m-l)
893 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
894 "Edit me"))))
895 "(function () {
896 var disabled = null;
897 var authorized = true;
898 return element.innerHTML = ['<textarea', disabled || !authorized ? [' disabled=\\\"', 'disabled', '\\\"'].join('') : '', '>Edit me</textarea>'].join('');
899 })();")
901 (test-ps-js plus-is-not-commutative
902 (setf x (+ "before" x "after"))
903 "x = 'before' + x + 'after';")
905 (test-ps-js plus-works-if-first
906 (setf x (+ x "middle" "after"))
907 "x = x + 'middle' + 'after';")
909 (test-ps-js method-call-op-form
910 (funcall (getprop (+ "" x) 'to-string))
911 "('' + x).toString();")
913 (test-ps-js method-call-op-form-args
914 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
915 "('' + x).foo(1, 2, 'baz', 3);")
917 (test-ps-js method-call-string
918 ((getprop "hi" 'to-string))
919 "'hi'.toString();")
921 (test-ps-js method-call-conditional
922 ((if a x y) 1)
923 "(a ? x : y)(1);")
925 (test-ps-js method-call-variable
926 ((@ x to-string))
927 "x.toString();")
929 (test-ps-js method-call-array
930 ((@ (list 10 20) to-string))
931 "[10, 20].toString();")
933 (test-ps-js method-call-lambda-call
934 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
935 "(function (x) { return x; })(10).toString();")
937 (fiveam:test no-whitespace-before-dot
938 (let ((str (ps* '((@ ((lambda (x) x) 10) to-string)))))
939 (fiveam:is (char= #\) (elt str (1- (position #\. str)))))))
941 (test-ps-js simple-getprop
942 (let ((foo (create a 1)))
943 (alert (getprop foo 'a)))
944 "(function () {
945 var foo = { a : 1 };
946 return alert(foo.a);
947 })();")
949 (test-ps-js buggy-getprop
950 (getprop foo slot-name)
951 "foo[slotName];")
953 (test-ps-js buggy-getprop-two
954 (getprop foo (get-slot-name))
955 "foo[getSlotName()];")
957 (test-ps-js old-case-is-now-switch
958 ;; Switch was "case" before, but that was very non-lispish.
959 ;; For example, this code makes three messages and not one
960 ;; which may have been expected. This is because a switch
961 ;; statment must have a break statement for it to return
962 ;; after the alert. Otherwise it continues on the next
963 ;; clause.
964 (switch (aref blorg i)
965 (1 (alert "one"))
966 (2 (alert "two"))
967 (default (alert "default clause")))
968 "switch (blorg[i]) {
969 case 1: alert('one');
970 case 2: alert('two');
971 default: alert('default clause');
972 };")
974 (test-ps-js lisp-like-case
975 (case (aref blorg i)
976 (1 (alert "one"))
977 (2 (alert "two"))
978 (t (alert "default clause")))
979 "switch (blorg[i]) {
980 case 1:
981 alert('one');
982 break;
983 case 2:
984 alert('two');
985 break;
986 default: alert('default clause');
987 };")
990 (test-ps-js even-lispier-case
991 (case (aref blorg i)
992 ((1 2) (alert "Below three"))
993 (3 (alert "Three"))
994 (t (alert "Something else")))
995 "switch (blorg[i]) {
996 case 1:
997 case 2:
998 alert('Below three');
999 break;
1000 case 3:
1001 alert('Three');
1002 break;
1003 default: alert('Something else');
1004 };")
1006 (test-ps-js otherwise-case
1007 (case (aref blorg i)
1008 (1 (alert "one"))
1009 (otherwise (alert "default clause")))
1010 "switch (blorg[i]) {
1011 case 1:
1012 alert('one');
1013 break;
1014 default: alert('default clause');
1015 };")
1017 (fiveam:test escape-sequences-in-string
1018 (let ((escapes
1019 `((#\\ . #\\)
1020 (#\b . #\Backspace)
1021 (#\f . ,(code-char 12))
1022 ("u000B" . ,(code-char #xB)) ; vertical tab
1023 (#\n . #\Newline)
1024 (#\r . #\Return)
1025 (#\' . #\')
1026 (#\" . #\")
1027 (#\t . #\Tab)
1028 ("u001F" . ,(code-char #x1F)) ; character below 32
1029 ("u0080" . ,(code-char 128)) ; character over 127
1030 ("u00A0" . ,(code-char 160)) ; non-breaking space
1031 ("u00AD" . ,(code-char 173)) ; soft hyphen
1032 ("u200B" . ,(code-char #x200B)) ; zero-width space
1033 ("u200C" . ,(code-char #x200C)) ; zero-width non-joiner
1035 (loop for (js-escape . lisp-char) in escapes
1036 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
1037 for wanted = (format nil "'hello\\~ahi';" js-escape)
1038 do (fiveam:is (string= generated wanted)))))
1040 (fiveam:test escape-doublequotes
1041 (let ((*js-string-delimiter* #\"))
1042 (fiveam:is (string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1044 (test-ps-js getprop-setf
1045 (setf (getprop x 'y) (+ (+ a 3) 4))
1046 "x.y = (a + 3) + 4;")
1048 (test-ps-js getprop-conditional1
1049 (getprop (if zoo foo bar) 'x)
1050 "(zoo ? foo : bar).x;")
1052 (test-ps-js getprop-conditional2
1053 (getprop (if (not zoo) foo bar) 'x)
1054 "(!zoo ? foo : bar).x;")
1056 (fiveam:test script-star-eval1
1057 (fiveam:is (string=
1058 (normalize-js-output (ps* '(setf x 1) '(setf y 2)))
1059 "x = 1; y = 2;")))
1061 (fiveam:test script-star-eval2
1062 (fiveam:is (string=
1063 (normalize-js-output (ps* '(setf x 1)))
1064 "x = 1;")))
1066 (test-ps-js list-with-single-nil
1067 (array nil)
1068 "[null];")
1070 (test-ps-js quoted-nil-is-array
1071 'nil
1072 "[];")
1074 (test-ps-js quoted-nil-is-array1
1076 "[];")
1078 (test-ps-js literal-nil
1079 (foo ())
1080 "foo(null);")
1082 (test-ps-js quoted-quoted-nil
1083 '(())
1084 "[null];")
1086 (test-ps-js quoted-quoted-nil1
1087 '(1 ())
1088 "[1, null];")
1090 (test-ps-js defsetf1
1091 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1092 (setf (baz 1 2) 3))
1093 "(function () {
1094 var _js2 = 1;
1095 var _js3 = 2;
1096 var _js1 = 3;
1097 return setBaz(_js2, _js3, _js1);
1098 })();")
1100 (test-ps-js setf-macroexpands1
1101 (macrolet ((bar (x y)
1102 `(aref ,x ,y 1)))
1103 (setf (bar foo 2) 3))
1104 "foo[2][1] = 3;")
1106 (test-ps-js defsetf-short
1107 (progn (defsetf baz set-baz "docstring")
1108 (setf (baz 1 2 3) "foo"))
1109 "setBaz(1, 2, 3, 'foo');")
1111 (test-ps-js defun-setf1
1112 (progn (defun (setf some-thing) (new-val i1 i2)
1113 (setf (aref *some-thing* i1 i2) new-val))
1114 (setf (some-thing 1 2) "foo"))
1115 "function __setf_someThing(newVal, i1, i2) {
1116 return SOMETHING[i1][i2] = newVal;
1118 __setf_someThing('foo', 1, 2);")
1120 (test-ps-js defun-optional1
1121 (defun test-opt (&optional x)
1122 (if x "yes" "no"))
1123 "function testOpt(x) {
1124 return x ? 'yes' : 'no';
1125 };")
1127 (test-ps-js defun-optional2
1128 (defun foo (x &optional y)
1129 (+ x y))
1130 "function foo(x, y) {
1131 return x + y;
1132 };")
1134 (test-ps-js defun-optional3
1135 (defun blah (&optional (x 0))
1137 "function blah(x) {
1138 if (x === undefined) {
1139 x = 0;
1141 return x;
1142 };")
1144 (test-ps-js arglist-optional4
1145 (lambda (&optional (x 0 supplied?))
1147 "(function (x) {
1148 var suppliedwhat = x !== undefined;
1149 if (!suppliedwhat) {
1150 x = 0;
1152 return x;
1153 });")
1155 (test-ps-js return-nothing
1156 (defun foo () (return-from foo))
1157 "function foo() {
1158 return null;
1159 };")
1161 (test-ps-js return-values
1162 (defun foo () (return-from foo (values 1 2 3)))
1163 "function foo() {
1164 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [2, 3] };
1165 return 1;
1166 };")
1168 (test-ps-js set-timeout
1169 (set-timeout (lambda () (alert "foo")) 10)
1170 "setTimeout(function () { return alert('foo'); }, 10);")
1172 (test-ps-js operator-precedence
1173 (* 3 (+ 4 5) 6)
1174 "3 * (4 + 5) * 6;")
1176 (test-ps-js operators-1
1177 (in prop obj)
1178 "prop in obj;")
1180 (test-ps-js incf1
1181 (incf foo bar)
1182 "foo += bar;")
1184 (test-ps-js decf1
1185 (decf foo bar)
1186 "foo -= bar;")
1188 (test-ps-js incf2
1189 (incf x 5)
1190 "x += 5;")
1192 (test-ps-js decf2
1193 (decf y 10)
1194 "y -= 10;")
1196 (test-ps-js setf-conditional
1197 (setf foo (if x 1 2))
1198 "foo = x ? 1 : 2;")
1200 (test-ps-js obj-literal-numbers
1201 (create 1 "foo")
1202 "({ 1 : 'foo' });")
1204 (test-ps-js obj-literal-strings
1205 (create "foo" 2)
1206 "({ 'foo' : 2 });")
1208 (test-ps-js getprop-string
1209 (getprop foo "bar")
1210 "foo['bar'];")
1212 (test-ps-js getprop-string1
1213 (getprop "bar" 'length)
1214 "'bar'.length;")
1216 (test-ps-js getprop-progn
1217 (getprop (progn (some-fun "abc") "123") "length")
1218 "(someFun('abc'), '123')['length'];")
1220 (test-ps-js getprop-multi1
1221 (getprop foo 1 "two" three 'bar 1 2)
1222 "foo[1]['two'][three].bar[1][2];")
1224 (test-ps-js method-call-block
1225 ((@ (progn (some-fun "abc") "123") to-string))
1226 "(someFun('abc'), '123').toString();")
1228 (test-ps-js create-blank
1229 (create)
1230 "({ });")
1232 (test-ps-js blank-object-literal
1234 "({ });")
1236 (test-ps-js array-literal1
1238 "[];")
1240 (test-ps-js array-literal2
1241 ([])
1242 "[];")
1244 (test-ps-js array-literal3
1245 ([] 1 2 3)
1246 "[1, 2, 3];")
1248 (test-ps-js array-literal4
1249 ([] 1 (2 3))
1250 "[1, [2, 3]];")
1252 (test-ps-js array-literal5
1253 ([] (1 2) ("a" "b"))
1254 "[[1, 2], ['a', 'b']];")
1256 (test-ps-js defun-rest1
1257 (defun foo (&rest bar)
1258 (alert (aref bar 1)))
1259 "function foo() {
1260 var bar = Array.prototype.slice.call(arguments, 0);
1261 return alert(bar[1]);
1262 };")
1264 (test-ps-js defun-rest2
1265 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1266 "function foo(baz) {
1267 var bar = Array.prototype.slice.call(arguments, 1);
1268 return baz + bar[1];
1269 };")
1271 (test-ps-js defun-keyword1
1272 (defun zoo (foo bar &key baz) (+ foo bar baz))
1273 "function zoo(foo, bar) {
1274 var _js2 = arguments.length;
1275 for (var n1 = 2; n1 < _js2; n1 += 2) {
1276 switch (arguments[n1]) {
1277 case 'baz':
1278 baz = arguments[n1 + 1];
1281 var baz;
1282 return foo + bar + baz;
1283 };")
1285 (test-ps-js defun-keyword2
1286 (defun zoo (&key baz) (* baz baz))
1287 "function zoo() {
1288 var _js2 = arguments.length;
1289 for (var n1 = 0; n1 < _js2; n1 += 2) {
1290 switch (arguments[n1]) {
1291 case 'baz':
1292 baz = arguments[n1 + 1];
1295 var baz;
1296 return baz * baz;
1297 };")
1299 (test-ps-js defun-keyword3
1300 (defun zoo (&key baz (bar 4)) (* baz bar))
1301 "function zoo() {
1302 var _js2 = arguments.length;
1303 for (var n1 = 0; n1 < _js2; n1 += 2) {
1304 switch (arguments[n1]) {
1305 case 'baz':
1306 baz = arguments[n1 + 1];
1307 break;
1308 case 'bar':
1309 bar = arguments[n1 + 1];
1312 var baz;
1313 var bar = 'undefined' === typeof bar ? 4 : bar;
1314 return baz * bar;
1315 };")
1317 (test-ps-js defun-keyword4
1318 (defun hello-world (&key ((:my-name-key my-name) 1))
1319 my-name)
1320 "function helloWorld() {
1321 var _js2 = arguments.length;
1322 for (var n1 = 0; n1 < _js2; n1 += 2) {
1323 switch (arguments[n1]) {
1324 case 'my-name-key':
1325 myName = arguments[n1 + 1];
1328 var myName = 'undefined' === typeof myName ? 1 : myName;
1329 return myName;
1330 };")
1332 (test-ps-js arglist-keyword-supplied
1333 (lambda (&key (foo 1 supplied?))
1334 foo)
1335 "(function () {
1336 var _js2 = arguments.length;
1337 for (var n1 = 0; n1 < _js2; n1 += 2) {
1338 switch (arguments[n1]) {
1339 case 'foo':
1340 foo = arguments[n1 + 1];
1341 suppliedwhat = true;
1344 var suppliedwhat;
1345 var foo = 'undefined' === typeof foo ? 1 : foo;
1346 return foo;
1347 });")
1349 (test-ps-js keyword-funcall1
1350 (func :baz 1)
1351 "func('baz', 1);")
1353 (test-ps-js keyword-funcall2
1354 (func :baz 1 :bar foo)
1355 "func('baz', 1, 'bar', foo);")
1357 (test-ps-js keyword-funcall3
1358 (fun a b :baz c)
1359 "fun(a, b, 'baz', c);")
1361 (test-ps-js cond1
1362 (cond ((= x 1) 1))
1363 "if (x === 1) {
1365 };")
1367 (test-ps-js cond2
1368 (cond ((= x 1) 2)
1369 ((= y (* x 4)) (foo "blah") (* x y)))
1370 "if (x === 1) {
1372 } else if (y === x * 4) {
1373 foo('blah');
1374 x * y;
1375 };")
1377 (test-ps-js if-exp-without-else-return
1378 (defun foo () (return-from foo (if x 1)))
1379 "function foo() {
1380 return x ? 1 : null;
1381 };")
1383 (test-ps-js progn-expression-single-statement
1384 (defun foo () (return-from foo (progn (* x y))))
1385 "function foo() {
1386 return x * y;
1387 };")
1389 (test-ps-js cond-expression1
1390 (defun foo ()
1391 (cond ((< 1 2) (bar "foo") (* 4 5))))
1392 "function foo() {
1393 if (1 < 2) {
1394 bar('foo');
1395 return 4 * 5;
1397 };")
1399 (test-ps-js cond-expression2
1400 (defun foo ()
1401 (cond ((< 2 1) "foo")
1402 ((= 7 7) "bar")))
1403 "function foo() {
1404 if (2 < 1) {
1405 return 'foo';
1406 } else if (7 === 7) {
1407 return 'bar';
1409 };")
1411 (test-ps-js cond-expression-final-t-clause
1412 (defun foo ()
1413 (cond ((< 1 2) (bar "foo") (* 4 5))
1414 ((= a b) (+ c d))
1415 ((< 1 2 3 4 5) x)
1416 (t "foo")))
1417 "function foo() {
1418 var _cmp1;
1419 var _cmp2;
1420 var _cmp3;
1421 if (1 < 2) {
1422 bar('foo');
1423 return 4 * 5;
1424 } else if (a === b) {
1425 return c + d;
1426 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1427 return x;
1428 } else {
1429 return 'foo';
1431 };")
1433 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1434 (defun foo ()
1435 (cond ((< 2 1) 5)
1436 (t "foo")
1437 ((< 1 2) "bar")))
1438 "function foo() {
1439 if (2 < 1) {
1440 return 5;
1441 } else {
1442 return 'foo';
1444 };")
1446 (test-ps-js funcall-if-expression
1447 (funcall (getprop document 'write)
1448 (if (= *linkornot* 1)
1449 (ps-html ((:a :href "#"
1450 :onclick (ps-inline (transport)))
1451 img))
1452 img))
1453 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1455 (test-ps-js negate-number-literal
1456 (- 1)
1457 "-1;")
1459 (fiveam:test macro-environment1
1460 (fiveam:is
1461 (string=
1462 (normalize-js-output
1463 (let* ((macroname (gensym)))
1464 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1465 `(defun test1 ()
1466 (macrolet ((,macroname (x) `(aref data ,x)))
1467 (when (,macroname x)
1468 (setf (,macroname x) 123)))))))
1469 (normalize-js-output
1470 "function test1() {
1471 return data[x] ? (data[x] = 123) : null;
1472 };"))))
1474 (fiveam:test macro-environment2
1475 (fiveam:is
1476 (string=
1477 (let ((outer-lexical-variable 1))
1478 (defpsmacro macro-environment2-macro (x)
1479 `(+ ,outer-lexical-variable ,x))
1480 (ps* '(macro-environment2-macro 2)))
1481 "1 + 2;")))
1483 (test-ps-js ampersand-whole-1
1484 (macrolet ((foo (&whole foo bar baz)
1485 (declare (ignore bar baz))
1486 (with-standard-io-syntax
1487 (let ((*print-case* :downcase))
1488 (format nil "~a" foo)))))
1489 (foo 1 2))
1490 "'(foo 1 2)';")
1492 (test-ps-js ampersand-whole-2
1493 (macrolet ((foo (&whole foo bar baz)
1494 `(+ ,bar ,baz)))
1495 (foo 1 2))
1496 "1 + 2;")
1498 (test-ps-js keyword-consistent
1500 "'x';")
1502 (test-ps-js simple-symbol-macrolet
1503 (symbol-macrolet ((x 1)) x)
1504 "1;")
1506 (test-ps-js compound-symbol-macrolet
1507 (symbol-macrolet ((x 123)
1508 (y (* 2 x)))
1510 "2 * 123;")
1512 (test-ps-js define-symbol-macro
1513 (progn (define-symbol-macro tst-sym-macro 2)
1514 tst-sym-macro)
1515 "2;")
1517 (test-ps-js define-symbol-macro1
1518 (progn (define-symbol-macro tst-sym-macro1 2)
1519 (foo tst-sym-macro1))
1520 "foo(2);")
1522 (test-ps-js define-symbol-macro2
1523 (progn (define-symbol-macro tst-sym-macro2 3)
1524 (list tst-sym-macro2))
1525 "[3];")
1527 (test-ps-js define-symbol-macro3
1528 (progn (define-symbol-macro tst-sym-macro3 4)
1529 (setq foo (create tst-sym-macro3 tst-sym-macro3)))
1530 "foo = { tstSymMacro3 : 4 };")
1532 (test-ps-js define-symbol-macro4
1533 (progn (define-symbol-macro tst-sym-macro4 5)
1534 (setq foo (if (baz) tst-sym-macro4 bar)))
1535 "foo = baz() ? 5 : bar;")
1537 (test-ps-js expression-progn
1538 (1+ (progn (foo) (if x 1 2)))
1539 "(foo(), x ? 1 : 2) + 1;")
1541 (test-ps-js let-decl-in-expression
1542 (defun f (x)
1543 (if x 1 (let* ((foo x)) foo)))
1544 "function f(x) {
1545 if (x) {
1546 return 1;
1547 } else {
1548 var foo = x;
1549 return foo;
1551 };")
1553 (test-ps-js special-var1
1554 (progn (defvar *foo*)
1555 (let* ((*foo* 2))
1556 (* *foo* 2)))
1557 "var FOO;
1558 (function () {
1559 var FOO_TMPSTACK1;
1560 try {
1561 FOO_TMPSTACK1 = FOO;
1562 FOO = 2;
1563 return FOO * 2;
1564 } finally {
1565 FOO = FOO_TMPSTACK1;
1567 })();")
1569 (test-ps-js special-var2
1570 (progn (defvar *foo*)
1571 (let* ((*baz* 3)
1572 (*foo* 2))
1573 (* *foo* 2 *baz*)))
1574 "var FOO;
1575 (function () {
1576 var BAZ = 3;
1577 var FOO_TMPSTACK1;
1578 try {
1579 FOO_TMPSTACK1 = FOO;
1580 FOO = 2;
1581 return FOO * 2 * BAZ;
1582 } finally {
1583 FOO = FOO_TMPSTACK1;
1585 })();")
1587 (test-ps-js literal1
1588 (setf x undefined)
1589 "x = undefined;")
1591 (test-ps-js literal2
1592 (aref this x)
1593 "this[x];")
1595 (test-ps-js setf-dec1
1596 (setf x (- 1 x 2))
1597 "x = 1 - x - 2;")
1599 (test-ps-js setf-dec2
1600 (setf x (- x 1 2))
1601 "x = x - 1 - 2;")
1603 (test-ps-js special-char-equals
1604 blah=
1605 "blahequals;")
1607 (test-ps-js setf-operator-priority
1608 (defun foo ()
1609 (or (getprop cache id)
1610 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1611 "function foo() {
1612 return cache[id] || (cache[id] = document.getElementById(id));
1613 };")
1615 (test-ps-js aref-operator-priority
1616 (aref (if (and x (> (length x) 0))
1617 (aref x 0)
1620 "(x && x.length > 0 ? x[0] : y)[z];")
1622 (test-ps-js aref-operator-priority1
1623 (aref (or (getprop x 'y)
1624 (getprop a 'b))
1626 "(x.y || a.b)[z];")
1628 (test-ps-js aref-operator-priority2
1629 (aref (if a b c) 0)
1630 "(a ? b : c)[0];")
1632 (test-ps-js negate-operator-priority
1633 (- (if x y z))
1634 "-(x ? y : z);")
1636 (test-ps-js op-p1
1637 (new (or a b))
1638 "new (a || b);")
1640 (test-ps-js op-p2
1641 (delete (if a (or b c) d))
1642 "delete (a ? b || c : d);")
1644 (test-ps-js op-p3
1645 (not (if (or x (not y)) z))
1646 "!(x || !y ? z : null);")
1648 (test-ps-js op-p4
1649 (- (- (* 1 2) 3))
1650 "-(1 * 2 - 3);")
1652 (test-ps-js op-p5
1653 (instanceof (or a b) (if x y z))
1654 "((a || b) instanceof (x ? y : z));")
1656 (test-ps-js op-p7
1657 (or x (if (= x 0) "zero" "empty"))
1658 "x || (x === 0 ? 'zero' : 'empty');")
1660 (test-ps-js named-op-expression
1661 (throw (if a b c))
1662 "throw a ? b : c;")
1664 (test-ps-js named-op-expression1
1665 (typeof (or x y))
1666 "typeof (x || y);")
1668 (test-ps-js aref-array-expression
1669 (aref (or a b c) 0)
1670 "(a || b || c)[0];")
1672 (test-ps-js getprop-operator
1673 (getprop (or a b c) 'd)
1674 "(a || b || c).d;")
1676 (test-ps-js getprop-parens
1677 (getprop (getprop foo 'bar) 'baz)
1678 "foo.bar.baz;")
1680 (test-ps-js funcall-funcall
1681 ((foo))
1682 "foo()();")
1684 (test-ps-js expression-funcall
1685 ((or (@ window eval) eval) foo nil)
1686 "(window.eval || eval)(foo, null);")
1688 (test-ps-js expression-funcall1
1689 (((or (@ window eval) eval) foo nil))
1690 "(window.eval || eval)(foo, null)();")
1692 (test-ps-js expression-funcall2
1693 (((or (@ window eval) eval)) foo nil)
1694 "(window.eval || eval)()(foo, null);")
1696 (test-ps-js who-html1
1697 (who-ps-html (:span :class "ticker-symbol"
1698 :ticker-symbol symbol
1699 (:a :href "http://foo.com"
1700 symbol)
1701 (:span :class "ticker-symbol-popup")))
1702 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1704 (test-ps-js who-html2
1705 (who-ps-html (:p "t0" (:span "t1")))
1706 "'<p>t0<span>t1</span></p>';")
1708 (test-ps-js flet1
1709 ((lambda () (flet ((foo (x)
1710 (1+ x)))
1711 (foo 1))))
1712 "(function () {
1713 var foo = function (x) {
1714 return x + 1;
1716 return foo(1);
1717 })();")
1719 (test-ps-js flet2
1720 (flet ((foo (x) (1+ x))
1721 (bar (y) (+ 2 y)))
1722 (bar (foo 1)))
1723 "(function () {
1724 var foo = function (x) {
1725 return x + 1;
1727 var bar = function (y) {
1728 return 2 + y;
1730 return bar(foo(1));
1731 })();")
1733 (test-ps-js flet3
1734 (flet ((foo (x) (+ 2 x)))
1735 (flet ((foo (x) (1+ x))
1736 (bar (y) (+ 2 (foo y))))
1737 (bar (foo 1))))
1738 "(function () {
1739 var foo = function (x) {
1740 return 2 + x;
1742 var foo1 = function (x) {
1743 return x + 1;
1745 var bar = function (y) {
1746 return 2 + foo(y);
1748 return bar(foo1(1));
1749 })();")
1751 (test-ps-js labels1
1752 ((lambda () (labels ((foo (x)
1753 (if (= 0 x)
1755 (+ x (foo (1- x))))))
1756 (foo 3))))
1757 "(function () {
1758 var foo = function (x) {
1759 return 0 === x ? 0 : x + foo(x - 1);
1761 return foo(3);
1762 })();")
1764 (test-ps-js labels2
1765 (labels ((foo (x) (1+ (bar x)))
1766 (bar (y) (+ 2 (foo y))))
1767 (bar (foo 1)))
1768 "(function () {
1769 var foo = function (x) {
1770 return bar(x) + 1;
1772 var bar = function (y) {
1773 return 2 + foo(y);
1775 return bar(foo(1));
1776 })();")
1778 (test-ps-js labels3
1779 (labels ((foo (x) (1+ x))
1780 (bar (y) (+ 2 (foo y))))
1781 (bar (foo 1)))
1782 "(function () {
1783 var foo = function (x) {
1784 return x + 1;
1786 var bar = function (y) {
1787 return 2 + foo(y);
1789 return bar(foo(1));
1790 })();")
1792 (test-ps-js labels-lambda-list
1793 (labels ((foo (x &optional (y 0))
1794 (+ x y)))
1795 (foo 1))
1796 "(function () {
1797 var foo = function (x, y) {
1798 if (y === undefined) {
1799 y = 0;
1801 return x + y;
1803 return foo(1);
1804 })();")
1806 (test-ps-js for-loop-var-init-exp
1807 ((lambda (x)
1808 (do* ((y (if x 0 1) (1+ y))
1809 (z 0 (1+ z)))
1810 ((= y 3) z)))
1812 "(function (x) {
1813 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1815 return z;
1816 })(true);")
1818 (test-ps-js math-pi
1820 "Math.PI;")
1822 (test-ps-js literal-array
1823 '(1 2 3)
1824 "[1, 2, 3];")
1826 (test-ps-js literal-array-1
1827 '(1 foo 3)
1828 "[1, 'foo', 3];")
1830 (test-ps-js literal-array-literal
1832 "[];")
1834 (test-ps-js literal-array-literal1
1835 '(1 [])
1836 "[1, []];")
1838 (fiveam:test ps-lisp-expands-in-lexical-environment
1839 (fiveam:is (string= (let ((x 5)) (ps (lisp x)))
1840 "5;")))
1842 (fiveam:test ps-lisp-expands-in-lexical-environment1
1843 (fiveam:is (string= (let ((x 5)) (ps (+ 1 (lisp x))))
1844 "1 + 5;")))
1846 (fiveam:test ps-lisp-expands-in-lexical-environment2
1847 (fiveam:is (string= (let ((x 2)) (ps (+ 1 (lisp x) 3)))
1848 "1 + 2 + 3;")))
1850 (fiveam:test ps*-lisp-expands-in-null-lexical-environment
1851 (fiveam:signals unbound-variable
1852 (let ((x 5))
1853 (declare (ignore x))
1854 (ps* '(lisp x)))))
1856 (fiveam:test ps*-lisp-expands-in-dynamic-environment
1857 (fiveam:is (string=
1858 (let ((foo 2))
1859 (declare (special foo))
1860 (ps* '(+ 1 (lisp (locally (declare (special foo))
1861 foo)))))
1862 "1 + 2;")))
1864 (fiveam:test ps-lisp-dynamic-environment
1865 (fiveam:is (string=
1866 (let ((foo 2))
1867 (declare (special foo))
1868 (ps (+ 1 (lisp foo))))
1869 "1 + 2;")))
1871 (test-ps-js nested-if-expressions1
1872 (defun foo ()
1873 (return-from foo (if (if x y z) a b)))
1874 "function foo() {
1875 if (x ? y : z) {
1876 return a;
1877 } else {
1878 return b;
1880 };")
1882 (test-ps-js nested-if-expressions2
1883 (defun foo ()
1884 (if x y (if z a b)))
1885 "function foo() {
1886 if (x) {
1887 return y;
1888 } else {
1889 return z ? a : b;
1891 };")
1893 (test-ps-js nested-if-expressions3
1894 (foo (if (if x y z) a b)
1895 (if x y (if z a b)))
1896 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
1898 (test-ps-js let1
1899 (let (x)
1900 (+ x x))
1901 "(function () {
1902 var x = null;
1903 return x + x;
1904 })();")
1906 (test-ps-js let2
1907 (let ((x 1))
1908 (+ x x))
1909 "(function () {
1910 var x = 1;
1911 return x + x;
1912 })();")
1914 (test-ps-js let-x-x
1915 (let ((x (1+ x)))
1916 (+ x x))
1917 "(function () {
1918 var x1 = x + 1;
1919 return x1 + x1;
1920 })();")
1922 (test-ps-js let3
1923 (let ((x 1)
1924 (y 2))
1925 (+ x x))
1926 "(function () {
1927 var x = 1;
1928 var y = 2;
1929 return x + x;
1930 })();")
1932 (test-ps-js let4
1933 (let ((x 1)
1934 (y (1+ x)))
1935 (+ x y))
1936 "(function () {
1937 var x1 = 1;
1938 var y = x + 1;
1939 return x1 + y;
1940 })();")
1942 (test-ps-js let5
1943 (let ((x 1))
1944 (+ x 1)
1945 (let ((x (+ x 5)))
1946 (+ x 1))
1947 (+ x 1))
1948 "(function () {
1949 var x = 1;
1950 x + 1;
1951 var x1 = x + 5;
1952 x1 + 1;
1953 return x + 1;
1954 })();")
1956 (test-ps-js let6
1957 (let ((x 2))
1958 (let ((x 1)
1959 (y (1+ x)))
1960 (+ x y)))
1961 "(function () {
1962 var x = 2;
1963 var x1 = 1;
1964 var y = x + 1;
1965 return x1 + y;
1966 })();")
1968 (test-ps-js let-exp1
1969 (lambda ()
1970 (let (x)
1971 (+ x x)))
1972 "(function () {
1973 var x = null;
1974 return x + x;
1975 });")
1977 (test-ps-js let*1
1978 (let* ((x 1))
1979 (+ x x))
1980 "(function () {
1981 var x = 1;
1982 return x + x;
1983 })();")
1985 (test-ps-js let*2
1986 (let* ((x 1)
1987 (y (+ x 2)))
1988 (+ x y))
1989 "(function () {
1990 var x = 1;
1991 var y = x + 2;
1992 return x + y;
1993 })();")
1995 (test-ps-js let*3
1996 (let ((x 3))
1997 (let* ((x 1)
1998 (y (+ x 2)))
1999 (+ x y)))
2000 "(function () {
2001 var x = 3;
2002 var x1 = 1;
2003 var y = x1 + 2;
2004 return x1 + y;
2005 })();")
2007 (test-ps-js let*4
2008 (let ((x 3))
2009 (let* ((y (+ x 2))
2010 (x 1))
2011 (+ x y)))
2012 "(function () {
2013 var x = 3;
2014 var y = x + 2;
2015 var x1 = 1;
2016 return x1 + y;
2017 })();")
2019 (test-ps-js symbol-macrolet-var
2020 (symbol-macrolet ((x y))
2021 (var x))
2022 "var y;")
2024 (test-ps-js setf-conditional1
2025 (setf x (unless (null a) (1+ a)))
2026 "x = a != null ? a + 1 : null;")
2028 (test-ps-js setf-let1
2029 (setf x (let ((a 1)) a))
2030 "x = (function () {
2031 var a = 1;
2032 return a;
2033 })();")
2035 (test-ps-js setf-let2
2036 (setf x (let ((a (foo)))
2037 (unless (null a)
2038 (1+ a))))
2039 "x = (function () {
2040 var a = foo();
2041 return a != null ? a + 1 : null;
2042 })();")
2044 (test-ps-js symbol-macro-env1
2045 (symbol-macrolet ((bar 1))
2046 (macrolet ((bar (x y) `(+ ,x ,y)))
2047 (bar bar bar)))
2048 "1 + 1;")
2050 (test-ps-js symbol-macrolet-fun1
2051 (symbol-macrolet ((baz +))
2052 (baz 1 2))
2053 "baz(1, 2);")
2055 (test-ps-js lisp2-namespaces1
2056 (let ((list nil))
2057 (setf list (list 1 2 3)))
2058 "(function () {
2059 var list = null;
2060 return list = [1, 2, 3];
2061 })();")
2063 (test-ps-js let-shadows-symbol-macrolet
2064 (symbol-macrolet ((x y))
2065 (let ((x 1))
2066 (+ x x))
2067 (+ x x))
2068 "(function () {
2069 var x1 = 1;
2070 return x1 + x1;
2071 })();
2072 y + y;")
2074 (test-ps-js let-rename-optimization1
2075 (let ((x 1))
2076 (+ x x))
2077 "(function () {
2078 var x = 1;
2079 return x + x;
2080 })();")
2082 (test-ps-js let-rename-optimization2
2083 (lambda (x)
2084 (let ((x (+ 1 x)))
2086 "(function (x) {
2087 var x1 = 1 + x;
2088 return x1;
2089 });")
2091 (test-ps-js symbol-macro-array
2092 (symbol-macrolet ((x 1))
2093 (list x))
2094 "[1];")
2096 (test-ps-js symbol-macro-obj
2097 (symbol-macrolet ((x (+ 1 2)))
2098 (create x 1))
2099 "({ x : 1 });")
2101 (test-ps-js symbol-macro-obj1
2102 (symbol-macrolet ((x (+ 1 2)))
2103 (ps:create x x))
2104 "({ x : 1 + 2 });")
2106 (test-ps-js symbol-macro-getprop1
2107 (symbol-macrolet ((x (+ 1 2)))
2108 (ps:getprop a x))
2109 "a[1 + 2];")
2111 (test-ps-js symbol-macro-getprop1
2112 (symbol-macrolet ((x (+ 1 2)))
2113 (ps:getprop a 'x))
2114 "a.x;")
2116 (test-ps-js let-let-create
2117 (let ((a 99))
2118 (let ((a 22))
2119 (create a 33)))
2120 "(function () {
2121 var a = 99;
2122 var a1 = 22;
2123 return { a : 33 };
2124 })();")
2126 (test-ps-js symbol-macro-conditional1
2127 (symbol-macrolet ((x y))
2128 (if x x x))
2129 "if (y) {
2131 } else {
2133 };")
2135 (test-ps-js symbol-macro-conditional2
2136 (symbol-macrolet ((x y))
2137 (1+ (if x x x)))
2138 "(y ? y : y) + 1;")
2140 (test-ps-js preserve-this
2141 (defun foo ()
2142 (let ((y (block nil (bar this))))
2143 (baz y)))
2144 "function foo() {
2145 var y = (function () {
2146 return bar(this);
2147 }).call(this);
2148 return baz(y);
2149 };")
2151 (test-ps-js flet-apply
2152 (flet ((foo () 'bar))
2153 (apply (function foo) nil))
2154 "(function () {
2155 var foo = function () {
2156 return 'bar';
2158 return foo.apply(this, null);
2159 }).call(this);")
2161 (test-ps-js let-apply
2162 (let ((foo (lambda () 1)))
2163 (let ((foo (lambda () 2)))
2164 (apply foo nil)))
2165 "(function () {
2166 var foo = function () {
2167 return 1;
2169 var foo1 = function () {
2170 return 2;
2172 return foo1.apply(this, null);
2173 }).call(this);")
2175 (test-ps-js flet-let
2176 (flet ((x (x) (1+ x)))
2177 (let ((x 2))
2178 (x x)))
2179 "(function () {
2180 var x = function (x) {
2181 return x + 1;
2183 var x1 = 2;
2184 return x(x1);
2185 })();")
2187 (test-ps-js let-flet
2188 (let ((x 2))
2189 (flet ((x (x) (1+ x)))
2190 (x x)))
2191 "(function () {
2192 var x = 2;
2193 var x1 = function (x) {
2194 return x + 1;
2196 return x1(x);
2197 })();")
2199 (test-ps-js labels-let
2200 (labels ((x (x) (1+ x)))
2201 (let ((x 2))
2202 (x x)))
2203 "(function () {
2204 var x = function (x) {
2205 return x + 1;
2207 var x1 = 2;
2208 return x(x1);
2209 })();")
2211 (test-ps-js let-labels
2212 (let ((x 2))
2213 (labels ((x (x) (1+ x)))
2214 (x x)))
2215 "(function () {
2216 var x = 2;
2217 var x1 = function (x) {
2218 return x + 1;
2220 return x1(x);
2221 })();")
2223 (test-ps-js macrolet-let-inteference
2224 (macrolet ((a (n) `(+ ,n 5)))
2225 (let ((a (a 1)))
2226 (let ((b (a (- a 4))))
2227 (+ a b))))
2228 "(function () {
2229 var a = 1 + 5;
2230 var b = (a - 4) + 5;
2231 return a + b;
2232 })();")
2234 (test-ps-js let-subtract-add
2235 (let ((x 1))
2236 (let ((x 2))
2237 (- x x)
2238 (- x)
2239 (decf x)
2240 (incf x)))
2241 "(function () {
2242 var x = 1;
2243 var x1 = 2;
2244 x1 - x1;
2245 -x1;
2246 --x1;
2247 return ++x1;
2248 })();")
2250 (test-ps-js create-reserved-word
2251 (create :default 1)
2252 "({ 'default' : 1 });")
2254 (test-ps-js getprop-reserved-word
2255 (getprop foo :default)
2256 "foo['default'];")
2258 (test-ps-js getprop-reserved-word1
2259 (getprop foo 'default)
2260 "foo['default'];")
2262 (test-ps-js eval-when-ps-side
2263 (eval-when (:execute)
2265 "5;")
2267 (defvar *lisp-output* nil)
2269 (fiveam:test eval-when-lisp-side ()
2270 (setf *lisp-output* 'original-value)
2271 (let ((js-output
2272 (normalize-js-output
2273 (ps-doc* `(eval-when (:compile-toplevel)
2274 (setf *lisp-output* 'it-works))))))
2275 (fiveam:is (eql 'it-works *lisp-output*))
2276 (fiveam:is (string= "" js-output))))
2278 (defpsmacro my-in-package (package-name)
2279 `(eval-when (:compile-toplevel)
2280 (setf *lisp-output* ,package-name)))
2282 (fiveam:test eval-when-macro-expansion ()
2283 (setf *lisp-output* 'original-value)
2284 (let ((js-output
2285 (normalize-js-output
2286 (ps-doc* `(progn
2287 (my-in-package :cl-user)
2288 3)))))
2289 (declare (ignore js-output))
2290 (fiveam:is (eql :cl-user *lisp-output*))))
2292 (fiveam:test eval-when-macrolet-expansion ()
2293 (setf *lisp-output* 'original-value)
2294 (let ((js-output
2295 (normalize-js-output
2296 (ps-doc*
2297 `(macrolet ((my-in-package2 (package-name)
2298 `(eval-when (:compile-toplevel)
2299 (setf *lisp-output* ,package-name))))
2300 (my-in-package2 :cl-user)
2301 3)))))
2302 (declare (ignore js-output))
2303 (fiveam:is (eql :cl-user *lisp-output*))))
2305 (test-ps-js getprop-keyword
2306 (getprop foo :bar)
2307 "foo['bar'];")
2309 (test-ps-js nary-comparison1
2310 (lambda () (< 1 2 3))
2311 "(function () {
2312 var _cmp1;
2313 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2314 });")
2316 (test-ps-js chain-getprop1
2317 (chain ($ "foo") (bar x z) frob (baz 5))
2318 "$('foo').bar(x, z).frob.baz(5);")
2320 (test-ps-js chain-getprop2
2321 (chain ($ "foo") bar baz)
2322 "$('foo').bar.baz;")
2324 (test-ps-js chain-getprop3
2325 (chain ($ "foo") bar (x y) baz)
2326 "$('foo').bar.x(y).baz;")
2328 (test-ps-js flet-expression
2329 (1+ (flet ((foo (x) (1+ x)))
2330 (foo 1)))
2331 "(function () {
2332 var foo = function (x) {
2333 return x + 1;
2335 return foo(1);
2336 })() + 1;")
2338 (test-ps-js flet-lambda-list
2339 (flet ((foo (x &key (y 0))
2340 (+ x y)))
2341 (foo 1 :y 2))
2342 "(function () {
2343 var foo = function (x) {
2344 var _js2 = arguments.length;
2345 for (var n1 = 1; n1 < _js2; n1 += 2) {
2346 switch (arguments[n1]) {
2347 case 'y':
2348 y = arguments[n1 + 1];
2351 var y = 'undefined' === typeof y ? 0 : y;
2352 return x + y;
2354 return foo(1, 'y', 2);
2355 })();")
2357 (test-ps-js return-case-break-elimination
2358 (defun foo ()
2359 (case 1
2360 (0 1)
2361 (otherwise 2)))
2362 "function foo() {
2363 switch (1) {
2364 case 0:
2365 return 1;
2366 default:
2367 return 2;
2369 };")
2371 (test-ps-js aplusplus
2373 "aplusplus;")
2375 (test-ps-js astarstar
2377 "astarstar;")
2379 (test-ps-js switch-return-fallthrough
2380 (defun foo ()
2381 (switch x
2382 (1 (foo) break)
2383 (2 (bar))
2384 (default 4)))
2385 "function foo() {
2386 switch (x) {
2387 case 1:
2388 return foo();
2389 case 2:
2390 bar();
2391 default:
2392 return 4;
2394 };")
2396 (test-ps-js return-last-case
2397 (defun foo ()
2398 (case x
2399 (:a 'eh)
2400 (:b 'bee)))
2401 "function foo() {
2402 switch (x) {
2403 case 'a':
2404 return 'eh';
2405 case 'b':
2406 return 'bee';
2408 };")
2410 (test-ps-js return-macrolet
2411 (defun foo ()
2412 (macrolet ((x () 1))
2413 (case (x)
2414 (:a 'eh)
2415 (:b 'bee))))
2416 "function foo() {
2417 switch (1) {
2418 case 'a':
2419 return 'eh';
2420 case 'b':
2421 return 'bee';
2423 };")
2425 (test-ps-js mv-bind1
2426 (multiple-value-bind (a b)
2427 (progn
2428 (returns-mv)
2429 (doesnt))
2430 (alert a)
2431 (alert b))
2432 "returnsMv();
2433 (function () {
2434 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2435 try {
2436 var a = doesnt();
2437 var _db2 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2438 var b = _db2[0];
2439 alert(a);
2440 return alert(b);
2441 } finally {
2442 __PS_MV_REG = prevMv1;
2444 })();")
2446 (test-ps-js mv-bind2
2447 (multiple-value-bind (a b)
2448 (let ((a 1))
2449 (returns-mv a)
2450 (doesnt b))
2451 (alert a)
2452 (alert b))
2453 "(function () {
2454 var a = 1;
2455 returnsMv(a);
2456 var prevMv2 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2457 try {
2458 var a3 = doesnt(b);
2459 var _db4 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2460 var b = _db4[0];
2461 alert(a3);
2462 return alert(b);
2463 } finally {
2464 __PS_MV_REG = prevMv2;
2466 })();")
2468 (test-ps-js multiple-value-bind-simple
2469 (multiple-value-bind (a b) (blah)
2470 (+ a b))
2471 "(function () {
2472 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2473 try {
2474 var a = blah();
2475 var _db2 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2476 var b = _db2[0];
2477 return a + b;
2478 } finally {
2479 __PS_MV_REG = prevMv1;
2481 })();")
2483 (test-ps-js values0
2484 (lambda () (values))
2485 "(function () {
2486 __PS_MV_REG = {};
2487 return null;
2488 });")
2490 (test-ps-js values1
2491 (values x)
2492 "x;")
2494 (test-ps-js values2
2495 (lambda () (values x y))
2496 "(function () {
2497 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2498 return x;
2499 });")
2501 (test-ps-js values3
2502 (lambda () (values x y z))
2503 "(function () {
2504 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2505 return x;
2506 });")
2508 (test-ps-js values-return
2509 (defun foo (x y)
2510 (return-from foo (values (* x x) y)))
2511 "function foo(x, y) {
2512 var val1_1 = x * x;
2513 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2514 return val1_1;
2515 };")
2517 (test-ps-js return-macrolet1
2518 (defun foo ()
2519 (symbol-macrolet ((x 2))
2520 (loop do (+ x x))))
2521 "function foo() {
2522 while (true) {
2523 2 + 2;
2525 };")
2527 (test-ps-js return-cond
2528 (defun foo ()
2529 (return-from foo
2530 (cond ((foo? x) (loop for y in x do (foo y)))
2531 ((bar? x) x)
2532 (t 3))))
2533 "function foo() {
2534 if (foowhat(x)) {
2535 var _js2 = x.length;
2536 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2537 var y = x[_js1];
2538 foo(y);
2540 } else if (barwhat(x)) {
2541 return x;
2542 } else {
2543 return 3;
2545 };")
2547 (test-ps-js return-case
2548 (defun foo ()
2549 (return-from foo
2550 (case x
2551 (1 (loop for y in x do (foo y)))
2552 (2 x)
2553 ((t) 3))))
2554 "function foo() {
2555 switch (x) {
2556 case 1:
2557 var _js2 = x.length;
2558 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2559 var y = x[_js1];
2560 foo(y);
2562 return;
2563 case 2:
2564 return x;
2565 case true:
2566 return 3;
2568 };")
2570 (test-ps-js return-case1
2571 (defun foo ()
2572 (return-from foo
2573 (case x
2574 (1 (if a 1 2))
2575 (2 x)
2576 ((t) 3))))
2577 "function foo() {
2578 switch (x) {
2579 case 1:
2580 return a ? 1 : 2;
2581 case 2:
2582 return x;
2583 case true:
2584 return 3;
2586 };")
2588 (test-ps-js lambda-loop-if-return
2589 (lambda ()
2590 (if a
2591 (loop for y in x do (foo y))
2593 "(function () {
2594 if (a) {
2595 var _js4 = x.length;
2596 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2597 var y = x[_js3];
2598 foo(y);
2600 } else {
2601 return c;
2603 });")
2605 (test-ps-js lambda-loop-if-return1
2606 (defun baz ()
2607 (foo (lambda ()
2608 (if a
2609 (progn (loop for y in x do (foo y))
2610 (return-from baz))
2611 c))))
2612 "function baz() {
2613 try {
2614 return foo(function () {
2615 if (a) {
2616 var _js4 = x.length;
2617 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2618 var y = x[_js3];
2619 foo(y);
2621 throw { '__ps_block_tag' : 'baz',
2622 '__ps_value1' : null };
2623 } else {
2624 return c;
2627 } catch (_ps_err5) {
2628 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2629 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2630 return _ps_err5['__ps_value1'];
2631 } else {
2632 throw _ps_err5;
2635 };")
2637 (test-ps-js switch-loop
2638 (defun foo (x)
2639 (case x
2640 (1 (dolist (a b)))))
2641 "function foo(x) {
2642 switch (x) {
2643 case 1:
2644 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2645 a = b[_js_idx1];
2647 return;
2649 };")
2651 (test-ps-js switch-folds-blocks
2652 (defun foo ()
2653 (case x
2654 (1 (loop repeat 3 do (alert "foo")))
2655 (2 "bar")))
2656 "function foo() {
2657 switch (x) {
2658 case 1:
2659 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2660 alert('foo');
2662 return;
2663 case 2:
2664 return 'bar';
2666 };")
2668 (test-ps-js setf-places-before-macros
2669 (lambda ()
2670 (defsetf left (el) (offset)
2671 `(setf (@ ,el style left) ,offset))
2672 (macrolet ((left (el)
2673 `(@ ,el offset-left)))
2674 (setf (left x) 10)
2675 (left x)))
2676 "(function () {
2677 var _js2 = x;
2678 var _js1 = 10;
2679 _js2.style.left = _js1;
2680 return x.offsetLeft;
2681 });")
2683 (test-ps-js for-return
2684 (lambda () (dolist (arg args) (foo arg)))
2685 "(function () {
2686 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2687 arg = args[_js_idx1];
2688 foo(arg);
2690 });")
2692 (test-ps-js try-catch-return
2693 (defun foo ()
2694 (try (foo)
2695 (:catch (e)
2696 (bar))
2697 (:finally
2698 (cleanup))))
2699 "function foo() {
2700 try {
2701 return foo();
2702 } catch (e) {
2703 return bar();
2704 } finally {
2705 cleanup();
2707 };")
2709 (test-ps-js let-try
2710 (let ((x (ps:try (+ 1 2)
2711 (:catch (y) 5))))
2713 "(function () {
2714 var x = (function () {
2715 try {
2716 return 1 + 2;
2717 } catch (y) {
2718 return 5;
2720 })();
2721 return x;
2722 })();")
2724 (test-ps-js try-finally-return-from
2725 (defun xyz ()
2726 (return-from xyz
2727 (ps:try (when (blah) 4)
2728 (:finally (foo))))
2729 (dont-call-me))
2730 "function xyz() {
2731 try {
2732 return blah() ? 4 : null;
2733 } finally {
2734 foo();
2736 return dontCallMe();
2737 };")
2739 (test-ps-js defun-setf-optional
2740 (defun (setf foo) (new-value b &optional c)
2741 (setf (aref b (or c 0)) new-value))
2742 "function __setf_foo(newValue, b, c) {
2743 return b[c || 0] = newValue;
2744 };")
2746 (test-ps-js defun-setf-rest
2747 (progn (defun (setf foo) (new-value b &rest foo)
2748 (do-something b foo new-value))
2749 (setf (foo x 1 2 3 4) 5))
2750 "function __setf_foo(newValue, b) {
2751 var foo = Array.prototype.slice.call(arguments, 2);
2752 return doSomething(b, foo, newValue);
2754 __setf_foo(5, x, 1, 2, 3, 4);")
2756 (test-ps-js return-null
2757 (defun foo () (return-from foo nil))
2758 "function foo() {
2759 return null;
2760 };")
2762 (test-ps-js implicit-return-null
2763 (lambda ()
2765 "(function () {
2766 return null;
2767 });")
2769 (test-ps-js implicit-return-null
2770 (lambda ()
2771 nil)
2772 "(function () {
2773 return null;
2774 });")
2776 (test-ps-js return-conditional-nested
2777 (defun blep (ss x y)
2778 (when foo?
2779 (let ((pair (bar)))
2780 (unless (null pair)
2781 (destructuring-bind (a b) pair
2782 (unless (or (null a) (null b))
2783 (let ((val (baz a b)))
2784 (unless (null val)
2785 (when (blah val)
2786 (unless (blee)
2787 t))))))))))
2788 "function blep(ss, x, y) {
2789 if (foowhat) {
2790 var pair = bar();
2791 if (pair != null) {
2792 var a = pair[0];
2793 var b = pair[1];
2794 if (!(a == null || b == null)) {
2795 var val = baz(a, b);
2796 if (val != null) {
2797 if (blah(val)) {
2798 return !blee() ? true : null;
2804 };")
2806 (test-ps-js return-when-returns-broken-return
2807 (defun foo ()
2808 (return-from foo (when x 1))
2809 (+ 2 3))
2810 "function foo() {
2811 return x ? 1 : null;
2812 return 2 + 3;
2813 };")
2815 (test-ps-js return-case-conditional
2816 (defun foo ()
2817 (return-from foo
2818 (case foo
2819 (123 (when (bar) t))
2820 (345 (blah)))))
2821 "function foo() {
2822 switch (foo) {
2823 case 123:
2824 return bar() ? true : null;
2825 case 345:
2826 return blah();
2828 };")
2830 (test-ps-js return-try-conditional
2831 (defun foo ()
2832 (return-from foo
2833 (try (when x 1)
2834 (:catch (x) 2)
2835 (:finally (bar)))))
2836 "function foo() {
2837 try {
2838 return x ? 1 : null;
2839 } catch (x) {
2840 return 2;
2841 } finally {
2842 bar();
2844 };")
2846 (test-ps-js function-declare-special
2847 (lambda ()
2848 (declare (special *foo*))
2849 (let ((*foo* 1))
2850 (1+ *foo*)))
2851 "(function () {
2852 var FOO_TMPSTACK1;
2853 try {
2854 FOO_TMPSTACK1 = FOO;
2855 FOO = 1;
2856 return FOO + 1;
2857 } finally {
2858 FOO = FOO_TMPSTACK1;
2860 });")
2862 (test-ps-js declare-special-let
2863 (let ((*foo* 123))
2864 (declare (special *foo*))
2865 (blah))
2866 "(function () {
2867 var FOO_TMPSTACK1;
2868 try {
2869 FOO_TMPSTACK1 = FOO;
2870 FOO = 123;
2871 return blah();
2872 } finally {
2873 FOO = FOO_TMPSTACK1;
2875 })();")
2877 (test-ps-js declare-special-let-scope
2878 (block nil
2879 (let ((*foo* 123))
2880 (declare (special *foo*))
2881 (blah))
2882 (let ((*foo* 456))
2883 (+ 4 5)))
2884 "(function () {
2885 var FOO_TMPSTACK1;
2886 try {
2887 FOO_TMPSTACK1 = FOO;
2888 FOO = 123;
2889 blah();
2890 } finally {
2891 FOO = FOO_TMPSTACK1;
2893 var FOO = 456;
2894 return 4 + 5;
2895 })();")
2897 (test-ps-js declare-special-let*
2898 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
2899 (declare (special *foo* *bar*))
2900 (blah))
2901 "(function () {
2902 var FOO_TMPSTACK1;
2903 try {
2904 FOO_TMPSTACK1 = FOO;
2905 FOO = 123;
2906 var BAR_TMPSTACK2;
2907 try {
2908 BAR_TMPSTACK2 = BAR;
2909 BAR = FOO + BAR;
2910 return blah();
2911 } finally {
2912 BAR = BAR_TMPSTACK2;
2914 } finally {
2915 FOO = FOO_TMPSTACK1;
2917 })();")
2919 (test-ps-js defun-multiple-declarations-around-docstring
2920 (defun foo (x y)
2921 (declare (ignorable x y))
2922 (declare (integer x) (float y))
2923 "Fooes X while barring Y."
2924 (declare (special *foo*) (special *bar*))
2925 (let ((*bar* (bar y)))
2926 (funcall *foo* x)))
2927 "/** Fooes X while barring Y. */
2928 function foo(x, y) {
2929 var BAR_TMPSTACK1;
2930 try {
2931 BAR_TMPSTACK1 = BAR;
2932 BAR = bar(y);
2933 return FOO(x);
2934 } finally {
2935 BAR = BAR_TMPSTACK1;
2937 };")
2939 (test-ps-js macro-null-toplevel
2940 (progn
2941 (defmacro macro-null-toplevel ()
2942 nil)
2943 (macro-null-toplevel))
2946 (test-ps-js define-symbol-macro-let
2947 (progn
2948 (define-symbol-macro test-symbol-macro 1)
2949 (let ((test-symbol-macro 2))
2950 (1+ test-symbol-macro))
2951 (1+ test-symbol-macro))
2952 "(function () {
2953 var testSymbolMacro1 = 2;
2954 return testSymbolMacro1 + 1;
2955 })();
2956 1 + 1;")
2958 (test-ps-js define-symbol-macro-flet
2959 (progn
2960 (define-symbol-macro test-symbol-macro1 1)
2961 (flet ((test-symbol-macro1 () 2))
2962 (foo test-symbol-macro1)
2963 (test-symbol-macro1))
2964 (bar test-symbol-macro1))
2965 "(function () {
2966 var testSymbolMacro1_1 = function () {
2967 return 2;
2969 foo(1);
2970 return testSymbolMacro1_1();
2971 })();
2972 bar(1);")
2974 (fiveam:test compile-stream-nulls
2975 (fiveam:is
2976 (string=
2977 (with-input-from-string (s "
2978 (defmacro macro-null-toplevel ()
2979 nil)
2980 (macro-null-toplevel)")
2981 (ps-compile-stream s))
2982 "")))
2984 (fiveam:test compile-stream1
2985 (fiveam:is
2986 (string=
2987 (with-input-from-string (s "
2988 (define-symbol-macro test-symbol-macro1 1)
2989 (flet ((test-symbol-macro1 () 2))
2990 (foo test-symbol-macro1)
2991 (test-symbol-macro1))
2992 (bar test-symbol-macro1)")
2993 (ps::with-blank-compilation-environment
2994 (ps-compile-stream s)))
2995 "(function () {
2996 var testSymbolMacro1_1 = function () {
2997 return 2;
2999 foo(1);
3000 return testSymbolMacro1_1();
3001 })();
3002 bar(1);
3003 ")))
3005 (test-ps-js equality-nary1
3006 (let ((x 10) (y 10) (z 10))
3007 (= x y z))
3008 "(function () {
3009 var _cmp1;
3010 var x = 10;
3011 var y = 10;
3012 var z = 10;
3013 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3014 })();")
3016 (test-ps-js equality1
3017 (progn
3018 (equal a b)
3019 (eql a b)
3020 (eq a b)
3021 (= a b))
3022 "a == b;
3023 a === b;
3024 a === b;
3025 a === b;")
3027 (test-ps-js getprop-quote-reserved
3028 (getprop foo ':break)
3029 "foo['break'];")
3031 (test-ps-js defun-block-return-from
3032 (defun foo (x)
3033 (baz 4)
3034 (return-from foo x)
3035 (bar 5))
3036 "function foo(x) {
3037 baz(4);
3038 return x;
3039 return bar(5);
3040 };")
3042 (test-ps-js block-return-from
3043 (block scope
3044 (foo)
3045 (when (bar)
3046 (return-from scope))
3047 (blee))
3048 "(function () {
3049 foo();
3050 if (bar()) {
3051 return null;
3053 return blee();
3054 })();")
3056 (test-ps-js block-return-from0
3057 (defun baz ()
3058 (block scope
3059 (foo)
3060 (when (bar)
3061 (return-from scope))
3062 (blee)))
3063 "function baz() {
3064 foo();
3065 if (bar()) {
3066 return null;
3068 return blee();
3069 };")
3071 (test-ps-js block-return-from01
3072 (defun baz ()
3073 (block scope
3074 (foo)
3075 (when (bar)
3076 (return-from scope))
3077 (blee))
3079 "function baz() {
3080 scope: {
3081 foo();
3082 if (bar()) {
3083 break scope;
3085 blee();
3087 return 2;
3088 };")
3090 (test-ps-js block-return-from02
3091 (defun baz ()
3092 (block scope
3093 (foo)
3094 (when (bar)
3095 (return-from scope (foobar)))
3096 (blee))
3098 "function baz() {
3099 scope: {
3100 foo();
3101 if (bar()) {
3102 foobar();
3103 break scope;
3105 blee();
3107 return 2;
3108 };")
3110 (test-ps-js block-return-from1
3111 (lambda ()
3112 (block scope
3113 (foo)
3114 (when (bar)
3115 (return-from scope))
3116 (blee))
3117 (+ 1 2))
3118 "(function () {
3119 scope: {
3120 foo();
3121 if (bar()) {
3122 break scope;
3124 blee();
3126 return 1 + 2;
3127 });")
3129 (test-ps-js block-return-from2
3130 (lambda ()
3131 (bar 5)
3132 (block scope
3133 (foo)
3134 (when (bar)
3135 (return-from scope 6))
3136 (blee)))
3137 "(function () {
3138 bar(5);
3139 foo();
3140 if (bar()) {
3141 return 6;
3143 return blee();
3144 });")
3146 (test-ps-js let-funcall
3147 (let ((x foo))
3148 (funcall x)
3149 (let ((x bar))
3150 (funcall x))
3151 (funcall x))
3152 "(function () {
3153 var x = foo;
3154 x();
3155 var x1 = bar;
3156 x1();
3157 return x();
3158 })();")
3160 (test-ps-js symbol-macrolet-funcall
3161 (symbol-macrolet ((foo bar))
3162 (funcall foo 1 2 3))
3163 "bar(1, 2, 3);")
3165 (test-ps-js times-assign
3166 (setf x (* x 1000))
3167 "x *= 1000;")
3169 (test-ps-js vector-literal
3170 #(1 2 3)
3171 "[1, 2, 3];")
3173 (test-ps-js vector-literal1
3174 #(1 2 #(a b) 3)
3175 "[1, 2, ['a', 'b'], 3];")
3177 (test-ps-js rem1
3178 (+ 1 (rem 2 (+ 3 4)))
3179 "1 + 2 % (3 + 4);")
3181 (test-ps-js non-associative
3182 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3183 "1 / (2 / 3) + (1 - (2 - 3));")
3185 (test-ps-js lambda-apply
3186 (lambda (x)
3187 (apply (lambda (y) (bar (1+ y))) x))
3188 "(function (x) {
3189 return (function (y) {
3190 return bar(y + 1);
3191 }).apply(this, x);
3192 });")
3194 (test-ps-js operator-expressions-nested-let
3195 (let ((x (let ((y 1))
3196 y)))
3198 "(function () {
3199 var y;
3200 var x = (y = 1, y);
3201 return x;
3202 })();")
3204 (test-ps-js operator-expressions-array-nested-let
3205 (list (let ((y 1)) y) 2)
3206 "[(function () {
3207 var y = 1;
3208 return y;
3209 })(), 2];")
3211 (test-ps-js add-subtract-precedence
3212 (- x (+ y z))
3213 "x - (y + z);")
3215 (test-ps-js ps-inline-toplevel
3216 (ps-inline (foo))
3217 "'javascript:' + 'foo()';")
3219 (test-ps-js no-clause-progn-exp
3220 (setf x (progn))
3221 "x = null;")
3223 (test-ps-js no-clause-progn-return
3224 (defun foo ()
3225 (return-from foo (progn)))
3226 "function foo() {
3227 return null;
3228 };")
3230 (test-ps-js empty-cond-clause
3231 (setf x (cond ((foo))))
3232 "x = (function () { var testResult1 = foo(); return testResult1 ? testResult1 : null; })();")
3234 (test-ps-js empty-cond-clause1
3235 (setf x (cond ((foo) 123)
3236 ((bar))
3237 (t 456)))
3238 "x = foo() ? 123 :
3239 (function () {
3240 var testResult1 = bar();
3241 if (testResult1) {
3242 return testResult1;
3243 } else {
3244 if (true) { return 456; };
3246 })();")
3248 (test-ps-js let-no-body
3249 (defun foo ()
3250 (return-from foo (let ((foo bar)))))
3251 "function foo() {
3252 var foo1 = bar;
3253 return null;
3254 };")
3256 (test-ps-js rename-lexical-dupes
3257 (lambda ()
3258 (list (let ((foo 12)) (* foo 2))
3259 (let ((foo 13)) (* foo 3))))
3260 "(function () {
3261 var foo;
3262 var foo1;
3263 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3264 });")
3266 (test-ps-js defun-comment1
3267 (defun foo (x)
3268 "BARBAR is a revolutionary new foobar.
3269 X y and x."
3270 (1+ x))
3271 "/**
3272 * BARBAR is a revolutionary new foobar.
3273 * X y and x.
3275 function foo(x) {
3276 return x + 1;
3277 };")
3279 (test-ps-js var-comment
3280 (var x 1 "foo")
3281 "/** foo */
3282 var x = 1;")
3284 (test-ps-js case-return-break-broken-return
3285 (defun foo ()
3286 (case x
3287 ("bar" (if y (return-from foo t) nil))
3288 ("baz" nil)))
3289 "function foo() {
3290 switch (x) {
3291 case 'bar':
3292 if (y) {
3293 return true;
3294 } else {
3295 return null;
3297 case 'baz':
3298 return null;
3300 };")
3302 (test-ps-js case-return-break1-broken-return
3303 (defun foo ()
3304 (case x
3305 ("bar" (if y (return-from foo t)))
3306 ("baz" nil)))
3307 "function foo() {
3308 switch (x) {
3309 case 'bar':
3310 if (y) {
3311 return true;
3312 } else {
3313 return null;
3315 case 'baz':
3316 return null;
3318 };")
3320 (test-ps-js setf-progn
3321 (setf foo (progn (bar) (baz) 3))
3322 "bar();
3323 baz();
3324 foo = 3;")
3326 (test-ps-js var-progn
3327 (var x (progn (foo) (bar)))
3328 "foo();
3329 var x = bar();")
3331 (test-ps-js implicit-return-loop
3332 (lambda ()
3333 (if baz 7
3334 (progn
3335 (loop :repeat 100 :do (bar))
3336 42)))
3337 "(function () {
3338 if (baz) {
3339 return 7;
3340 } else {
3341 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3342 bar();
3344 return 42;
3346 });")
3348 (test-ps-js loop-closures
3349 (dotimes (i 10) (lambda () (+ i 1)))
3350 "(function () {
3351 for (var i = 0; i < 10; i += 1) {
3352 function () {
3353 return i + 1;
3356 })();")
3358 (test-ps-js loop-closures-let
3359 (dotimes (i 10)
3360 (let ((x (+ i 1)))
3361 (lambda () (+ i x))))
3362 "(function () {
3363 for (var i = 0; i < 10; i += 1) {
3364 with ({ x : null }) {
3365 var x = i + 1;
3366 function () {
3367 return i + x;
3371 })();")
3373 (test-ps-js loop-closures-flet
3374 (dotimes (i 10)
3375 (flet ((foo (x) (+ i x)))
3376 (lambda () (foo i))))
3377 "(function () {
3378 for (var i = 0; i < 10; i += 1) {
3379 with ({ foo : null }) {
3380 var foo = function (x) {
3381 return i + x;
3383 function () {
3384 return foo(i);
3388 })();")
3390 (test-ps-js while-closures-let
3391 (while (foo)
3392 (let ((abc (bar)))
3393 (lambda () (+ 1 abc))))
3394 "while (foo()) {
3395 with ({ abc : null }) {
3396 var abc = bar();
3397 function () {
3398 return 1 + abc;
3401 };")
3403 (test-ps-js dotted-list-form
3404 (defun foo (a)
3405 (when a
3406 (destructuring-bind (b . c)
3408 (list b c))))
3409 "function foo(a) {
3410 if (a) {
3411 var b = bar[0];
3412 var c = bar.length > 1 ? bar.slice(1) : [];
3413 return [b, c];
3415 };")
3417 (test-ps-js explicit-nil-block
3418 (defun bar ()
3419 (foo 1)
3420 (block nil (return (foo 2)) (+ 1 2))
3422 "function bar() {
3423 foo(1);
3424 nilBlock: {
3425 foo(2);
3426 break nilBlock;
3427 1 + 2;
3429 return 2;
3430 };")
3432 (test-ps-js dynamic-extent-function-return
3433 (defun foo ()
3434 ((lambda ()
3435 (return-from foo 6))))
3436 "function foo() {
3437 try {
3438 return (function () {
3439 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3440 })();
3441 } catch (_ps_err1) {
3442 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3443 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3444 return _ps_err1['__ps_value1'];
3445 } else {
3446 throw _ps_err1;
3449 };")
3451 (test-ps-js dynamic-extent-function-return-nothing
3452 (defun foo ()
3453 ((lambda ()
3454 (return-from foo))))
3455 "function foo() {
3456 try {
3457 return (function () {
3458 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3459 })();
3460 } catch (_ps_err1) {
3461 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3462 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3463 return _ps_err1['__ps_value1'];
3464 } else {
3465 throw _ps_err1;
3468 };")
3470 (test-ps-js dynamic-extent-function-return-values
3471 (defun foo ()
3472 ((lambda ()
3473 (return-from foo (values 1 2 3)))))
3474 "function foo() {
3475 try {
3476 __PS_MV_REG = {};
3477 return (function () {
3478 throw { '__ps_block_tag' : 'foo',
3479 '__ps_value1' : 1,
3480 '__ps_values' : [2, 3] };
3481 })();
3482 } catch (_ps_err1) {
3483 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3484 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3485 return _ps_err1['__ps_value1'];
3486 } else {
3487 throw _ps_err1;
3490 };")
3492 (test-ps-js dynamic-extent-function-return-funcall
3493 (defun foo ()
3494 ((lambda ()
3495 (return-from foo (if baz 6 5)))))
3496 "function foo() {
3497 try {
3498 return (function () {
3499 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3500 })();
3501 } catch (_ps_err1) {
3502 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3503 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3504 return _ps_err1['__ps_value1'];
3505 } else {
3506 throw _ps_err1;
3509 };")
3511 (test-ps-js block-dynamic-return
3512 (var foo ((lambda ()
3513 (block nil
3514 ((lambda () (return 6)))
3515 (+ 1 2)))))
3516 "var foo = (function () {
3517 try {
3518 (function () {
3519 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3520 })();
3521 return 1 + 2;
3522 } catch (_ps_err1) {
3523 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3524 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3525 return _ps_err1['__ps_value1'];
3526 } else {
3527 throw _ps_err1;
3530 })();")
3532 (test-ps-js block-dynamic-return1
3533 (var foo ((lambda ()
3534 (block nil
3535 ((lambda () (return 6)))
3536 (+ 1 2))
3537 (foobar 1 2))))
3538 "var foo = (function () {
3539 nilBlock: {
3540 (function () {
3541 break nilBlock;
3542 })();
3543 1 + 2;
3545 return foobar(1, 2);
3546 })();")
3548 (test-ps-js iteration-lambda-capture-no-need
3549 (dolist (x y)
3550 (lambda (x) (1+ x)))
3551 "(function () {
3552 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3553 x = y[_js_idx1];
3554 function (x) {
3555 return x + 1;
3558 })();")
3560 (test-ps-js case-invert1
3561 (encodeURIComponent fooBar)
3562 "encodeURIComponent(fooBar);")
3564 (test-ps-js simple-ash
3565 (+ (ash 4 1) (ash 4 -1))
3566 "(4 << 1) + (4 >> 1);")
3568 (test-ps-js progn-nil-expression
3569 (bar (progn (foo) nil))
3570 "bar((foo(), null));")
3572 (test-ps-js other-progn-nil-exp
3573 (defun blah ()
3574 (or (foo) (progn (bar) nil)))
3575 "function blah() {
3576 return foo() || (bar(), null);
3577 };")
3579 (test-ps-js lambda-nil-return
3580 (lambda (x)
3581 (block nil
3582 (when x
3583 (return 1))
3585 "(function (x) {
3586 if (x) {
3587 return 1;
3589 return 2;
3590 });")
3592 (test-ps-js lambda-nil-return-implicit-nested2
3593 (lambda (x)
3594 (block foo
3595 (if x
3596 (return-from foo 1)
3597 (dotimes (i 4)
3598 (return-from foo i)))
3600 "(function (x) {
3601 if (x) {
3602 return 1;
3603 } else {
3604 for (var i = 0; i < 4; i += 1) {
3605 return i;
3608 return 2;
3609 });")
3611 (test-ps-js throw-is-a-statement
3612 (defun blah ()
3613 (let ((result (foo)))
3614 (unless (null result)
3615 (throw result))))
3616 "function blah() {
3617 var result = foo();
3618 if (result != null) {
3619 throw result;
3621 };")
3623 (test-ps-js expressify1
3624 (defun blah ()
3625 (when (some-condition)
3626 (foo)
3627 (bar)
3628 (baz)))
3629 "function blah() {
3630 if (someCondition()) {
3631 foo();
3632 bar();
3633 return baz();
3635 };")
3637 (test-ps-js case-when-return
3638 (defun blah (a)
3639 (case a
3640 ("a" (when (foo) (return-from blah 111)))
3641 ("b" t)))
3642 "function blah(a) {
3643 switch (a) {
3644 case 'a':
3645 if (foo()) {
3646 return 111;
3647 } else {
3648 return null;
3650 case 'b':
3651 return true;
3653 };")
3655 (test-ps-js flet-return-from
3656 (defun abc ()
3657 (flet ((foo ()
3658 (return-from foo 123)))
3659 (foo)))
3660 "function abc() {
3661 var foo = function () {
3662 return 123;
3664 return foo();
3665 };")
3667 (test-ps-js flet-return-from1
3668 (flet ((foo ()
3669 (return-from foo 123)))
3670 (foo))
3671 "(function () {
3672 var foo = function () {
3673 return 123;
3675 return foo();
3676 })();")
3678 (test-ps-js lambda-docstring-declarations
3679 (lambda (x)
3680 "This is a docstring"
3681 (declare (ignore x))
3683 "(function (x) {
3684 return 2;
3685 });")
3687 (test-ps-js setf-let-exp
3688 (setf foo (let ((x (+ 1 2)))
3689 (if x 123 456)))
3690 "foo = (function () {
3691 var x = 1 + 2;
3692 return x ? 123 : 456;
3693 })();")
3695 (test-ps-js create-let-exp
3696 (create :abc (let ((x (+ 1 2)))
3697 (if x 123 456)))
3698 "({ 'abc' : (function () {
3699 var x = 1 + 2;
3700 return x ? 123 : 456;
3701 })() });")
3703 (test-ps-js eql-eql-eql-precedence
3704 (unless (equal (= 3 3) (= 3 4))
3705 (chain console (log 1)))
3706 "if ((3 === 3) != (3 === 4)) {
3707 console.log(1);
3708 };")
3710 (test-ps-js case-cond-breaks
3711 (defun blah (x)
3712 (case x
3713 (123 (cond ((foo1)
3714 (when (foo2)
3715 (when (foo3)
3716 (return-from blah nil))
3717 t))))
3718 (456 (foo7))))
3719 "function blah(x) {
3720 switch (x) {
3721 case 123:
3722 if (foo1()) {
3723 if (foo2()) {
3724 if (foo3()) {
3725 return null;
3727 return true;
3728 } else {
3729 return null;
3731 } else {
3732 return null;
3734 case 456:
3735 return foo7();
3737 };")
3739 (test-ps-js cond-double-t
3740 (lambda ()
3741 (cond (foo 1)
3742 (t 2)
3743 (t 3)))
3744 "(function () {
3745 if (foo) {
3746 return 1;
3747 } else {
3748 return 2;
3750 });")
3752 (test-ps-js let-let-funcall-lambda
3753 (let ((x 5))
3754 (let ((x 7))
3755 (funcall (lambda (x) (+ x 9)) x)))
3756 "(function () {
3757 var x = 5;
3758 var x1 = 7;
3759 return (function (x) {
3760 return x + 9;
3761 })(x1);
3762 })();")
3764 (test-ps-js let-let-lambda
3765 (let ((x 5))
3766 (let ((x 7))
3767 (lambda (x) (+ x 9))))
3768 "(function () {
3769 var x = 5;
3770 var x1 = 7;
3771 return function (x) {
3772 return x + 9;
3774 })();")
3776 (test-ps-js let-lambda
3777 (let ((x 5))
3778 (lambda (x) (+ x 9)))
3779 "(function () {
3780 var x = 5;
3781 return function (x) {
3782 return x + 9;
3784 })();")
3786 (test-ps-js symbol-macrolet-no-shadow-lambda
3787 (symbol-macrolet ((x y))
3788 (lambda (x) (+ x x)))
3789 "(function (x) {
3790 return x + x;
3791 });")
3793 (test-ps-js divide-one-arg-reciprocal
3794 (/ 2)
3795 "1 / 2;")
3797 (test-ps-js division-not-associative
3798 (/ a (* b c))
3799 "a / (b * c);")
3801 (test-ps-js divide-expressions
3802 (/ (foo) (bar))
3803 "foo() / bar();")
3805 (test-ps-js divide-expressions1
3806 (floor (1- x) y)
3807 "Math.floor((x - 1) / y);")
3809 (test-ps-js lexical-funargs-shadow1
3810 (lambda (x)
3811 (let ((x 1))
3812 (foo x))
3813 (incf x))
3814 "(function (x) {
3815 var x1 = 1;
3816 foo(x1);
3817 return ++x;
3818 });")
3820 (test-ps-js times-rem
3821 (* x (rem y z))
3822 "x * (y % z);")
3824 (test-ps-js rem-divide
3825 (/ x (rem y z))
3826 "x / (y % z);")
3828 (test-ps-js case-break-return
3829 (lambda () (case x (:foo) (:bar 1)))
3830 "(function () {
3831 switch (x) {
3832 case 'foo':
3833 return null;
3834 case 'bar':
3835 return 1;
3837 });")
3839 (test-ps-js trivial-expression-switch
3840 (foobar (case x (1 2)))
3841 "foobar((function () {
3842 switch (x) {
3843 case 1:
3844 return 2;
3846 })());")
3848 (test-ps-js trivial-expression-while
3849 (foobar (while (< 0 x) (decf x)))
3850 "foobar((function () {
3851 while (0 < x) {
3852 --x;
3854 })());")
3856 (test-ps-js funcall-block-expression-loop-lambda
3857 (foobar (loop for i from 0 to 10 do (1+ i)))
3858 "foobar((function () {
3859 for (var i = 0; i <= 10; i += 1) {
3860 i + 1;
3862 })());")
3864 (test-ps-js plus-block-expression-loop-lambda
3865 (1+ (loop for i from 0 to 10 do (1+ i)))
3866 "(function () {
3867 for (var i = 0; i <= 10; i += 1) {
3868 i + 1;
3870 })() + 1;")
3872 (test-ps-js let-closures-rename
3873 (lambda ()
3874 (let ((x 1)) (lambda () (1+ x)))
3875 (let ((x 2)) (lambda () (1+ x))))
3876 "(function () {
3877 var x = 1;
3878 function () {
3879 return x + 1;
3881 var x1 = 2;
3882 return function () {
3883 return x1 + 1;
3885 });")
3887 (test-ps-js let-closures-rename1
3888 (lambda ()
3889 (let ((x 1))
3890 (let ((y 2))
3891 (lambda () (+ x y))))
3892 (let ((x 2))
3893 (let ((y 3))
3894 (lambda () (+ x y)))))
3895 "(function () {
3896 var x = 1;
3897 var y = 2;
3898 function () {
3899 return x + y;
3901 var x1 = 2;
3902 var y2 = 3;
3903 return function () {
3904 return x1 + y2;
3906 });")
3908 (test-ps-js let-closures-rename2
3909 (defun make-closures ()
3910 (list
3911 (let ((x 1)) (lambda () (1+ x)))
3912 (let ((x 2)) (lambda () (1+ x)))))
3913 "function makeClosures() {
3914 var x;
3915 var x1;
3916 return [(x = 1, function () {
3917 return x + 1;
3918 }), (x1 = 2, function () {
3919 return x1 + 1;
3920 })];
3922 };")
3924 (test-ps-js conditional-not-used-up
3925 (lambda (bar)
3926 (when bar
3927 (let ((x 1))
3928 (1+ x))))
3929 "(function (bar) {
3930 if (bar) {
3931 var x = 1;
3932 return x + 1;
3934 });")
3936 (test-ps-js toplevel-local-scope
3937 (create "fn" (let ((x 5)) (lambda () x)))
3938 "({ 'fn' : (function () {
3939 var x = 5;
3940 return function () {
3941 return x;
3943 })() });")
3945 (test-ps-js toplevel-local-scope1
3946 (defvar foo (create "fn" (let ((x 5)) (lambda () x))))
3947 "var foo = { 'fn' : (function () {
3948 var x = 5;
3949 return function () {
3950 return x;
3952 })() };")
3954 (test-ps-js block-let
3955 (block foobar
3956 (let ((x 1))
3957 (return-from foobar x)
3959 "(function () {
3960 var x = 1;
3961 return x;
3962 return 2;
3963 })();")
3965 (test-ps-js expressionize-if-macroexpand-error
3966 (progn (defmacro xbaz () `(blah))
3968 (defun foo (xbaz)
3969 (unless (blah)
3970 (cond (xbaz (blah))
3971 (t (blahblah))))))
3972 "function foo(xbaz) {
3973 if (!blah()) {
3974 if (xbaz) {
3975 return blah();
3976 } else {
3977 return blahblah();
3980 };")
3982 (test-ps-js toplevel-defun-macroexpand
3983 (progn (defmacro defun-js (name lambda-list &body body)
3984 `(defun ,name ,lambda-list ,@body))
3986 (let ((foo 0))
3987 (defun-js bar () (1+ foo))
3988 (defvar baz 2)))
3989 "var foo = 0;
3990 function bar() {
3991 return foo + 1;
3993 var baz = 2;")
3995 (test-ps-js js-ir-package-unique-symbols
3996 (loop :for i :from 0 :below 5 :do
3997 (let ((block (elt blocks i)))
3998 (foo block)
3999 (lambda () nil)))
4000 "(function () {
4001 for (var i = 0; i < 5; i += 1) {
4002 var block = blocks[i];
4003 foo(block);
4004 function () {
4005 return null;
4008 })();")
4010 (test-ps-js broken-quote-expansion1
4011 (lambda (p)
4012 (with-slots (x y) p
4013 (if (< x 0) y x)))
4014 "(function (p) {
4015 return p.x < 0 ? p.y : p.x;
4016 });")
4018 (test-ps-js broken-quote-expansion2
4019 (progn
4020 (define-symbol-macro foo123 (ps:@ a foo123))
4021 (lambda () (when (> foo123 1) 2)))
4022 "(function () {
4023 return a.foo123 > 1 ? 2 : null;
4024 });")
4026 (test-ps-js unused-named-block-not-printed1
4027 (block foobar
4028 (+ 1 2 3))
4029 "(function () {
4030 return 1 + 2 + 3;
4031 })();")
4033 (test-ps-js unused-named-block-not-printed2
4034 (block nil
4035 (block nil
4036 (+ 1 2 3)))
4037 "(function () {
4038 return 1 + 2 + 3;
4039 })();")
4041 (test-ps-js unused-named-block-not-printed3
4042 (block foobar
4043 (block nil
4044 (+ 1 2 3)))
4045 "(function () {
4046 return 1 + 2 + 3;
4047 })();")
4049 (test-ps-js unused-named-block-not-printed4
4050 (block nil
4051 (block foobar
4052 (block nil
4053 (+ 1 2 3))))
4054 "(function () {
4055 return 1 + 2 + 3;
4056 })();")
4058 (test-ps-js trig-no-bind1
4059 (cosh 3.14)
4060 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4062 (test-ps-js trig-bind1
4063 (acosh (blah 3.14))
4064 "(function () {
4065 var x1 = blah(3.14);
4066 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4067 })();")
4069 (test-ps-js double-negation
4070 (or (not foo) (not (not foo)) (not (not (not foo))))
4071 "!foo || foo || !foo;")
4073 (test-ps-js empty-let
4074 (defun foo ()
4075 (let ((a (bar)))))
4076 "function foo() {
4077 var a = bar();
4078 return null;
4079 };")
4081 (test-ps-js empty-let*
4082 (defun foo ()
4083 (let* ((a (bar)))))
4084 "function foo() {
4085 var a = bar();
4086 return null;
4087 };")
4089 (test-ps-js defun-no-body-declare
4090 (defun foo () (declare (ignore x)))
4091 "function foo() {
4092 return null;
4093 };")
4095 (test-ps-js defun-no-body-let-decare
4096 (defun foo () (let () (declare (ignore x))))
4097 "function foo() {
4098 return null;
4099 };")
4101 (test-ps-js empty-defun-docstring-declare
4102 (defun foo (x)
4103 "docstring"
4104 (declare (ignore x)))
4105 "/** docstring */
4106 function foo(x) {
4107 return null;
4108 };")
4110 (test-ps-js defun-docstring-string
4111 (defun foo (x)
4112 "docstring"
4113 "abc")
4114 "/** docstring */
4115 function foo(x) {
4116 return 'abc';
4117 };")
4119 (test-ps-js return-object
4120 (defun foo (obj)
4121 (ps:create :abc (let ((x (ps:getprop obj "blah")))
4122 (if x 123 456))))
4123 "function foo(obj) {
4124 var x;
4125 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4126 };")
4128 (test-ps-js unicode-strings
4129 "фоо бар"
4130 "'фоо бар';")
4132 ;;; broken
4134 ;; (test-ps-js let-defun-toplevel
4135 ;; (progn (let ((foo 0))
4136 ;; (defun bar () foo))
4137 ;; (bar))
4138 ;; "var bar_foo1 = 0;
4139 ;; function bar() {
4140 ;; return bar_foo1;
4141 ;; };
4142 ;; bar();")
4144 ;; (test-ps-js let-defvar-toplevel
4145 ;; (progn (let ((foo 0))
4146 ;; (defvar bar (1+ foo)))
4147 ;; bar)
4148 ;; "var bar_foo1 = 0;
4149 ;; var bar = bar_foo1 + 1;
4150 ;; bar;")
4152 ;; (test-ps-js setf-side-effects
4153 ;; (progn
4154 ;; (let ((x 10))
4155 ;; (defun side-effect()
4156 ;; (setf x 4)
4157 ;; 3)
4158 ;; (setf x (+ 2 (side-effect) x 5))))
4159 ;; "var sideEffect_x1 = 10;
4160 ;; function sideEffect() {
4161 ;; sideEffect_x1 = 4;
4162 ;; return 3;
4163 ;; };
4164 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")