Added more unit tests
[parenscript.git] / tests / output-tests.lisp
blob57c7cabbe50fbccefbd271d781577a7c69c9d286
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 #x000b)) ; vertical tab
1023 (#\n . #\Newline)
1024 (#\r . #\Return)
1025 (#\' . #\')
1026 (#\" . #\")
1027 (#\t . #\Tab)
1028 ("u001F" . ,(code-char #x001f)) ; character below 32
1029 ("u0080" . ,(code-char 128)) ; character over 127
1030 ("uABCD" . ,(code-char #xabcd))))) ; well above ASCII
1031 (loop for (js-escape . lisp-char) in escapes
1032 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
1033 for wanted = (format nil "'hello\\~ahi';" js-escape)
1034 do (fiveam:is (string= generated wanted)))))
1036 (fiveam:test escape-doublequotes
1037 (let ((*js-string-delimiter* #\"))
1038 (fiveam:is (string= (ps-doc* "hello\"hi") "\"hello\\\"\hi\";"))))
1040 (test-ps-js getprop-setf
1041 (setf (getprop x 'y) (+ (+ a 3) 4))
1042 "x.y = (a + 3) + 4;")
1044 (test-ps-js getprop-conditional1
1045 (getprop (if zoo foo bar) 'x)
1046 "(zoo ? foo : bar).x;")
1048 (test-ps-js getprop-conditional2
1049 (getprop (if (not zoo) foo bar) 'x)
1050 "(!zoo ? foo : bar).x;")
1052 (fiveam:test script-star-eval1
1053 (fiveam:is (string=
1054 (normalize-js-output (ps* '(setf x 1) '(setf y 2)))
1055 "x = 1; y = 2;")))
1057 (fiveam:test script-star-eval2
1058 (fiveam:is (string=
1059 (normalize-js-output (ps* '(setf x 1)))
1060 "x = 1;")))
1062 (test-ps-js list-with-single-nil
1063 (array nil)
1064 "[null];")
1066 (test-ps-js quoted-nil-is-array
1067 'nil
1068 "[];")
1070 (test-ps-js quoted-nil-is-array1
1072 "[];")
1074 (test-ps-js literal-nil
1075 (foo ())
1076 "foo(null);")
1078 (test-ps-js quoted-quoted-nil
1079 '(())
1080 "[null];")
1082 (test-ps-js quoted-quoted-nil1
1083 '(1 ())
1084 "[1, null];")
1086 (test-ps-js defsetf1
1087 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1088 (setf (baz 1 2) 3))
1089 "(function () {
1090 var _js2 = 1;
1091 var _js3 = 2;
1092 var _js1 = 3;
1093 return setBaz(_js2, _js3, _js1);
1094 })();")
1096 (test-ps-js setf-macroexpands1
1097 (macrolet ((bar (x y)
1098 `(aref ,x ,y 1)))
1099 (setf (bar foo 2) 3))
1100 "foo[2][1] = 3;")
1102 (test-ps-js defsetf-short
1103 (progn (defsetf baz set-baz "docstring")
1104 (setf (baz 1 2 3) "foo"))
1105 "setBaz(1, 2, 3, 'foo');")
1107 (test-ps-js defun-setf1
1108 (progn (defun (setf some-thing) (new-val i1 i2)
1109 (setf (aref *some-thing* i1 i2) new-val))
1110 (setf (some-thing 1 2) "foo"))
1111 "function __setf_someThing(newVal, i1, i2) {
1112 return SOMETHING[i1][i2] = newVal;
1114 __setf_someThing('foo', 1, 2);")
1116 (test-ps-js defun-optional1
1117 (defun test-opt (&optional x)
1118 (if x "yes" "no"))
1119 "function testOpt(x) {
1120 return x ? 'yes' : 'no';
1121 };")
1123 (test-ps-js defun-optional2
1124 (defun foo (x &optional y)
1125 (+ x y))
1126 "function foo(x, y) {
1127 return x + y;
1128 };")
1130 (test-ps-js defun-optional3
1131 (defun blah (&optional (x 0))
1133 "function blah(x) {
1134 if (x === undefined) {
1135 x = 0;
1137 return x;
1138 };")
1140 (test-ps-js arglist-optional4
1141 (lambda (&optional (x 0 supplied?))
1143 "(function (x) {
1144 var suppliedwhat = x !== undefined;
1145 if (!suppliedwhat) {
1146 x = 0;
1148 return x;
1149 });")
1151 (test-ps-js return-nothing
1152 (defun foo () (return-from foo))
1153 "function foo() {
1154 return null;
1155 };")
1157 (test-ps-js return-values
1158 (defun foo () (return-from foo (values 1 2 3)))
1159 "function foo() {
1160 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [2, 3] };
1161 return 1;
1162 };")
1164 (test-ps-js set-timeout
1165 (set-timeout (lambda () (alert "foo")) 10)
1166 "setTimeout(function () { return alert('foo'); }, 10);")
1168 (test-ps-js operator-precedence
1169 (* 3 (+ 4 5) 6)
1170 "3 * (4 + 5) * 6;")
1172 (test-ps-js operators-1
1173 (in prop obj)
1174 "prop in obj;")
1176 (test-ps-js incf1
1177 (incf foo bar)
1178 "foo += bar;")
1180 (test-ps-js decf1
1181 (decf foo bar)
1182 "foo -= bar;")
1184 (test-ps-js incf2
1185 (incf x 5)
1186 "x += 5;")
1188 (test-ps-js decf2
1189 (decf y 10)
1190 "y -= 10;")
1192 (test-ps-js setf-conditional
1193 (setf foo (if x 1 2))
1194 "foo = x ? 1 : 2;")
1196 (test-ps-js obj-literal-numbers
1197 (create 1 "foo")
1198 "({ 1 : 'foo' });")
1200 (test-ps-js obj-literal-strings
1201 (create "foo" 2)
1202 "({ 'foo' : 2 });")
1204 (test-ps-js getprop-string
1205 (getprop foo "bar")
1206 "foo['bar'];")
1208 (test-ps-js getprop-string1
1209 (getprop "bar" 'length)
1210 "'bar'.length;")
1212 (test-ps-js getprop-progn
1213 (getprop (progn (some-fun "abc") "123") "length")
1214 "(someFun('abc'), '123')['length'];")
1216 (test-ps-js getprop-multi1
1217 (getprop foo 1 "two" three 'bar 1 2)
1218 "foo[1]['two'][three].bar[1][2];")
1220 (test-ps-js method-call-block
1221 ((@ (progn (some-fun "abc") "123") to-string))
1222 "(someFun('abc'), '123').toString();")
1224 (test-ps-js create-blank
1225 (create)
1226 "({ });")
1228 (test-ps-js blank-object-literal
1230 "({ });")
1232 (test-ps-js array-literal1
1234 "[];")
1236 (test-ps-js array-literal2
1237 ([])
1238 "[];")
1240 (test-ps-js array-literal3
1241 ([] 1 2 3)
1242 "[1, 2, 3];")
1244 (test-ps-js array-literal4
1245 ([] 1 (2 3))
1246 "[1, [2, 3]];")
1248 (test-ps-js array-literal5
1249 ([] (1 2) ("a" "b"))
1250 "[[1, 2], ['a', 'b']];")
1252 (test-ps-js defun-rest1
1253 (defun foo (&rest bar)
1254 (alert (aref bar 1)))
1255 "function foo() {
1256 var bar = Array.prototype.slice.call(arguments, 0);
1257 return alert(bar[1]);
1258 };")
1260 (test-ps-js defun-rest2
1261 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1262 "function foo(baz) {
1263 var bar = Array.prototype.slice.call(arguments, 1);
1264 return baz + bar[1];
1265 };")
1267 (test-ps-js defun-keyword1
1268 (defun zoo (foo bar &key baz) (+ foo bar baz))
1269 "function zoo(foo, bar) {
1270 var _js2 = arguments.length;
1271 for (var n1 = 2; n1 < _js2; n1 += 2) {
1272 switch (arguments[n1]) {
1273 case 'baz':
1274 baz = arguments[n1 + 1];
1277 var baz;
1278 return foo + bar + baz;
1279 };")
1281 (test-ps-js defun-keyword2
1282 (defun zoo (&key baz) (* baz baz))
1283 "function zoo() {
1284 var _js2 = arguments.length;
1285 for (var n1 = 0; n1 < _js2; n1 += 2) {
1286 switch (arguments[n1]) {
1287 case 'baz':
1288 baz = arguments[n1 + 1];
1291 var baz;
1292 return baz * baz;
1293 };")
1295 (test-ps-js defun-keyword3
1296 (defun zoo (&key baz (bar 4)) (* baz bar))
1297 "function zoo() {
1298 var _js2 = arguments.length;
1299 for (var n1 = 0; n1 < _js2; n1 += 2) {
1300 switch (arguments[n1]) {
1301 case 'baz':
1302 baz = arguments[n1 + 1];
1303 break;
1304 case 'bar':
1305 bar = arguments[n1 + 1];
1308 var baz;
1309 var bar = 'undefined' === typeof bar ? 4 : bar;
1310 return baz * bar;
1311 };")
1313 (test-ps-js defun-keyword4
1314 (defun hello-world (&key ((:my-name-key my-name) 1))
1315 my-name)
1316 "function helloWorld() {
1317 var _js2 = arguments.length;
1318 for (var n1 = 0; n1 < _js2; n1 += 2) {
1319 switch (arguments[n1]) {
1320 case 'my-name-key':
1321 myName = arguments[n1 + 1];
1324 var myName = 'undefined' === typeof myName ? 1 : myName;
1325 return myName;
1326 };")
1328 (test-ps-js arglist-keyword-supplied
1329 (lambda (&key (foo 1 supplied?))
1330 foo)
1331 "(function () {
1332 var _js2 = arguments.length;
1333 for (var n1 = 0; n1 < _js2; n1 += 2) {
1334 switch (arguments[n1]) {
1335 case 'foo':
1336 foo = arguments[n1 + 1];
1337 suppliedwhat = true;
1340 var suppliedwhat;
1341 var foo = 'undefined' === typeof foo ? 1 : foo;
1342 return foo;
1343 });")
1345 (test-ps-js keyword-funcall1
1346 (func :baz 1)
1347 "func('baz', 1);")
1349 (test-ps-js keyword-funcall2
1350 (func :baz 1 :bar foo)
1351 "func('baz', 1, 'bar', foo);")
1353 (test-ps-js keyword-funcall3
1354 (fun a b :baz c)
1355 "fun(a, b, 'baz', c);")
1357 (test-ps-js cond1
1358 (cond ((= x 1) 1))
1359 "if (x === 1) {
1361 };")
1363 (test-ps-js cond2
1364 (cond ((= x 1) 2)
1365 ((= y (* x 4)) (foo "blah") (* x y)))
1366 "if (x === 1) {
1368 } else if (y === x * 4) {
1369 foo('blah');
1370 x * y;
1371 };")
1373 (test-ps-js if-exp-without-else-return
1374 (defun foo () (return-from foo (if x 1)))
1375 "function foo() {
1376 return x ? 1 : null;
1377 };")
1379 (test-ps-js progn-expression-single-statement
1380 (defun foo () (return-from foo (progn (* x y))))
1381 "function foo() {
1382 return x * y;
1383 };")
1385 (test-ps-js cond-expression1
1386 (defun foo ()
1387 (cond ((< 1 2) (bar "foo") (* 4 5))))
1388 "function foo() {
1389 if (1 < 2) {
1390 bar('foo');
1391 return 4 * 5;
1393 };")
1395 (test-ps-js cond-expression2
1396 (defun foo ()
1397 (cond ((< 2 1) "foo")
1398 ((= 7 7) "bar")))
1399 "function foo() {
1400 if (2 < 1) {
1401 return 'foo';
1402 } else if (7 === 7) {
1403 return 'bar';
1405 };")
1407 (test-ps-js cond-expression-final-t-clause
1408 (defun foo ()
1409 (cond ((< 1 2) (bar "foo") (* 4 5))
1410 ((= a b) (+ c d))
1411 ((< 1 2 3 4 5) x)
1412 (t "foo")))
1413 "function foo() {
1414 var _cmp1;
1415 var _cmp2;
1416 var _cmp3;
1417 if (1 < 2) {
1418 bar('foo');
1419 return 4 * 5;
1420 } else if (a === b) {
1421 return c + d;
1422 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1423 return x;
1424 } else {
1425 return 'foo';
1427 };")
1429 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1430 (defun foo ()
1431 (cond ((< 2 1) 5)
1432 (t "foo")
1433 ((< 1 2) "bar")))
1434 "function foo() {
1435 if (2 < 1) {
1436 return 5;
1437 } else {
1438 return 'foo';
1440 };")
1442 (test-ps-js funcall-if-expression
1443 (funcall (getprop document 'write)
1444 (if (= *linkornot* 1)
1445 (ps-html ((:a :href "#"
1446 :onclick (ps-inline (transport)))
1447 img))
1448 img))
1449 "document.write(LINKORNOT === 1 ? ['<a href=\\\"#\\\" onclick=\\\"', 'javascript:' + 'transport()', '\\\">', img, '</a>'].join('') : img);")
1451 (test-ps-js negate-number-literal
1452 (- 1)
1453 "-1;")
1455 (fiveam:test macro-environment1
1456 (fiveam:is
1457 (string=
1458 (normalize-js-output
1459 (let* ((macroname (gensym)))
1460 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1461 `(defun test1 ()
1462 (macrolet ((,macroname (x) `(aref data ,x)))
1463 (when (,macroname x)
1464 (setf (,macroname x) 123)))))))
1465 (normalize-js-output
1466 "function test1() {
1467 return data[x] ? (data[x] = 123) : null;
1468 };"))))
1470 (fiveam:test macro-environment2
1471 (fiveam:is
1472 (string=
1473 (let ((outer-lexical-variable 1))
1474 (defpsmacro macro-environment2-macro (x)
1475 `(+ ,outer-lexical-variable ,x))
1476 (ps* '(macro-environment2-macro 2)))
1477 "1 + 2;")))
1479 (test-ps-js ampersand-whole-1
1480 (macrolet ((foo (&whole foo bar baz)
1481 (declare (ignore bar baz))
1482 (with-standard-io-syntax
1483 (let ((*print-case* :downcase))
1484 (format nil "~a" foo)))))
1485 (foo 1 2))
1486 "'(foo 1 2)';")
1488 (test-ps-js ampersand-whole-2
1489 (macrolet ((foo (&whole foo bar baz)
1490 `(+ ,bar ,baz)))
1491 (foo 1 2))
1492 "1 + 2;")
1494 (test-ps-js keyword-consistent
1496 "'x';")
1498 (test-ps-js simple-symbol-macrolet
1499 (symbol-macrolet ((x 1)) x)
1500 "1;")
1502 (test-ps-js compound-symbol-macrolet
1503 (symbol-macrolet ((x 123)
1504 (y (* 2 x)))
1506 "2 * 123;")
1508 (test-ps-js define-symbol-macro
1509 (progn (define-symbol-macro tst-sym-macro 2)
1510 tst-sym-macro)
1511 "2;")
1513 (test-ps-js define-symbol-macro1
1514 (progn (define-symbol-macro tst-sym-macro1 2)
1515 (foo tst-sym-macro1))
1516 "foo(2);")
1518 (test-ps-js define-symbol-macro2
1519 (progn (define-symbol-macro tst-sym-macro2 3)
1520 (list tst-sym-macro2))
1521 "[3];")
1523 (test-ps-js define-symbol-macro3
1524 (progn (define-symbol-macro tst-sym-macro3 4)
1525 (setq foo (create tst-sym-macro3 tst-sym-macro3)))
1526 "foo = { tstSymMacro3 : 4 };")
1528 (test-ps-js define-symbol-macro4
1529 (progn (define-symbol-macro tst-sym-macro4 5)
1530 (setq foo (if (baz) tst-sym-macro4 bar)))
1531 "foo = baz() ? 5 : bar;")
1533 (test-ps-js expression-progn
1534 (1+ (progn (foo) (if x 1 2)))
1535 "(foo(), x ? 1 : 2) + 1;")
1537 (test-ps-js let-decl-in-expression
1538 (defun f (x)
1539 (if x 1 (let* ((foo x)) foo)))
1540 "function f(x) {
1541 if (x) {
1542 return 1;
1543 } else {
1544 var foo = x;
1545 return foo;
1547 };")
1549 (test-ps-js special-var1
1550 (progn (defvar *foo*)
1551 (let* ((*foo* 2))
1552 (* *foo* 2)))
1553 "var FOO;
1554 (function () {
1555 var FOO_TMPSTACK1;
1556 try {
1557 FOO_TMPSTACK1 = FOO;
1558 FOO = 2;
1559 return FOO * 2;
1560 } finally {
1561 FOO = FOO_TMPSTACK1;
1563 })();")
1565 (test-ps-js special-var2
1566 (progn (defvar *foo*)
1567 (let* ((*baz* 3)
1568 (*foo* 2))
1569 (* *foo* 2 *baz*)))
1570 "var FOO;
1571 (function () {
1572 var BAZ = 3;
1573 var FOO_TMPSTACK1;
1574 try {
1575 FOO_TMPSTACK1 = FOO;
1576 FOO = 2;
1577 return FOO * 2 * BAZ;
1578 } finally {
1579 FOO = FOO_TMPSTACK1;
1581 })();")
1583 (test-ps-js literal1
1584 (setf x undefined)
1585 "x = undefined;")
1587 (test-ps-js literal2
1588 (aref this x)
1589 "this[x];")
1591 (test-ps-js setf-dec1
1592 (setf x (- 1 x 2))
1593 "x = 1 - x - 2;")
1595 (test-ps-js setf-dec2
1596 (setf x (- x 1 2))
1597 "x = x - 1 - 2;")
1599 (test-ps-js special-char-equals
1600 blah=
1601 "blahequals;")
1603 (test-ps-js setf-operator-priority
1604 (defun foo ()
1605 (or (getprop cache id)
1606 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1607 "function foo() {
1608 return cache[id] || (cache[id] = document.getElementById(id));
1609 };")
1611 (test-ps-js aref-operator-priority
1612 (aref (if (and x (> (length x) 0))
1613 (aref x 0)
1616 "(x && x.length > 0 ? x[0] : y)[z];")
1618 (test-ps-js aref-operator-priority1
1619 (aref (or (getprop x 'y)
1620 (getprop a 'b))
1622 "(x.y || a.b)[z];")
1624 (test-ps-js aref-operator-priority2
1625 (aref (if a b c) 0)
1626 "(a ? b : c)[0];")
1628 (test-ps-js negate-operator-priority
1629 (- (if x y z))
1630 "-(x ? y : z);")
1632 (test-ps-js op-p1
1633 (new (or a b))
1634 "new (a || b);")
1636 (test-ps-js op-p2
1637 (delete (if a (or b c) d))
1638 "delete (a ? b || c : d);")
1640 (test-ps-js op-p3
1641 (not (if (or x (not y)) z))
1642 "!(x || !y ? z : null);")
1644 (test-ps-js op-p4
1645 (- (- (* 1 2) 3))
1646 "-(1 * 2 - 3);")
1648 (test-ps-js op-p5
1649 (instanceof (or a b) (if x y z))
1650 "((a || b) instanceof (x ? y : z));")
1652 (test-ps-js op-p7
1653 (or x (if (= x 0) "zero" "empty"))
1654 "x || (x === 0 ? 'zero' : 'empty');")
1656 (test-ps-js named-op-expression
1657 (throw (if a b c))
1658 "throw a ? b : c;")
1660 (test-ps-js named-op-expression1
1661 (typeof (or x y))
1662 "typeof (x || y);")
1664 (test-ps-js aref-array-expression
1665 (aref (or a b c) 0)
1666 "(a || b || c)[0];")
1668 (test-ps-js getprop-operator
1669 (getprop (or a b c) 'd)
1670 "(a || b || c).d;")
1672 (test-ps-js getprop-parens
1673 (getprop (getprop foo 'bar) 'baz)
1674 "foo.bar.baz;")
1676 (test-ps-js funcall-funcall
1677 ((foo))
1678 "foo()();")
1680 (test-ps-js expression-funcall
1681 ((or (@ window eval) eval) foo nil)
1682 "(window.eval || eval)(foo, null);")
1684 (test-ps-js expression-funcall1
1685 (((or (@ window eval) eval) foo nil))
1686 "(window.eval || eval)(foo, null)();")
1688 (test-ps-js expression-funcall2
1689 (((or (@ window eval) eval)) foo nil)
1690 "(window.eval || eval)()(foo, null);")
1692 (test-ps-js who-html1
1693 (who-ps-html (:span :class "ticker-symbol"
1694 :ticker-symbol symbol
1695 (:a :href "http://foo.com"
1696 symbol)
1697 (:span :class "ticker-symbol-popup")))
1698 "['<span class=\\\"ticker-symbol\\\" ticker-symbol=\\\"', symbol, '\\\"><a href=\\\"http://foo.com\\\">', symbol, '</a><span class=\\\"ticker-symbol-popup\\\"></span></span>'].join('');")
1700 (test-ps-js who-html2
1701 (who-ps-html (:p "t0" (:span "t1")))
1702 "'<p>t0<span>t1</span></p>';")
1704 (test-ps-js flet1
1705 ((lambda () (flet ((foo (x)
1706 (1+ x)))
1707 (foo 1))))
1708 "(function () {
1709 var foo = function (x) {
1710 return x + 1;
1712 return foo(1);
1713 })();")
1715 (test-ps-js flet2
1716 (flet ((foo (x) (1+ x))
1717 (bar (y) (+ 2 y)))
1718 (bar (foo 1)))
1719 "(function () {
1720 var foo = function (x) {
1721 return x + 1;
1723 var bar = function (y) {
1724 return 2 + y;
1726 return bar(foo(1));
1727 })();")
1729 (test-ps-js flet3
1730 (flet ((foo (x) (+ 2 x)))
1731 (flet ((foo (x) (1+ x))
1732 (bar (y) (+ 2 (foo y))))
1733 (bar (foo 1))))
1734 "(function () {
1735 var foo = function (x) {
1736 return 2 + x;
1738 var foo1 = function (x) {
1739 return x + 1;
1741 var bar = function (y) {
1742 return 2 + foo(y);
1744 return bar(foo1(1));
1745 })();")
1747 (test-ps-js labels1
1748 ((lambda () (labels ((foo (x)
1749 (if (= 0 x)
1751 (+ x (foo (1- x))))))
1752 (foo 3))))
1753 "(function () {
1754 var foo = function (x) {
1755 return 0 === x ? 0 : x + foo(x - 1);
1757 return foo(3);
1758 })();")
1760 (test-ps-js labels2
1761 (labels ((foo (x) (1+ (bar x)))
1762 (bar (y) (+ 2 (foo y))))
1763 (bar (foo 1)))
1764 "(function () {
1765 var foo = function (x) {
1766 return bar(x) + 1;
1768 var bar = function (y) {
1769 return 2 + foo(y);
1771 return bar(foo(1));
1772 })();")
1774 (test-ps-js labels3
1775 (labels ((foo (x) (1+ x))
1776 (bar (y) (+ 2 (foo y))))
1777 (bar (foo 1)))
1778 "(function () {
1779 var foo = function (x) {
1780 return x + 1;
1782 var bar = function (y) {
1783 return 2 + foo(y);
1785 return bar(foo(1));
1786 })();")
1788 (test-ps-js labels-lambda-list
1789 (labels ((foo (x &optional (y 0))
1790 (+ x y)))
1791 (foo 1))
1792 "(function () {
1793 var foo = function (x, y) {
1794 if (y === undefined) {
1795 y = 0;
1797 return x + y;
1799 return foo(1);
1800 })();")
1802 (test-ps-js for-loop-var-init-exp
1803 ((lambda (x)
1804 (do* ((y (if x 0 1) (1+ y))
1805 (z 0 (1+ z)))
1806 ((= y 3) z)))
1808 "(function (x) {
1809 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1811 return z;
1812 })(true);")
1814 (test-ps-js math-pi
1816 "Math.PI;")
1818 (test-ps-js literal-array
1819 '(1 2 3)
1820 "[1, 2, 3];")
1822 (test-ps-js literal-array-1
1823 '(1 foo 3)
1824 "[1, 'foo', 3];")
1826 (test-ps-js literal-array-literal
1828 "[];")
1830 (test-ps-js literal-array-literal1
1831 '(1 [])
1832 "[1, []];")
1834 (fiveam:test ps-lisp-expands-in-lexical-environment
1835 (fiveam:is (string= (let ((x 5)) (ps (lisp x)))
1836 "5;")))
1838 (fiveam:test ps-lisp-expands-in-lexical-environment1
1839 (fiveam:is (string= (let ((x 5)) (ps (+ 1 (lisp x))))
1840 "1 + 5;")))
1842 (fiveam:test ps-lisp-expands-in-lexical-environment2
1843 (fiveam:is (string= (let ((x 2)) (ps (+ 1 (lisp x) 3)))
1844 "1 + 2 + 3;")))
1846 (fiveam:test ps*-lisp-expands-in-null-lexical-environment
1847 (fiveam:signals unbound-variable
1848 (let ((x 5))
1849 (declare (ignore x))
1850 (ps* '(lisp x)))))
1852 (fiveam:test ps*-lisp-expands-in-dynamic-environment
1853 (fiveam:is (string=
1854 (let ((foo 2))
1855 (declare (special foo))
1856 (ps* '(+ 1 (lisp (locally (declare (special foo))
1857 foo)))))
1858 "1 + 2;")))
1860 (fiveam:test ps-lisp-dynamic-environment
1861 (fiveam:is (string=
1862 (let ((foo 2))
1863 (declare (special foo))
1864 (ps (+ 1 (lisp foo))))
1865 "1 + 2;")))
1867 (test-ps-js nested-if-expressions1
1868 (defun foo ()
1869 (return-from foo (if (if x y z) a b)))
1870 "function foo() {
1871 if (x ? y : z) {
1872 return a;
1873 } else {
1874 return b;
1876 };")
1878 (test-ps-js nested-if-expressions2
1879 (defun foo ()
1880 (if x y (if z a b)))
1881 "function foo() {
1882 if (x) {
1883 return y;
1884 } else {
1885 return z ? a : b;
1887 };")
1889 (test-ps-js nested-if-expressions3
1890 (foo (if (if x y z) a b)
1891 (if x y (if z a b)))
1892 "foo((x ? y : z) ? a : b, x ? y : (z ? a : b));")
1894 (test-ps-js let1
1895 (let (x)
1896 (+ x x))
1897 "(function () {
1898 var x = null;
1899 return x + x;
1900 })();")
1902 (test-ps-js let2
1903 (let ((x 1))
1904 (+ x x))
1905 "(function () {
1906 var x = 1;
1907 return x + x;
1908 })();")
1910 (test-ps-js let-x-x
1911 (let ((x (1+ x)))
1912 (+ x x))
1913 "(function () {
1914 var x1 = x + 1;
1915 return x1 + x1;
1916 })();")
1918 (test-ps-js let3
1919 (let ((x 1)
1920 (y 2))
1921 (+ x x))
1922 "(function () {
1923 var x = 1;
1924 var y = 2;
1925 return x + x;
1926 })();")
1928 (test-ps-js let4
1929 (let ((x 1)
1930 (y (1+ x)))
1931 (+ x y))
1932 "(function () {
1933 var x1 = 1;
1934 var y = x + 1;
1935 return x1 + y;
1936 })();")
1938 (test-ps-js let5
1939 (let ((x 1))
1940 (+ x 1)
1941 (let ((x (+ x 5)))
1942 (+ x 1))
1943 (+ x 1))
1944 "(function () {
1945 var x = 1;
1946 x + 1;
1947 var x1 = x + 5;
1948 x1 + 1;
1949 return x + 1;
1950 })();")
1952 (test-ps-js let6
1953 (let ((x 2))
1954 (let ((x 1)
1955 (y (1+ x)))
1956 (+ x y)))
1957 "(function () {
1958 var x = 2;
1959 var x1 = 1;
1960 var y = x + 1;
1961 return x1 + y;
1962 })();")
1964 (test-ps-js let-exp1
1965 (lambda ()
1966 (let (x)
1967 (+ x x)))
1968 "(function () {
1969 var x = null;
1970 return x + x;
1971 });")
1973 (test-ps-js let*1
1974 (let* ((x 1))
1975 (+ x x))
1976 "(function () {
1977 var x = 1;
1978 return x + x;
1979 })();")
1981 (test-ps-js let*2
1982 (let* ((x 1)
1983 (y (+ x 2)))
1984 (+ x y))
1985 "(function () {
1986 var x = 1;
1987 var y = x + 2;
1988 return x + y;
1989 })();")
1991 (test-ps-js let*3
1992 (let ((x 3))
1993 (let* ((x 1)
1994 (y (+ x 2)))
1995 (+ x y)))
1996 "(function () {
1997 var x = 3;
1998 var x1 = 1;
1999 var y = x1 + 2;
2000 return x1 + y;
2001 })();")
2003 (test-ps-js let*4
2004 (let ((x 3))
2005 (let* ((y (+ x 2))
2006 (x 1))
2007 (+ x y)))
2008 "(function () {
2009 var x = 3;
2010 var y = x + 2;
2011 var x1 = 1;
2012 return x1 + y;
2013 })();")
2015 (test-ps-js symbol-macrolet-var
2016 (symbol-macrolet ((x y))
2017 (var x))
2018 "var y;")
2020 (test-ps-js setf-conditional1
2021 (setf x (unless (null a) (1+ a)))
2022 "x = a != null ? a + 1 : null;")
2024 (test-ps-js setf-let1
2025 (setf x (let ((a 1)) a))
2026 "x = (function () {
2027 var a = 1;
2028 return a;
2029 })();")
2031 (test-ps-js setf-let2
2032 (setf x (let ((a (foo)))
2033 (unless (null a)
2034 (1+ a))))
2035 "x = (function () {
2036 var a = foo();
2037 return a != null ? a + 1 : null;
2038 })();")
2040 (test-ps-js symbol-macro-env1
2041 (symbol-macrolet ((bar 1))
2042 (macrolet ((bar (x y) `(+ ,x ,y)))
2043 (bar bar bar)))
2044 "1 + 1;")
2046 (test-ps-js symbol-macrolet-fun1
2047 (symbol-macrolet ((baz +))
2048 (baz 1 2))
2049 "baz(1, 2);")
2051 (test-ps-js lisp2-namespaces1
2052 (let ((list nil))
2053 (setf list (list 1 2 3)))
2054 "(function () {
2055 var list = null;
2056 return list = [1, 2, 3];
2057 })();")
2059 (test-ps-js let-shadows-symbol-macrolet
2060 (symbol-macrolet ((x y))
2061 (let ((x 1))
2062 (+ x x))
2063 (+ x x))
2064 "(function () {
2065 var x1 = 1;
2066 return x1 + x1;
2067 })();
2068 y + y;")
2070 (test-ps-js let-rename-optimization1
2071 (let ((x 1))
2072 (+ x x))
2073 "(function () {
2074 var x = 1;
2075 return x + x;
2076 })();")
2078 (test-ps-js let-rename-optimization2
2079 (lambda (x)
2080 (let ((x (+ 1 x)))
2082 "(function (x) {
2083 var x1 = 1 + x;
2084 return x1;
2085 });")
2087 (test-ps-js symbol-macro-array
2088 (symbol-macrolet ((x 1))
2089 (list x))
2090 "[1];")
2092 (test-ps-js symbol-macro-obj
2093 (symbol-macrolet ((x (+ 1 2)))
2094 (create x 1))
2095 "({ x : 1 });")
2097 (test-ps-js symbol-macro-obj1
2098 (symbol-macrolet ((x (+ 1 2)))
2099 (ps:create x x))
2100 "({ x : 1 + 2 });")
2102 (test-ps-js symbol-macro-getprop1
2103 (symbol-macrolet ((x (+ 1 2)))
2104 (ps:getprop a x))
2105 "a[1 + 2];")
2107 (test-ps-js symbol-macro-getprop1
2108 (symbol-macrolet ((x (+ 1 2)))
2109 (ps:getprop a 'x))
2110 "a.x;")
2112 (test-ps-js let-let-create
2113 (let ((a 99))
2114 (let ((a 22))
2115 (create a 33)))
2116 "(function () {
2117 var a = 99;
2118 var a1 = 22;
2119 return { a : 33 };
2120 })();")
2122 (test-ps-js symbol-macro-conditional1
2123 (symbol-macrolet ((x y))
2124 (if x x x))
2125 "if (y) {
2127 } else {
2129 };")
2131 (test-ps-js symbol-macro-conditional2
2132 (symbol-macrolet ((x y))
2133 (1+ (if x x x)))
2134 "(y ? y : y) + 1;")
2136 (test-ps-js preserve-this
2137 (defun foo ()
2138 (let ((y (block nil (bar this))))
2139 (baz y)))
2140 "function foo() {
2141 var y = (function () {
2142 return bar(this);
2143 }).call(this);
2144 return baz(y);
2145 };")
2147 (test-ps-js flet-apply
2148 (flet ((foo () 'bar))
2149 (apply (function foo) nil))
2150 "(function () {
2151 var foo = function () {
2152 return 'bar';
2154 return foo.apply(this, null);
2155 }).call(this);")
2157 (test-ps-js let-apply
2158 (let ((foo (lambda () 1)))
2159 (let ((foo (lambda () 2)))
2160 (apply foo nil)))
2161 "(function () {
2162 var foo = function () {
2163 return 1;
2165 var foo1 = function () {
2166 return 2;
2168 return foo1.apply(this, null);
2169 }).call(this);")
2171 (test-ps-js flet-let
2172 (flet ((x (x) (1+ x)))
2173 (let ((x 2))
2174 (x x)))
2175 "(function () {
2176 var x = function (x) {
2177 return x + 1;
2179 var x1 = 2;
2180 return x(x1);
2181 })();")
2183 (test-ps-js let-flet
2184 (let ((x 2))
2185 (flet ((x (x) (1+ x)))
2186 (x x)))
2187 "(function () {
2188 var x = 2;
2189 var x1 = function (x) {
2190 return x + 1;
2192 return x1(x);
2193 })();")
2195 (test-ps-js labels-let
2196 (labels ((x (x) (1+ x)))
2197 (let ((x 2))
2198 (x x)))
2199 "(function () {
2200 var x = function (x) {
2201 return x + 1;
2203 var x1 = 2;
2204 return x(x1);
2205 })();")
2207 (test-ps-js let-labels
2208 (let ((x 2))
2209 (labels ((x (x) (1+ x)))
2210 (x x)))
2211 "(function () {
2212 var x = 2;
2213 var x1 = function (x) {
2214 return x + 1;
2216 return x1(x);
2217 })();")
2219 (test-ps-js macrolet-let-inteference
2220 (macrolet ((a (n) `(+ ,n 5)))
2221 (let ((a (a 1)))
2222 (let ((b (a (- a 4))))
2223 (+ a b))))
2224 "(function () {
2225 var a = 1 + 5;
2226 var b = (a - 4) + 5;
2227 return a + b;
2228 })();")
2230 (test-ps-js let-subtract-add
2231 (let ((x 1))
2232 (let ((x 2))
2233 (- x x)
2234 (- x)
2235 (decf x)
2236 (incf x)))
2237 "(function () {
2238 var x = 1;
2239 var x1 = 2;
2240 x1 - x1;
2241 -x1;
2242 --x1;
2243 return ++x1;
2244 })();")
2246 (test-ps-js create-reserved-word
2247 (create :default 1)
2248 "({ 'default' : 1 });")
2250 (test-ps-js getprop-reserved-word
2251 (getprop foo :default)
2252 "foo['default'];")
2254 (test-ps-js getprop-reserved-word1
2255 (getprop foo 'default)
2256 "foo['default'];")
2258 (test-ps-js eval-when-ps-side
2259 (eval-when (:execute)
2261 "5;")
2263 (defvar *lisp-output* nil)
2265 (fiveam:test eval-when-lisp-side ()
2266 (setf *lisp-output* 'original-value)
2267 (let ((js-output
2268 (normalize-js-output
2269 (ps-doc* `(eval-when (:compile-toplevel)
2270 (setf *lisp-output* 'it-works))))))
2271 (fiveam:is (eql 'it-works *lisp-output*))
2272 (fiveam:is (string= "" js-output))))
2274 (defpsmacro my-in-package (package-name)
2275 `(eval-when (:compile-toplevel)
2276 (setf *lisp-output* ,package-name)))
2278 (fiveam:test eval-when-macro-expansion ()
2279 (setf *lisp-output* 'original-value)
2280 (let ((js-output
2281 (normalize-js-output
2282 (ps-doc* `(progn
2283 (my-in-package :cl-user)
2284 3)))))
2285 (declare (ignore js-output))
2286 (fiveam:is (eql :cl-user *lisp-output*))))
2288 (fiveam:test eval-when-macrolet-expansion ()
2289 (setf *lisp-output* 'original-value)
2290 (let ((js-output
2291 (normalize-js-output
2292 (ps-doc*
2293 `(macrolet ((my-in-package2 (package-name)
2294 `(eval-when (:compile-toplevel)
2295 (setf *lisp-output* ,package-name))))
2296 (my-in-package2 :cl-user)
2297 3)))))
2298 (declare (ignore js-output))
2299 (fiveam:is (eql :cl-user *lisp-output*))))
2301 (test-ps-js getprop-keyword
2302 (getprop foo :bar)
2303 "foo['bar'];")
2305 (test-ps-js nary-comparison1
2306 (lambda () (< 1 2 3))
2307 "(function () {
2308 var _cmp1;
2309 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2310 });")
2312 (test-ps-js chain-getprop1
2313 (chain ($ "foo") (bar x z) frob (baz 5))
2314 "$('foo').bar(x, z).frob.baz(5);")
2316 (test-ps-js chain-getprop2
2317 (chain ($ "foo") bar baz)
2318 "$('foo').bar.baz;")
2320 (test-ps-js chain-getprop3
2321 (chain ($ "foo") bar (x y) baz)
2322 "$('foo').bar.x(y).baz;")
2324 (test-ps-js flet-expression
2325 (1+ (flet ((foo (x) (1+ x)))
2326 (foo 1)))
2327 "(function () {
2328 var foo = function (x) {
2329 return x + 1;
2331 return foo(1);
2332 })() + 1;")
2334 (test-ps-js flet-lambda-list
2335 (flet ((foo (x &key (y 0))
2336 (+ x y)))
2337 (foo 1 :y 2))
2338 "(function () {
2339 var foo = function (x) {
2340 var _js2 = arguments.length;
2341 for (var n1 = 1; n1 < _js2; n1 += 2) {
2342 switch (arguments[n1]) {
2343 case 'y':
2344 y = arguments[n1 + 1];
2347 var y = 'undefined' === typeof y ? 0 : y;
2348 return x + y;
2350 return foo(1, 'y', 2);
2351 })();")
2353 (test-ps-js return-case-break-elimination
2354 (defun foo ()
2355 (case 1
2356 (0 1)
2357 (otherwise 2)))
2358 "function foo() {
2359 switch (1) {
2360 case 0:
2361 return 1;
2362 default:
2363 return 2;
2365 };")
2367 (test-ps-js aplusplus
2369 "aplusplus;")
2371 (test-ps-js astarstar
2373 "astarstar;")
2375 (test-ps-js switch-return-fallthrough
2376 (defun foo ()
2377 (switch x
2378 (1 (foo) break)
2379 (2 (bar))
2380 (default 4)))
2381 "function foo() {
2382 switch (x) {
2383 case 1:
2384 return foo();
2385 case 2:
2386 bar();
2387 default:
2388 return 4;
2390 };")
2392 (test-ps-js return-last-case
2393 (defun foo ()
2394 (case x
2395 (:a 'eh)
2396 (:b 'bee)))
2397 "function foo() {
2398 switch (x) {
2399 case 'a':
2400 return 'eh';
2401 case 'b':
2402 return 'bee';
2404 };")
2406 (test-ps-js return-macrolet
2407 (defun foo ()
2408 (macrolet ((x () 1))
2409 (case (x)
2410 (:a 'eh)
2411 (:b 'bee))))
2412 "function foo() {
2413 switch (1) {
2414 case 'a':
2415 return 'eh';
2416 case 'b':
2417 return 'bee';
2419 };")
2421 (test-ps-js mv-bind1
2422 (multiple-value-bind (a b)
2423 (progn
2424 (returns-mv)
2425 (doesnt))
2426 (alert a)
2427 (alert b))
2428 "returnsMv();
2429 (function () {
2430 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2431 try {
2432 var a = doesnt();
2433 var _db2 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2434 var b = _db2[0];
2435 alert(a);
2436 return alert(b);
2437 } finally {
2438 __PS_MV_REG = prevMv1;
2440 })();")
2442 (test-ps-js mv-bind2
2443 (multiple-value-bind (a b)
2444 (let ((a 1))
2445 (returns-mv a)
2446 (doesnt b))
2447 (alert a)
2448 (alert b))
2449 "(function () {
2450 var a = 1;
2451 returnsMv(a);
2452 var prevMv2 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2453 try {
2454 var a3 = doesnt(b);
2455 var _db4 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2456 var b = _db4[0];
2457 alert(a3);
2458 return alert(b);
2459 } finally {
2460 __PS_MV_REG = prevMv2;
2462 })();")
2464 (test-ps-js multiple-value-bind-simple
2465 (multiple-value-bind (a b) (blah)
2466 (+ a b))
2467 "(function () {
2468 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2469 try {
2470 var a = blah();
2471 var _db2 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2472 var b = _db2[0];
2473 return a + b;
2474 } finally {
2475 __PS_MV_REG = prevMv1;
2477 })();")
2479 (test-ps-js values0
2480 (lambda () (values))
2481 "(function () {
2482 __PS_MV_REG = {};
2483 return null;
2484 });")
2486 (test-ps-js values1
2487 (values x)
2488 "x;")
2490 (test-ps-js values2
2491 (lambda () (values x y))
2492 "(function () {
2493 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2494 return x;
2495 });")
2497 (test-ps-js values3
2498 (lambda () (values x y z))
2499 "(function () {
2500 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2501 return x;
2502 });")
2504 (test-ps-js values-return
2505 (defun foo (x y)
2506 (return-from foo (values (* x x) y)))
2507 "function foo(x, y) {
2508 var val1_1 = x * x;
2509 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2510 return val1_1;
2511 };")
2513 (test-ps-js return-macrolet1
2514 (defun foo ()
2515 (symbol-macrolet ((x 2))
2516 (loop do (+ x x))))
2517 "function foo() {
2518 while (true) {
2519 2 + 2;
2521 };")
2523 (test-ps-js return-cond
2524 (defun foo ()
2525 (return-from foo
2526 (cond ((foo? x) (loop for y in x do (foo y)))
2527 ((bar? x) x)
2528 (t 3))))
2529 "function foo() {
2530 if (foowhat(x)) {
2531 var _js2 = x.length;
2532 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2533 var y = x[_js1];
2534 foo(y);
2536 } else if (barwhat(x)) {
2537 return x;
2538 } else {
2539 return 3;
2541 };")
2543 (test-ps-js return-case
2544 (defun foo ()
2545 (return-from foo
2546 (case x
2547 (1 (loop for y in x do (foo y)))
2548 (2 x)
2549 ((t) 3))))
2550 "function foo() {
2551 switch (x) {
2552 case 1:
2553 var _js2 = x.length;
2554 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2555 var y = x[_js1];
2556 foo(y);
2558 return;
2559 case 2:
2560 return x;
2561 case true:
2562 return 3;
2564 };")
2566 (test-ps-js return-case1
2567 (defun foo ()
2568 (return-from foo
2569 (case x
2570 (1 (if a 1 2))
2571 (2 x)
2572 ((t) 3))))
2573 "function foo() {
2574 switch (x) {
2575 case 1:
2576 return a ? 1 : 2;
2577 case 2:
2578 return x;
2579 case true:
2580 return 3;
2582 };")
2584 (test-ps-js lambda-loop-if-return
2585 (lambda ()
2586 (if a
2587 (loop for y in x do (foo y))
2589 "(function () {
2590 if (a) {
2591 var _js4 = x.length;
2592 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2593 var y = x[_js3];
2594 foo(y);
2596 } else {
2597 return c;
2599 });")
2601 (test-ps-js lambda-loop-if-return1
2602 (defun baz ()
2603 (foo (lambda ()
2604 (if a
2605 (progn (loop for y in x do (foo y))
2606 (return-from baz))
2607 c))))
2608 "function baz() {
2609 try {
2610 return foo(function () {
2611 if (a) {
2612 var _js4 = x.length;
2613 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2614 var y = x[_js3];
2615 foo(y);
2617 throw { '__ps_block_tag' : 'baz',
2618 '__ps_value1' : null };
2619 } else {
2620 return c;
2623 } catch (_ps_err5) {
2624 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2625 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2626 return _ps_err5['__ps_value1'];
2627 } else {
2628 throw _ps_err5;
2631 };")
2633 (test-ps-js switch-loop
2634 (defun foo (x)
2635 (case x
2636 (1 (dolist (a b)))))
2637 "function foo(x) {
2638 switch (x) {
2639 case 1:
2640 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2641 a = b[_js_idx1];
2643 return;
2645 };")
2647 (test-ps-js switch-folds-blocks
2648 (defun foo ()
2649 (case x
2650 (1 (loop repeat 3 do (alert "foo")))
2651 (2 "bar")))
2652 "function foo() {
2653 switch (x) {
2654 case 1:
2655 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2656 alert('foo');
2658 return;
2659 case 2:
2660 return 'bar';
2662 };")
2664 (test-ps-js setf-places-before-macros
2665 (lambda ()
2666 (defsetf left (el) (offset)
2667 `(setf (@ ,el style left) ,offset))
2668 (macrolet ((left (el)
2669 `(@ ,el offset-left)))
2670 (setf (left x) 10)
2671 (left x)))
2672 "(function () {
2673 var _js2 = x;
2674 var _js1 = 10;
2675 _js2.style.left = _js1;
2676 return x.offsetLeft;
2677 });")
2679 (test-ps-js for-return
2680 (lambda () (dolist (arg args) (foo arg)))
2681 "(function () {
2682 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2683 arg = args[_js_idx1];
2684 foo(arg);
2686 });")
2688 (test-ps-js try-catch-return
2689 (defun foo ()
2690 (try (foo)
2691 (:catch (e)
2692 (bar))
2693 (:finally
2694 (cleanup))))
2695 "function foo() {
2696 try {
2697 return foo();
2698 } catch (e) {
2699 return bar();
2700 } finally {
2701 cleanup();
2703 };")
2705 (test-ps-js let-try
2706 (let ((x (ps:try (+ 1 2)
2707 (:catch (y) 5))))
2709 "(function () {
2710 var x = (function () {
2711 try {
2712 return 1 + 2;
2713 } catch (y) {
2714 return 5;
2716 })();
2717 return x;
2718 })();")
2720 (test-ps-js try-finally-return-from
2721 (defun xyz ()
2722 (return-from xyz
2723 (ps:try (when (blah) 4)
2724 (:finally (foo))))
2725 (dont-call-me))
2726 "function xyz() {
2727 try {
2728 return blah() ? 4 : null;
2729 } finally {
2730 foo();
2732 return dontCallMe();
2733 };")
2735 (test-ps-js defun-setf-optional
2736 (defun (setf foo) (new-value b &optional c)
2737 (setf (aref b (or c 0)) new-value))
2738 "function __setf_foo(newValue, b, c) {
2739 return b[c || 0] = newValue;
2740 };")
2742 (test-ps-js defun-setf-rest
2743 (progn (defun (setf foo) (new-value b &rest foo)
2744 (do-something b foo new-value))
2745 (setf (foo x 1 2 3 4) 5))
2746 "function __setf_foo(newValue, b) {
2747 var foo = Array.prototype.slice.call(arguments, 2);
2748 return doSomething(b, foo, newValue);
2750 __setf_foo(5, x, 1, 2, 3, 4);")
2752 (test-ps-js return-null
2753 (defun foo () (return-from foo nil))
2754 "function foo() {
2755 return null;
2756 };")
2758 (test-ps-js implicit-return-null
2759 (lambda ()
2761 "(function () {
2762 return null;
2763 });")
2765 (test-ps-js implicit-return-null
2766 (lambda ()
2767 nil)
2768 "(function () {
2769 return null;
2770 });")
2772 (test-ps-js return-conditional-nested
2773 (defun blep (ss x y)
2774 (when foo?
2775 (let ((pair (bar)))
2776 (unless (null pair)
2777 (destructuring-bind (a b) pair
2778 (unless (or (null a) (null b))
2779 (let ((val (baz a b)))
2780 (unless (null val)
2781 (when (blah val)
2782 (unless (blee)
2783 t))))))))))
2784 "function blep(ss, x, y) {
2785 if (foowhat) {
2786 var pair = bar();
2787 if (pair != null) {
2788 var a = pair[0];
2789 var b = pair[1];
2790 if (!(a == null || b == null)) {
2791 var val = baz(a, b);
2792 if (val != null) {
2793 if (blah(val)) {
2794 return !blee() ? true : null;
2800 };")
2802 (test-ps-js return-when-returns-broken-return
2803 (defun foo ()
2804 (return-from foo (when x 1))
2805 (+ 2 3))
2806 "function foo() {
2807 return x ? 1 : null;
2808 return 2 + 3;
2809 };")
2811 (test-ps-js return-case-conditional
2812 (defun foo ()
2813 (return-from foo
2814 (case foo
2815 (123 (when (bar) t))
2816 (345 (blah)))))
2817 "function foo() {
2818 switch (foo) {
2819 case 123:
2820 return bar() ? true : null;
2821 case 345:
2822 return blah();
2824 };")
2826 (test-ps-js return-try-conditional
2827 (defun foo ()
2828 (return-from foo
2829 (try (when x 1)
2830 (:catch (x) 2)
2831 (:finally (bar)))))
2832 "function foo() {
2833 try {
2834 return x ? 1 : null;
2835 } catch (x) {
2836 return 2;
2837 } finally {
2838 bar();
2840 };")
2842 (test-ps-js function-declare-special
2843 (lambda ()
2844 (declare (special *foo*))
2845 (let ((*foo* 1))
2846 (1+ *foo*)))
2847 "(function () {
2848 var FOO_TMPSTACK1;
2849 try {
2850 FOO_TMPSTACK1 = FOO;
2851 FOO = 1;
2852 return FOO + 1;
2853 } finally {
2854 FOO = FOO_TMPSTACK1;
2856 });")
2858 (test-ps-js declare-special-let
2859 (let ((*foo* 123))
2860 (declare (special *foo*))
2861 (blah))
2862 "(function () {
2863 var FOO_TMPSTACK1;
2864 try {
2865 FOO_TMPSTACK1 = FOO;
2866 FOO = 123;
2867 return blah();
2868 } finally {
2869 FOO = FOO_TMPSTACK1;
2871 })();")
2873 (test-ps-js declare-special-let-scope
2874 (block nil
2875 (let ((*foo* 123))
2876 (declare (special *foo*))
2877 (blah))
2878 (let ((*foo* 456))
2879 (+ 4 5)))
2880 "(function () {
2881 var FOO_TMPSTACK1;
2882 try {
2883 FOO_TMPSTACK1 = FOO;
2884 FOO = 123;
2885 blah();
2886 } finally {
2887 FOO = FOO_TMPSTACK1;
2889 var FOO = 456;
2890 return 4 + 5;
2891 })();")
2893 (test-ps-js declare-special-let*
2894 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
2895 (declare (special *foo* *bar*))
2896 (blah))
2897 "(function () {
2898 var FOO_TMPSTACK1;
2899 try {
2900 FOO_TMPSTACK1 = FOO;
2901 FOO = 123;
2902 var BAR_TMPSTACK2;
2903 try {
2904 BAR_TMPSTACK2 = BAR;
2905 BAR = FOO + BAR;
2906 return blah();
2907 } finally {
2908 BAR = BAR_TMPSTACK2;
2910 } finally {
2911 FOO = FOO_TMPSTACK1;
2913 })();")
2915 (test-ps-js defun-multiple-declarations-around-docstring
2916 (defun foo (x y)
2917 (declare (ignorable x y))
2918 (declare (integer x) (float y))
2919 "Fooes X while barring Y."
2920 (declare (special *foo*) (special *bar*))
2921 (let ((*bar* (bar y)))
2922 (funcall *foo* x)))
2923 "/** Fooes X while barring Y. */
2924 function foo(x, y) {
2925 var BAR_TMPSTACK1;
2926 try {
2927 BAR_TMPSTACK1 = BAR;
2928 BAR = bar(y);
2929 return FOO(x);
2930 } finally {
2931 BAR = BAR_TMPSTACK1;
2933 };")
2935 (test-ps-js macro-null-toplevel
2936 (progn
2937 (defmacro macro-null-toplevel ()
2938 nil)
2939 (macro-null-toplevel))
2942 (test-ps-js define-symbol-macro-let
2943 (progn
2944 (define-symbol-macro test-symbol-macro 1)
2945 (let ((test-symbol-macro 2))
2946 (1+ test-symbol-macro))
2947 (1+ test-symbol-macro))
2948 "(function () {
2949 var testSymbolMacro1 = 2;
2950 return testSymbolMacro1 + 1;
2951 })();
2952 1 + 1;")
2954 (test-ps-js define-symbol-macro-flet
2955 (progn
2956 (define-symbol-macro test-symbol-macro1 1)
2957 (flet ((test-symbol-macro1 () 2))
2958 (foo test-symbol-macro1)
2959 (test-symbol-macro1))
2960 (bar test-symbol-macro1))
2961 "(function () {
2962 var testSymbolMacro1_1 = function () {
2963 return 2;
2965 foo(1);
2966 return testSymbolMacro1_1();
2967 })();
2968 bar(1);")
2970 (fiveam:test compile-stream-nulls
2971 (fiveam:is
2972 (string=
2973 (with-input-from-string (s "
2974 (defmacro macro-null-toplevel ()
2975 nil)
2976 (macro-null-toplevel)")
2977 (ps-compile-stream s))
2978 "")))
2980 (fiveam:test compile-stream1
2981 (fiveam:is
2982 (string=
2983 (with-input-from-string (s "
2984 (define-symbol-macro test-symbol-macro1 1)
2985 (flet ((test-symbol-macro1 () 2))
2986 (foo test-symbol-macro1)
2987 (test-symbol-macro1))
2988 (bar test-symbol-macro1)")
2989 (ps::with-blank-compilation-environment
2990 (ps-compile-stream s)))
2991 "(function () {
2992 var testSymbolMacro1_1 = function () {
2993 return 2;
2995 foo(1);
2996 return testSymbolMacro1_1();
2997 })();
2998 bar(1);
2999 ")))
3001 (test-ps-js equality-nary1
3002 (let ((x 10) (y 10) (z 10))
3003 (= x y z))
3004 "(function () {
3005 var _cmp1;
3006 var x = 10;
3007 var y = 10;
3008 var z = 10;
3009 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
3010 })();")
3012 (test-ps-js equality1
3013 (progn
3014 (equal a b)
3015 (eql a b)
3016 (eq a b)
3017 (= a b))
3018 "a == b;
3019 a === b;
3020 a === b;
3021 a === b;")
3023 (test-ps-js getprop-quote-reserved
3024 (getprop foo ':break)
3025 "foo['break'];")
3027 (test-ps-js defun-block-return-from
3028 (defun foo (x)
3029 (baz 4)
3030 (return-from foo x)
3031 (bar 5))
3032 "function foo(x) {
3033 baz(4);
3034 return x;
3035 return bar(5);
3036 };")
3038 (test-ps-js block-return-from
3039 (block scope
3040 (foo)
3041 (when (bar)
3042 (return-from scope))
3043 (blee))
3044 "(function () {
3045 foo();
3046 if (bar()) {
3047 return null;
3049 return blee();
3050 })();")
3052 (test-ps-js block-return-from0
3053 (defun baz ()
3054 (block scope
3055 (foo)
3056 (when (bar)
3057 (return-from scope))
3058 (blee)))
3059 "function baz() {
3060 foo();
3061 if (bar()) {
3062 return null;
3064 return blee();
3065 };")
3067 (test-ps-js block-return-from01
3068 (defun baz ()
3069 (block scope
3070 (foo)
3071 (when (bar)
3072 (return-from scope))
3073 (blee))
3075 "function baz() {
3076 scope: {
3077 foo();
3078 if (bar()) {
3079 break scope;
3081 blee();
3083 return 2;
3084 };")
3086 (test-ps-js block-return-from02
3087 (defun baz ()
3088 (block scope
3089 (foo)
3090 (when (bar)
3091 (return-from scope (foobar)))
3092 (blee))
3094 "function baz() {
3095 scope: {
3096 foo();
3097 if (bar()) {
3098 foobar();
3099 break scope;
3101 blee();
3103 return 2;
3104 };")
3106 (test-ps-js block-return-from1
3107 (lambda ()
3108 (block scope
3109 (foo)
3110 (when (bar)
3111 (return-from scope))
3112 (blee))
3113 (+ 1 2))
3114 "(function () {
3115 scope: {
3116 foo();
3117 if (bar()) {
3118 break scope;
3120 blee();
3122 return 1 + 2;
3123 });")
3125 (test-ps-js block-return-from2
3126 (lambda ()
3127 (bar 5)
3128 (block scope
3129 (foo)
3130 (when (bar)
3131 (return-from scope 6))
3132 (blee)))
3133 "(function () {
3134 bar(5);
3135 foo();
3136 if (bar()) {
3137 return 6;
3139 return blee();
3140 });")
3142 (test-ps-js let-funcall
3143 (let ((x foo))
3144 (funcall x)
3145 (let ((x bar))
3146 (funcall x))
3147 (funcall x))
3148 "(function () {
3149 var x = foo;
3150 x();
3151 var x1 = bar;
3152 x1();
3153 return x();
3154 })();")
3156 (test-ps-js symbol-macrolet-funcall
3157 (symbol-macrolet ((foo bar))
3158 (funcall foo 1 2 3))
3159 "bar(1, 2, 3);")
3161 (test-ps-js times-assign
3162 (setf x (* x 1000))
3163 "x *= 1000;")
3165 (test-ps-js vector-literal
3166 #(1 2 3)
3167 "[1, 2, 3];")
3169 (test-ps-js vector-literal1
3170 #(1 2 #(a b) 3)
3171 "[1, 2, ['a', 'b'], 3];")
3173 (test-ps-js rem1
3174 (+ 1 (rem 2 (+ 3 4)))
3175 "1 + 2 % (3 + 4);")
3177 (test-ps-js non-associative
3178 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3179 "1 / (2 / 3) + (1 - (2 - 3));")
3181 (test-ps-js lambda-apply
3182 (lambda (x)
3183 (apply (lambda (y) (bar (1+ y))) x))
3184 "(function (x) {
3185 return (function (y) {
3186 return bar(y + 1);
3187 }).apply(this, x);
3188 });")
3190 (test-ps-js operator-expressions-nested-let
3191 (let ((x (let ((y 1))
3192 y)))
3194 "(function () {
3195 var y;
3196 var x = (y = 1, y);
3197 return x;
3198 })();")
3200 (test-ps-js operator-expressions-array-nested-let
3201 (list (let ((y 1)) y) 2)
3202 "[(function () {
3203 var y = 1;
3204 return y;
3205 })(), 2];")
3207 (test-ps-js add-subtract-precedence
3208 (- x (+ y z))
3209 "x - (y + z);")
3211 (test-ps-js ps-inline-toplevel
3212 (ps-inline (foo))
3213 "'javascript:' + 'foo()';")
3215 (test-ps-js no-clause-progn-exp
3216 (setf x (progn))
3217 "x = null;")
3219 (test-ps-js no-clause-progn-return
3220 (defun foo ()
3221 (return-from foo (progn)))
3222 "function foo() {
3223 return null;
3224 };")
3226 (test-ps-js empty-cond-clause
3227 (setf x (cond ((foo))))
3228 "x = (function () { var testResult1 = foo(); return testResult1 ? testResult1 : null; })();")
3230 (test-ps-js empty-cond-clause1
3231 (setf x (cond ((foo) 123)
3232 ((bar))
3233 (t 456)))
3234 "x = foo() ? 123 :
3235 (function () {
3236 var testResult1 = bar();
3237 if (testResult1) {
3238 return testResult1;
3239 } else {
3240 if (true) { return 456; };
3242 })();")
3244 (test-ps-js let-no-body
3245 (defun foo ()
3246 (return-from foo (let ((foo bar)))))
3247 "function foo() {
3248 var foo1 = bar;
3249 return null;
3250 };")
3252 (test-ps-js rename-lexical-dupes
3253 (lambda ()
3254 (list (let ((foo 12)) (* foo 2))
3255 (let ((foo 13)) (* foo 3))))
3256 "(function () {
3257 var foo;
3258 var foo1;
3259 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3260 });")
3262 (test-ps-js defun-comment1
3263 (defun foo (x)
3264 "BARBAR is a revolutionary new foobar.
3265 X y and x."
3266 (1+ x))
3267 "/**
3268 * BARBAR is a revolutionary new foobar.
3269 * X y and x.
3271 function foo(x) {
3272 return x + 1;
3273 };")
3275 (test-ps-js var-comment
3276 (var x 1 "foo")
3277 "/** foo */
3278 var x = 1;")
3280 (test-ps-js case-return-break-broken-return
3281 (defun foo ()
3282 (case x
3283 ("bar" (if y (return-from foo t) nil))
3284 ("baz" nil)))
3285 "function foo() {
3286 switch (x) {
3287 case 'bar':
3288 if (y) {
3289 return true;
3290 } else {
3291 return null;
3293 case 'baz':
3294 return null;
3296 };")
3298 (test-ps-js case-return-break1-broken-return
3299 (defun foo ()
3300 (case x
3301 ("bar" (if y (return-from foo t)))
3302 ("baz" nil)))
3303 "function foo() {
3304 switch (x) {
3305 case 'bar':
3306 if (y) {
3307 return true;
3308 } else {
3309 return null;
3311 case 'baz':
3312 return null;
3314 };")
3316 (test-ps-js setf-progn
3317 (setf foo (progn (bar) (baz) 3))
3318 "bar();
3319 baz();
3320 foo = 3;")
3322 (test-ps-js var-progn
3323 (var x (progn (foo) (bar)))
3324 "foo();
3325 var x = bar();")
3327 (test-ps-js implicit-return-loop
3328 (lambda ()
3329 (if baz 7
3330 (progn
3331 (loop :repeat 100 :do (bar))
3332 42)))
3333 "(function () {
3334 if (baz) {
3335 return 7;
3336 } else {
3337 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3338 bar();
3340 return 42;
3342 });")
3344 (test-ps-js loop-closures
3345 (dotimes (i 10) (lambda () (+ i 1)))
3346 "(function () {
3347 for (var i = 0; i < 10; i += 1) {
3348 function () {
3349 return i + 1;
3352 })();")
3354 (test-ps-js loop-closures-let
3355 (dotimes (i 10)
3356 (let ((x (+ i 1)))
3357 (lambda () (+ i x))))
3358 "(function () {
3359 for (var i = 0; i < 10; i += 1) {
3360 with ({ x : null }) {
3361 var x = i + 1;
3362 function () {
3363 return i + x;
3367 })();")
3369 (test-ps-js loop-closures-flet
3370 (dotimes (i 10)
3371 (flet ((foo (x) (+ i x)))
3372 (lambda () (foo i))))
3373 "(function () {
3374 for (var i = 0; i < 10; i += 1) {
3375 with ({ foo : null }) {
3376 var foo = function (x) {
3377 return i + x;
3379 function () {
3380 return foo(i);
3384 })();")
3386 (test-ps-js while-closures-let
3387 (while (foo)
3388 (let ((abc (bar)))
3389 (lambda () (+ 1 abc))))
3390 "while (foo()) {
3391 with ({ abc : null }) {
3392 var abc = bar();
3393 function () {
3394 return 1 + abc;
3397 };")
3399 (test-ps-js dotted-list-form
3400 (defun foo (a)
3401 (when a
3402 (destructuring-bind (b . c)
3404 (list b c))))
3405 "function foo(a) {
3406 if (a) {
3407 var b = bar[0];
3408 var c = bar.length > 1 ? bar.slice(1) : [];
3409 return [b, c];
3411 };")
3413 (test-ps-js explicit-nil-block
3414 (defun bar ()
3415 (foo 1)
3416 (block nil (return (foo 2)) (+ 1 2))
3418 "function bar() {
3419 foo(1);
3420 nilBlock: {
3421 foo(2);
3422 break nilBlock;
3423 1 + 2;
3425 return 2;
3426 };")
3428 (test-ps-js dynamic-extent-function-return
3429 (defun foo ()
3430 ((lambda ()
3431 (return-from foo 6))))
3432 "function foo() {
3433 try {
3434 return (function () {
3435 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3436 })();
3437 } catch (_ps_err1) {
3438 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3439 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3440 return _ps_err1['__ps_value1'];
3441 } else {
3442 throw _ps_err1;
3445 };")
3447 (test-ps-js dynamic-extent-function-return-nothing
3448 (defun foo ()
3449 ((lambda ()
3450 (return-from foo))))
3451 "function foo() {
3452 try {
3453 return (function () {
3454 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3455 })();
3456 } catch (_ps_err1) {
3457 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3458 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3459 return _ps_err1['__ps_value1'];
3460 } else {
3461 throw _ps_err1;
3464 };")
3466 (test-ps-js dynamic-extent-function-return-values
3467 (defun foo ()
3468 ((lambda ()
3469 (return-from foo (values 1 2 3)))))
3470 "function foo() {
3471 try {
3472 __PS_MV_REG = {};
3473 return (function () {
3474 throw { '__ps_block_tag' : 'foo',
3475 '__ps_value1' : 1,
3476 '__ps_values' : [2, 3] };
3477 })();
3478 } catch (_ps_err1) {
3479 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3480 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3481 return _ps_err1['__ps_value1'];
3482 } else {
3483 throw _ps_err1;
3486 };")
3488 (test-ps-js dynamic-extent-function-return-funcall
3489 (defun foo ()
3490 ((lambda ()
3491 (return-from foo (if baz 6 5)))))
3492 "function foo() {
3493 try {
3494 return (function () {
3495 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3496 })();
3497 } catch (_ps_err1) {
3498 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3499 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3500 return _ps_err1['__ps_value1'];
3501 } else {
3502 throw _ps_err1;
3505 };")
3507 (test-ps-js block-dynamic-return
3508 (var foo ((lambda ()
3509 (block nil
3510 ((lambda () (return 6)))
3511 (+ 1 2)))))
3512 "var foo = (function () {
3513 try {
3514 (function () {
3515 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3516 })();
3517 return 1 + 2;
3518 } catch (_ps_err1) {
3519 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3520 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3521 return _ps_err1['__ps_value1'];
3522 } else {
3523 throw _ps_err1;
3526 })();")
3528 (test-ps-js block-dynamic-return1
3529 (var foo ((lambda ()
3530 (block nil
3531 ((lambda () (return 6)))
3532 (+ 1 2))
3533 (foobar 1 2))))
3534 "var foo = (function () {
3535 nilBlock: {
3536 (function () {
3537 break nilBlock;
3538 })();
3539 1 + 2;
3541 return foobar(1, 2);
3542 })();")
3544 (test-ps-js iteration-lambda-capture-no-need
3545 (dolist (x y)
3546 (lambda (x) (1+ x)))
3547 "(function () {
3548 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3549 x = y[_js_idx1];
3550 function (x) {
3551 return x + 1;
3554 })();")
3556 (test-ps-js case-invert1
3557 (encodeURIComponent fooBar)
3558 "encodeURIComponent(fooBar);")
3560 (test-ps-js simple-ash
3561 (+ (ash 4 1) (ash 4 -1))
3562 "(4 << 1) + (4 >> 1);")
3564 (test-ps-js progn-nil-expression
3565 (bar (progn (foo) nil))
3566 "bar((foo(), null));")
3568 (test-ps-js other-progn-nil-exp
3569 (defun blah ()
3570 (or (foo) (progn (bar) nil)))
3571 "function blah() {
3572 return foo() || (bar(), null);
3573 };")
3575 (test-ps-js lambda-nil-return
3576 (lambda (x)
3577 (block nil
3578 (when x
3579 (return 1))
3581 "(function (x) {
3582 if (x) {
3583 return 1;
3585 return 2;
3586 });")
3588 (test-ps-js lambda-nil-return-implicit-nested2
3589 (lambda (x)
3590 (block foo
3591 (if x
3592 (return-from foo 1)
3593 (dotimes (i 4)
3594 (return-from foo i)))
3596 "(function (x) {
3597 if (x) {
3598 return 1;
3599 } else {
3600 for (var i = 0; i < 4; i += 1) {
3601 return i;
3604 return 2;
3605 });")
3607 (test-ps-js throw-is-a-statement
3608 (defun blah ()
3609 (let ((result (foo)))
3610 (unless (null result)
3611 (throw result))))
3612 "function blah() {
3613 var result = foo();
3614 if (result != null) {
3615 throw result;
3617 };")
3619 (test-ps-js expressify1
3620 (defun blah ()
3621 (when (some-condition)
3622 (foo)
3623 (bar)
3624 (baz)))
3625 "function blah() {
3626 if (someCondition()) {
3627 foo();
3628 bar();
3629 return baz();
3631 };")
3633 (test-ps-js case-when-return
3634 (defun blah (a)
3635 (case a
3636 ("a" (when (foo) (return-from blah 111)))
3637 ("b" t)))
3638 "function blah(a) {
3639 switch (a) {
3640 case 'a':
3641 if (foo()) {
3642 return 111;
3643 } else {
3644 return null;
3646 case 'b':
3647 return true;
3649 };")
3651 (test-ps-js flet-return-from
3652 (defun abc ()
3653 (flet ((foo ()
3654 (return-from foo 123)))
3655 (foo)))
3656 "function abc() {
3657 var foo = function () {
3658 return 123;
3660 return foo();
3661 };")
3663 (test-ps-js flet-return-from1
3664 (flet ((foo ()
3665 (return-from foo 123)))
3666 (foo))
3667 "(function () {
3668 var foo = function () {
3669 return 123;
3671 return foo();
3672 })();")
3674 (test-ps-js lambda-docstring-declarations
3675 (lambda (x)
3676 "This is a docstring"
3677 (declare (ignore x))
3679 "(function (x) {
3680 return 2;
3681 });")
3683 (test-ps-js setf-let-exp
3684 (setf foo (let ((x (+ 1 2)))
3685 (if x 123 456)))
3686 "foo = (function () {
3687 var x = 1 + 2;
3688 return x ? 123 : 456;
3689 })();")
3691 (test-ps-js create-let-exp
3692 (create :abc (let ((x (+ 1 2)))
3693 (if x 123 456)))
3694 "({ 'abc' : (function () {
3695 var x = 1 + 2;
3696 return x ? 123 : 456;
3697 })() });")
3699 (test-ps-js eql-eql-eql-precedence
3700 (unless (equal (= 3 3) (= 3 4))
3701 (chain console (log 1)))
3702 "if ((3 === 3) != (3 === 4)) {
3703 console.log(1);
3704 };")
3706 (test-ps-js case-cond-breaks
3707 (defun blah (x)
3708 (case x
3709 (123 (cond ((foo1)
3710 (when (foo2)
3711 (when (foo3)
3712 (return-from blah nil))
3713 t))))
3714 (456 (foo7))))
3715 "function blah(x) {
3716 switch (x) {
3717 case 123:
3718 if (foo1()) {
3719 if (foo2()) {
3720 if (foo3()) {
3721 return null;
3723 return true;
3724 } else {
3725 return null;
3727 } else {
3728 return null;
3730 case 456:
3731 return foo7();
3733 };")
3735 (test-ps-js cond-double-t
3736 (lambda ()
3737 (cond (foo 1)
3738 (t 2)
3739 (t 3)))
3740 "(function () {
3741 if (foo) {
3742 return 1;
3743 } else {
3744 return 2;
3746 });")
3748 (test-ps-js let-let-funcall-lambda
3749 (let ((x 5))
3750 (let ((x 7))
3751 (funcall (lambda (x) (+ x 9)) x)))
3752 "(function () {
3753 var x = 5;
3754 var x1 = 7;
3755 return (function (x) {
3756 return x + 9;
3757 })(x1);
3758 })();")
3760 (test-ps-js let-let-lambda
3761 (let ((x 5))
3762 (let ((x 7))
3763 (lambda (x) (+ x 9))))
3764 "(function () {
3765 var x = 5;
3766 var x1 = 7;
3767 return function (x) {
3768 return x + 9;
3770 })();")
3772 (test-ps-js let-lambda
3773 (let ((x 5))
3774 (lambda (x) (+ x 9)))
3775 "(function () {
3776 var x = 5;
3777 return function (x) {
3778 return x + 9;
3780 })();")
3782 (test-ps-js symbol-macrolet-no-shadow-lambda
3783 (symbol-macrolet ((x y))
3784 (lambda (x) (+ x x)))
3785 "(function (x) {
3786 return x + x;
3787 });")
3789 (test-ps-js divide-one-arg-reciprocal
3790 (/ 2)
3791 "1 / 2;")
3793 (test-ps-js division-not-associative
3794 (/ a (* b c))
3795 "a / (b * c);")
3797 (test-ps-js divide-expressions
3798 (/ (foo) (bar))
3799 "foo() / bar();")
3801 (test-ps-js divide-expressions1
3802 (floor (1- x) y)
3803 "Math.floor((x - 1) / y);")
3805 (test-ps-js lexical-funargs-shadow1
3806 (lambda (x)
3807 (let ((x 1))
3808 (foo x))
3809 (incf x))
3810 "(function (x) {
3811 var x1 = 1;
3812 foo(x1);
3813 return ++x;
3814 });")
3816 (test-ps-js times-rem
3817 (* x (rem y z))
3818 "x * (y % z);")
3820 (test-ps-js rem-divide
3821 (/ x (rem y z))
3822 "x / (y % z);")
3824 (test-ps-js case-break-return
3825 (lambda () (case x (:foo) (:bar 1)))
3826 "(function () {
3827 switch (x) {
3828 case 'foo':
3829 return null;
3830 case 'bar':
3831 return 1;
3833 });")
3835 (test-ps-js trivial-expression-switch
3836 (foobar (case x (1 2)))
3837 "foobar((function () {
3838 switch (x) {
3839 case 1:
3840 return 2;
3842 })());")
3844 (test-ps-js trivial-expression-while
3845 (foobar (while (< 0 x) (decf x)))
3846 "foobar((function () {
3847 while (0 < x) {
3848 --x;
3850 })());")
3852 (test-ps-js funcall-block-expression-loop-lambda
3853 (foobar (loop for i from 0 to 10 do (1+ i)))
3854 "foobar((function () {
3855 for (var i = 0; i <= 10; i += 1) {
3856 i + 1;
3858 })());")
3860 (test-ps-js plus-block-expression-loop-lambda
3861 (1+ (loop for i from 0 to 10 do (1+ i)))
3862 "(function () {
3863 for (var i = 0; i <= 10; i += 1) {
3864 i + 1;
3866 })() + 1;")
3868 (test-ps-js let-closures-rename
3869 (lambda ()
3870 (let ((x 1)) (lambda () (1+ x)))
3871 (let ((x 2)) (lambda () (1+ x))))
3872 "(function () {
3873 var x = 1;
3874 function () {
3875 return x + 1;
3877 var x1 = 2;
3878 return function () {
3879 return x1 + 1;
3881 });")
3883 (test-ps-js let-closures-rename1
3884 (lambda ()
3885 (let ((x 1))
3886 (let ((y 2))
3887 (lambda () (+ x y))))
3888 (let ((x 2))
3889 (let ((y 3))
3890 (lambda () (+ x y)))))
3891 "(function () {
3892 var x = 1;
3893 var y = 2;
3894 function () {
3895 return x + y;
3897 var x1 = 2;
3898 var y2 = 3;
3899 return function () {
3900 return x1 + y2;
3902 });")
3904 (test-ps-js let-closures-rename2
3905 (defun make-closures ()
3906 (list
3907 (let ((x 1)) (lambda () (1+ x)))
3908 (let ((x 2)) (lambda () (1+ x)))))
3909 "function makeClosures() {
3910 var x;
3911 var x1;
3912 return [(x = 1, function () {
3913 return x + 1;
3914 }), (x1 = 2, function () {
3915 return x1 + 1;
3916 })];
3918 };")
3920 (test-ps-js conditional-not-used-up
3921 (lambda (bar)
3922 (when bar
3923 (let ((x 1))
3924 (1+ x))))
3925 "(function (bar) {
3926 if (bar) {
3927 var x = 1;
3928 return x + 1;
3930 });")
3932 (test-ps-js toplevel-local-scope
3933 (create "fn" (let ((x 5)) (lambda () x)))
3934 "({ 'fn' : (function () {
3935 var x = 5;
3936 return function () {
3937 return x;
3939 })() });")
3941 (test-ps-js toplevel-local-scope1
3942 (defvar foo (create "fn" (let ((x 5)) (lambda () x))))
3943 "var foo = { 'fn' : (function () {
3944 var x = 5;
3945 return function () {
3946 return x;
3948 })() };")
3950 (test-ps-js block-let
3951 (block foobar
3952 (let ((x 1))
3953 (return-from foobar x)
3955 "(function () {
3956 var x = 1;
3957 return x;
3958 return 2;
3959 })();")
3961 (test-ps-js expressionize-if-macroexpand-error
3962 (progn (defmacro xbaz () `(blah))
3964 (defun foo (xbaz)
3965 (unless (blah)
3966 (cond (xbaz (blah))
3967 (t (blahblah))))))
3968 "function foo(xbaz) {
3969 if (!blah()) {
3970 if (xbaz) {
3971 return blah();
3972 } else {
3973 return blahblah();
3976 };")
3978 (test-ps-js toplevel-defun-macroexpand
3979 (progn (defmacro defun-js (name lambda-list &body body)
3980 `(defun ,name ,lambda-list ,@body))
3982 (let ((foo 0))
3983 (defun-js bar () (1+ foo))
3984 (defvar baz 2)))
3985 "var foo = 0;
3986 function bar() {
3987 return foo + 1;
3989 var baz = 2;")
3991 (test-ps-js js-ir-package-unique-symbols
3992 (loop :for i :from 0 :below 5 :do
3993 (let ((block (elt blocks i)))
3994 (foo block)
3995 (lambda () nil)))
3996 "(function () {
3997 for (var i = 0; i < 5; i += 1) {
3998 var block = blocks[i];
3999 foo(block);
4000 function () {
4001 return null;
4004 })();")
4006 (test-ps-js broken-quote-expansion1
4007 (lambda (p)
4008 (with-slots (x y) p
4009 (if (< x 0) y x)))
4010 "(function (p) {
4011 return p.x < 0 ? p.y : p.x;
4012 });")
4014 (test-ps-js broken-quote-expansion2
4015 (progn
4016 (define-symbol-macro foo123 (ps:@ a foo123))
4017 (lambda () (when (> foo123 1) 2)))
4018 "(function () {
4019 return a.foo123 > 1 ? 2 : null;
4020 });")
4022 (test-ps-js unused-named-block-not-printed1
4023 (block foobar
4024 (+ 1 2 3))
4025 "(function () {
4026 return 1 + 2 + 3;
4027 })();")
4029 (test-ps-js unused-named-block-not-printed2
4030 (block nil
4031 (block nil
4032 (+ 1 2 3)))
4033 "(function () {
4034 return 1 + 2 + 3;
4035 })();")
4037 (test-ps-js unused-named-block-not-printed3
4038 (block foobar
4039 (block nil
4040 (+ 1 2 3)))
4041 "(function () {
4042 return 1 + 2 + 3;
4043 })();")
4045 (test-ps-js unused-named-block-not-printed4
4046 (block nil
4047 (block foobar
4048 (block nil
4049 (+ 1 2 3))))
4050 "(function () {
4051 return 1 + 2 + 3;
4052 })();")
4054 (test-ps-js trig-no-bind1
4055 (cosh 3.14)
4056 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
4058 (test-ps-js trig-bind1
4059 (acosh (blah 3.14))
4060 "(function () {
4061 var x1 = blah(3.14);
4062 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
4063 })();")
4065 (test-ps-js double-negation
4066 (or (not foo) (not (not foo)) (not (not (not foo))))
4067 "!foo || foo || !foo;")
4069 (test-ps-js empty-let
4070 (defun foo ()
4071 (let ((a (bar)))))
4072 "function foo() {
4073 var a = bar();
4074 return null;
4075 };")
4077 (test-ps-js empty-let*
4078 (defun foo ()
4079 (let* ((a (bar)))))
4080 "function foo() {
4081 var a = bar();
4082 return null;
4083 };")
4085 (test-ps-js defun-no-body-declare
4086 (defun foo () (declare (ignore x)))
4087 "function foo() {
4088 return null;
4089 };")
4091 (test-ps-js defun-no-body-let-decare
4092 (defun foo () (let () (declare (ignore x))))
4093 "function foo() {
4094 return null;
4095 };")
4097 (test-ps-js empty-defun-docstring-declare
4098 (defun foo (x)
4099 "docstring"
4100 (declare (ignore x)))
4101 "/** docstring */
4102 function foo(x) {
4103 return null;
4104 };")
4106 (test-ps-js defun-docstring-string
4107 (defun foo (x)
4108 "docstring"
4109 "abc")
4110 "/** docstring */
4111 function foo(x) {
4112 return 'abc';
4113 };")
4115 (test-ps-js return-object
4116 (defun foo (obj)
4117 (ps:create :abc (let ((x (ps:getprop obj "blah")))
4118 (if x 123 456))))
4119 "function foo(obj) {
4120 var x;
4121 return { 'abc' : (x = obj['blah'], x ? 123 : 456) };
4122 };")
4124 ;;; broken
4126 ;; (test-ps-js let-defun-toplevel
4127 ;; (progn (let ((foo 0))
4128 ;; (defun bar () foo))
4129 ;; (bar))
4130 ;; "var bar_foo1 = 0;
4131 ;; function bar() {
4132 ;; return bar_foo1;
4133 ;; };
4134 ;; bar();")
4136 ;; (test-ps-js let-defvar-toplevel
4137 ;; (progn (let ((foo 0))
4138 ;; (defvar bar (1+ foo)))
4139 ;; bar)
4140 ;; "var bar_foo1 = 0;
4141 ;; var bar = bar_foo1 + 1;
4142 ;; bar;")
4144 ;; (test-ps-js setf-side-effects
4145 ;; (progn
4146 ;; (let ((x 10))
4147 ;; (defun side-effect()
4148 ;; (setf x 4)
4149 ;; 3)
4150 ;; (setf x (+ 2 (side-effect) x 5))))
4151 ;; "var sideEffect_x1 = 10;
4152 ;; function sideEffect() {
4153 ;; sideEffect_x1 = 4;
4154 ;; return 3;
4155 ;; };
4156 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")