Clarified that the license is BSD 3-clause. Added SPDX identifiers
[parenscript.git] / t / output-tests.lisp
blob3ac873fa2b490c807a2fccda2ccf5a4b06542f4c
1 ;; SPDX-License-Identifier: BSD-3-Clause
3 (in-package #:ps-test)
4 (named-readtables:in-readtable :parenscript)
6 (in-suite output-tests)
8 (test-ps-js statements-and-expressions-1
9 (+ i (if 1 2 3))
10 "i + (1 ? 2 : 3);")
12 (test-ps-js statements-and-expressions-2
13 (if 1 2 3)
14 "if (1) {
16 } else {
18 };")
20 (test-ps-js symbol-conversion-1
21 !?#@%
22 "bangwhathashatpercent;")
24 (test-ps-js symbol-conversion-2
25 bla-foo-bar
26 "blaFooBar;")
28 (test-ps-js symbol-conversion-3
29 *array
30 "Array;")
32 (test-ps-js symbol-conversion-4
33 *global-array*
34 "GLOBALARRAY;")
36 (test-ps-js symbol-conversion-5
37 encodeURIComponent
38 "encodeURIComponent;")
40 (test-ps-js symbol-conversion-6
41 URI
42 "URI;")
44 (test-ps-js number-literals-1
46 "1;")
48 (test-ps-js number-literals-2
49 123.123
50 "123.123;")
52 (test-ps-js number-literals-3
53 #x10
54 "16;")
56 (test-ps-js string-literals-1
57 "foobar"
58 "'foobar';")
60 (test-ps-js string-literals-2
61 "bratzel bub"
62 "'bratzel bub';")
64 (test-ps-js string-literals-3
65 " "
66 "'\\t';")
68 (test-ps-js array-literals-1
69 (array)
70 "[ ];")
72 (test-ps-js array-literals-2
73 (array 1 2 3)
74 "[ 1, 2, 3 ];")
76 (test-ps-js array-literals-3
77 (array (array 2 3)
78 (array "foobar" "bratzel bub"))
79 "[ [ 2, 3 ], [ 'foobar', 'bratzel bub' ] ];")
81 (test-ps-js array-literals-4
82 (make-array)
83 "new Array();")
85 (test-ps-js array-literals-5
86 (make-array 1 2 3)
87 "new Array(1, 2, 3);")
89 (test-ps-js array-literals-6
90 (make-array
91 (make-array 2 3)
92 (make-array "foobar" "bratzel bub"))
93 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
95 (test-ps-js array-init-1
96 (make-array 2 :initial-contents '(10 20))
97 "(function () {
98 var arr1 = new Array(2);
99 var init2 = [10, 20];
100 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
101 arr1[i4] = init2[i4];
103 return arr1;
104 })();")
106 (test-ps-js array-init-2
107 (make-array 5 :initial-element 10)
108 "(function () {
109 var arr1 = new Array(5);
110 var elt3 = 10;
111 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
112 arr1[i4] = elt3;
114 return arr1;
115 })();")
117 (test-ps-js object-literals-1
118 (create foo "bar" :blorg 1)
119 "({ foo : 'bar', 'blorg' : 1 });")
121 (test-ps-js object-literals-2
122 (create foo "hihi"
123 blorg (array 1 2 3)
124 another-object (create :schtrunz 1))
125 "({ foo : 'hihi',
126 blorg : [ 1, 2, 3 ],
127 anotherObject : { 'schtrunz' : 1 } });")
129 (test-ps-js object-literals-3
130 (getprop an-object 'foo)
131 "anObject.foo;")
133 (test-ps-js object-literals-4
134 (@ an-object foo bar)
135 "anObject.foo.bar;")
137 (test-ps-js object-literals-5
138 (with-slots (a b c) this
139 (+ a b c))
140 "this.a + this.b + this.c;")
142 (test-ps-js with-slots-single-eval
143 (lambda () (with-slots (a b) (foo) (+ a b)))
144 "(function () {
145 var object1 = foo();
146 return object1.a + object1.b;
147 });")
149 (test-ps-js object-literal-quoted-symbols
150 (create 'test "bang" 'symbol-saved-my-life "parenscript")
151 "({ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' });")
153 (test-ps-js object-literal-property-accessors
154 (defun foo ()
155 (let ((x 10))
156 (create (get x) x
157 (set x v) (setf x v))))
158 "function foo() {
159 var x = 10;
160 return { get x() {
161 return x;
162 }, set x(v) {
163 return x = v;
164 } };
166 :js-target-version "1.8.5")
168 (test-ps-js object-method-apply-1
169 (apply (@ an-object foo) nil)
170 "anObject.foo.apply(anObject, null);")
172 (test-ps-js object-method-apply-2
173 (apply (getprop (make-an-object) foo 'bar) nil)
174 "(function () {
175 var _js1 = makeAnObject()[foo];
176 var _js2 = _js1.bar;
177 return _js2.apply(_js1, null);
178 })();")
180 (test-ps-js object-method-apply-3
181 (apply (@ (make-an-object) foo) (bar))
182 "(function () {
183 var _js1 = makeAnObject();
184 var _js2 = _js1.foo;
185 return _js2.apply(_js1, bar());
186 })();")
188 (test-ps-js regular-expression-literals-1
189 (regex "foobar")
190 "/foobar/;")
192 (test-ps-js regular-expression-literals-2
193 (regex "/foobar/i")
194 "/foobar/i;")
196 (test-ps-js literal-symbols-1
198 "true;")
200 (test-ps-js literal-symbols-2
201 false
202 "false;")
204 (test-ps-js literal-symbols-3
206 "false;")
208 (test-ps-js literal-symbols-4
209 (lambda () nil)
210 "(function () {
211 return null;
212 });")
214 (test-ps-js literal-symbols-5
215 undefined
216 "undefined;")
218 (test-ps-js literal-symbols-6
219 this
220 "this;")
222 (test-ps-js variables-1
223 variable
224 "variable;")
226 (test-ps-js variables-2
227 a-variable
228 "aVariable;")
230 (test-ps-js variables-3
231 *math
232 "Math;")
234 (test-ps-js function-calls-and-method-calls-1
235 (blorg 1 2)
236 "blorg(1, 2);")
238 (test-ps-js function-calls-and-method-calls-2
239 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
240 "foobar(blorg(1, 2), blabla(3, 4), [ 2, 3, 4 ]);")
242 (test-ps-js function-calls-and-method-calls-3
243 ((getprop this 'blorg) 1 2)
244 "this.blorg(1, 2);")
246 (test-ps-js function-calls-and-method-calls-4
247 ((aref foo i) 1 2)
248 "foo[i](1, 2);")
250 (test-ps-js function-calls-and-method-calls-5
251 ((getprop (aref foobar 1) 'blorg) nil t)
252 "foobar[1].blorg(null, true);")
254 (test-ps-js operator-expressions-1
255 (* 1 2)
256 "1 * 2;")
258 (test-ps-js operator-expressions-2
259 (= 1 2)
260 "1 === 2;")
262 (test-ps-js operator-expressions-3
263 (* 1 (+ 2 3 4) 4 (/ 6 7))
264 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
266 (test-ps-js operator-expressions-4
267 (incf i)
268 "++i;")
270 (test-ps-js operator-expressions-5
271 (decf i)
272 "--i;")
274 (test-ps-js operator-expressions-6
275 (1- i)
276 "i - 1;")
278 (test-ps-js operator-expressions-7
279 (1+ i)
280 "i + 1;")
282 (test-ps-js operator-expressions-8
283 (not (< i 2))
284 "i >= 2;")
286 (test-ps-js body-forms-1
287 (progn (blorg i) (blafoo i))
288 "blorg(i);
289 blafoo(i);")
291 (test-ps-js body-forms-2
292 (+ i (progn (blorg i) (blafoo i)))
293 "i + (blorg(i), blafoo(i));")
295 (test-ps-js function-definition-1
296 (defun a-function (a b)
297 (+ a b))
298 "function aFunction(a, b) {
299 return a + b;
300 };")
302 (test-ps-js lambda-definition-2
303 (lambda (a b) (+ a b))
304 "(function (a, b) {
305 return a + b;
306 });")
308 (test-ps-js assignment-1
309 (setf a 1)
310 "a = 1;")
312 (test-ps-js assignment-2
313 (setf a 2 b 3 c 4 x (+ a b c))
314 "a = 2;
315 b = 3;
316 c = 4;
317 x = a + b + c;")
319 (test-ps-js assignment-3
320 (setf a (+ a 2 3 4 a))
321 "a = a + 2 + 3 + 4 + a;")
323 (test-ps-js assignment-4
324 (setf a (- 1 a))
325 "a = 1 - a;")
327 (test-ps-js assignment-5
328 (let ((a 1) (b 2))
329 (psetf a b b a))
330 "(function () {
331 var a = 1;
332 var b = 2;
333 var _js3 = b;
334 var _js4 = a;
335 a = _js3;
336 return b = _js4;
337 })();")
339 (test-ps-js assignment-6
340 (setq a 1)
341 "a = 1;")
343 (test-ps-js assignment-8
344 (progn
345 (defun (setf color) (new-color el)
346 (setf (getprop (getprop el 'style) 'color) new-color))
347 (setf (color some-div) (+ 23 "em")))
348 "function __setf_color(newColor, el) {
349 return el.style.color = newColor;
351 __setf_color(23 + 'em', someDiv);")
353 (test-ps-js assignment-10
354 (progn
355 (defsetf left (el) (offset)
356 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
357 (setf (left some-div) (+ 123 "px")))
358 "(function () {
359 var _js2 = someDiv;
360 var _js1 = 123 + 'px';
361 return _js2.style.left = _js1;
362 })();")
364 (test-ps-js assignment-12
365 (macrolet ((left (el)
366 `(getprop ,el 'offset-left)))
367 (left some-div))
368 "someDiv.offsetLeft;")
370 (test-ps-js nil-block-return-1
371 (block nil (return) 1)
372 "(function () {
373 return null;
374 return 1;
375 })();")
377 (test-ps-js single-argument-statements-2
378 (throw "foobar")
379 "throw 'foobar';")
381 (test-ps-js single-argument-expression-1
382 (delete (new (*foobar 2 3 4)))
383 "delete new Foobar(2, 3, 4);")
385 (test-ps-js single-argument-expression-2
386 (if (= (typeof blorg) *string)
387 (alert (+ "blorg is a string: " blorg))
388 (alert "blorg is not a string"))
389 "if (typeof blorg === String) {
390 alert('blorg is a string: ' + blorg);
391 } else {
392 alert('blorg is not a string');
393 };")
395 (test-ps-js conditional-statements-1
396 (defun foo ()
397 (if ((@ blorg is-correct))
398 (progn (carry-on) (return-from foo i))
399 (alert "blorg is not correct!")))
400 "function foo() {
401 if (blorg.isCorrect()) {
402 carryOn();
403 return i;
404 } else {
405 return alert('blorg is not correct!');
407 };")
409 (test-ps-js conditional-statements-2
410 (+ i (if ((@ blorg add-one)) 1 2))
411 "i + (blorg.addOne() ? 1 : 2);")
413 (test-ps-js conditional-statements-3
414 (defun foo ()
415 (when ((@ blorg is-correct))
416 (carry-on)
417 (return-from foo i)))
418 "function foo() {
419 if (blorg.isCorrect()) {
420 carryOn();
421 return i;
423 };")
425 (test-ps-js conditional-statements-4
426 (unless ((@ blorg is-correct))
427 (alert "blorg is not correct!"))
428 "if (!blorg.isCorrect()) {
429 alert('blorg is not correct!');
430 };")
432 (test-ps-js variable-declaration-1
433 (defvar *a* (array 1 2 3))
434 "var A = [ 1, 2, 3 ];")
436 (test-ps-js variable-declaration-2
437 (progn (defvar *a* 4)
438 (let ((x 1)
439 (*a* 2))
440 (let* ((y (+ x 1))
441 (x (+ x y)))
442 (+ *a* x y))))
443 "var A = 4;
444 (function () {
445 var x = 1;
446 var A_TMPSTACK1;
447 try {
448 A_TMPSTACK1 = A;
449 A = 2;
450 var y = x + 1;
451 var x2 = x + y;
452 return A + x2 + y;
453 } finally {
454 A = A_TMPSTACK1;
456 })();")
458 (test-ps-js iteration-constructs-1
459 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
460 (d 0 (1+ d))
461 (e (aref c d) (aref c d)))
462 ((or (= d (@ c length)) (string= e "x")))
463 (setf a d b e)
464 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
465 "(function () {
466 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
467 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
468 a = d;
469 b = e;
470 document.write('a: ' + a + ' b: ' + b + '<br/>');
472 })();")
474 (test-ps-js iteration-constructs-2
475 (do ((i 0 (1+ i))
476 (s 0 (+ s i (1+ i))))
477 ((> i 10))
478 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
479 "(function () {
480 var i = 0;
481 var s = 0;
482 for (; i <= 10; ) {
483 document.write('i: ' + i + ' s: ' + s + '<br/>');
484 var _js1 = i + 1;
485 var _js2 = s + i + (i + 1);
486 i = _js1;
487 s = _js2;
489 })();")
491 (test-ps-js iteration-constructs-3
492 (do* ((i 0 (1+ i))
493 (s 0 (+ s i (1- i))))
494 ((> i 10))
495 ((@ document write) (+ "i: " i " s: " s "<br/>")))
496 "(function () {
497 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
498 document.write('i: ' + i + ' s: ' + s + '<br/>');
500 })();")
502 (test-ps-js iteration-constructs-4
503 (let ((arr (array "a" "b" "c" "d" "e")))
504 (dotimes (i (@ arr length))
505 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
506 "(function () {
507 var arr = ['a', 'b', 'c', 'd', 'e'];
508 for (var i = 0; i < arr.length; i += 1) {
509 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
511 })();")
513 (test-ps-js iteration-constructs-5
514 (let ((res 0))
515 (alert (+ "Summation to 10 is "
516 (dotimes (i 10 res)
517 (incf res (1+ i))))))
518 "(function () {
519 var res = 0;
520 return alert('Summation to 10 is ' + (function () {
521 for (var i = 0; i < 10; i += 1) {
522 res += i + 1;
524 return res;
525 })());
526 })();")
528 (test-ps-js iteration-constructs-6
529 (let ((l (list 1 2 4 8 16 32)))
530 (dolist (c l)
531 ((@ document write) (+ "c: " c "<br/>"))))
532 "(function () {
533 var l = [1, 2, 4, 8, 16, 32];
534 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
535 c = l[_js_idx2];
536 document.write('c: ' + c + '<br/>');
538 })();")
540 (test-ps-js iteration-constructs-7
541 (let ((l '(1 2 4 8 16 32))
542 (s 0))
543 (alert (+ "Sum of " l " is: "
544 (dolist (c l s)
545 (incf s c)))))
546 "(function () {
547 var l = [1, 2, 4, 8, 16, 32];
548 var s = 0;
549 return alert('Sum of ' + l + ' is: ' + (function () {
550 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
551 c = l[_js_idx1];
552 s += c;
554 return s;
555 })());
556 })();")
558 (test-ps-js iteration-constructs-8
559 (let ((obj (create a 1 b 2 c 3)))
560 (for-in (i obj)
561 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
562 "(function () {
563 var obj = { a : 1, b : 2, c : 3 };
564 for (var i in obj) {
565 document.write(i + ': ' + obj[i] + '<br/>');
567 })();")
569 (test-ps-js iteration-constructs-9
570 (while ((@ film is-not-finished))
571 ((@ this eat) (new *popcorn)))
572 "while (film.isNotFinished()) {
573 this.eat(new Popcorn);
574 };")
576 (test-ps-js loop-for-bindings
577 (loop :for ((a b) (:c :d)) :in arr :do (foo a b c d))
578 "(function () {
579 var _js2 = arr.length;
580 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
581 var _db4 = arr[_js1];
582 var _db5 = _db4[0];
583 var a = _db5[0];
584 var b = _db5[1];
585 var _js3 = _db4[1];
586 var c = _js3['c'];
587 var d = _js3['d'];
588 foo(a, b, c, d);
590 })();")
592 (test-ps-js loop-for-on
593 (loop :for (k v) :on plist :by 2 :do (foo k v))
594 "(function () {
595 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
596 var k = _js1[0];
597 var v = _js1[1];
598 foo(k, v);
600 })();")
602 (test-ps-js loop-for-keys-of
603 (loop :for k :of obj :do (foo k))
604 "(function () {
605 for (var k in obj) {
606 foo(k);
608 })();")
610 (test-ps-js loop-for-key-val-pairs-of
611 (loop :for (k v) :of obj :do (foo k v))
612 "(function () {
613 for (var k in obj) {
614 var v = obj[k];
615 foo(k, v);
617 })();")
619 (test-ps-js loop-for-key-val-pairs-of-with-bindings
620 (loop :for (k (a b)) :of obj :do (foo k a b))
621 "(function () {
622 for (var k in obj) {
623 var _db1 = obj[k];
624 var a = _db1[0];
625 var b = _db1[1];
626 foo(k, a, b);
628 })();")
630 (test-ps-js loop-for-just-vals-of
631 (loop :for (nil v) :of obj :do (foo k v))
632 "(function () {
633 for (var _js1 in obj) {
634 var v = obj[_js1];
635 foo(k, v);
637 })();")
639 (test-ps-js loop-map-to
640 (loop :for str :in strs :map str :to (length str))
641 "(function () {
642 var _js2 = strs.length;
643 var map3 = { };
644 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
645 var str = strs[_js1];
646 map3[str] = str.length;
648 return map3;
649 })();")
651 (test-ps-js loop-for-of-map-to
652 (loop :for k :of obj :map k :to (foo k))
653 "(function () {
654 var map1 = { };
655 for (var k in obj) {
656 map1[k] = foo(k);
658 return map1;
659 })();")
661 (test-ps-js loop-for-of-when
662 (loop :for k :of obj :when (foo k) :map k :to (bar k))
663 "(function () {
664 var map1 = { };
665 for (var k in obj) {
666 if (foo(k)) {
667 map1[k] = bar(k);
670 return map1;
671 })();")
673 (test-ps-js loop-for-in-until-when
674 (loop :for a :in b :until (> a 100) :when (< a 50) :do (foo a))
675 "(function () {
676 var _js2 = b.length;
677 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
678 var a = b[_js1];
679 if (a > 100) {
680 break;
682 if (a < 50) {
683 foo(a);
686 })();")
688 (test-ps-js loop-with-for-when
689 (loop :with c = c1 :for d :from c1 :below c2
690 :when (foo c d) :do (setf c d)
691 :do (bar d))
692 "(function () {
693 var c = c1;
694 for (var d = c1; d < c2; d += 1) {
695 if (foo(c, d)) {
696 c = d;
698 bar(d);
700 })();")
702 (test-ps-js loop-for-then-for-in-while
703 (defun blah (c)
704 (loop :for a = (foo) :then (bar) :for b :in c :while b :do (foo a b c)))
705 "function blah(c) {
706 var _js2 = c.length;
707 var FIRST3 = true;
708 for (var a = foo(); true; a = bar()) {
709 var _js1 = FIRST3 ? 0 : _js1 + 1;
710 if (_js1 >= _js2) {
711 break;
713 var b = c[_js1];
714 if (!b) {
715 break;
717 foo(a, b, c);
718 FIRST3 = null;
720 };")
722 (test-ps-js loop-while-when
723 (loop :for a = (pop stack) :while a :for (b c) = (foo a) :when b :do (bar c))
724 "(function () {
725 for (var a = pop(stack); a; a = pop(stack)) {
726 var _db1 = foo(a);
727 var b = _db1[0];
728 var c = _db1[1];
729 if (b) {
730 bar(c);
733 })();")
735 (test-ps-js loop-for-of-for-in
736 (defun blah (obj b)
737 (loop :for k :of obj :for a :in b :do (foo k a)))
738 "function blah(obj, b) {
739 var _js2 = b.length;
740 var FIRST3 = true;
741 for (var k in obj) {
742 var _js1 = FIRST3 ? 0 : _js1 + 1;
743 if (_js1 >= _js2) {
744 break;
746 var a = b[_js1];
747 foo(k, a);
748 FIRST3 = null;
750 };")
752 (test-ps-js loop-for-dot
753 (loop :for (op . args) :in expr :do (foo op args))
754 "(function () {
755 var _js2 = expr.length;
756 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
757 var _db3 = expr[_js1];
758 var op = _db3[0];
759 var args = _db3.length > 1 ? _db3.slice(1) : [];
760 foo(op, args);
762 })();")
764 (test-ps-js loop-for-rest
765 (loop :for (op &rest args) :in expr :do (foo op args))
766 "(function () {
767 var _js2 = expr.length;
768 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
769 var _db3 = expr[_js1];
770 var op = _db3[0];
771 var args = _db3.length > 1 ? _db3.slice(1) : [];
772 foo(op, args);
774 })();")
776 (test-ps-js loop-collect
777 (setf x (loop :for a :in b :collect (foo a)))
778 "x = (function () {
779 var _js2 = b.length;
780 var collect3 = [];
781 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
782 var a = b[_js1];
783 collect3.push(foo(a));
785 return collect3;
786 })();")
788 (test-ps-js loop-append
789 (loop :for a :in b :append a)
790 "(function () {
791 var _js2 = b.length;
792 var append3 = [];
793 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
794 var a = b[_js1];
795 append3 = append3.concat(a);
797 return append3;
798 })();")
800 (test-ps-js the-case-statement-1
801 (case (aref blorg i)
802 ((1 "one") (alert "one"))
803 (2 (alert "two"))
804 (t (alert "default clause")))
805 "switch (blorg[i]) {
806 case 1:
807 case 'one':
808 alert('one');
809 break;
810 case 2:
811 alert('two');
812 break;
813 default:
814 alert('default clause');
815 };")
817 (test-ps-js the-case-statement-2
818 (switch (aref blorg i)
819 (1 (alert "If I get here"))
820 (2 (alert "I also get here"))
821 (default (alert "I always get here")))
822 "switch (blorg[i]) {
823 case 1: alert('If I get here');
824 case 2: alert('I also get here');
825 default: alert('I always get here');
826 };")
828 (test-ps-js the-try-statement-1
829 (try (throw "i")
830 (:catch (error)
831 (alert (+ "an error happened: " error)))
832 (:finally
833 (alert "Leaving the try form")))
834 "try {
835 throw 'i';
836 } catch (error) {
837 alert('an error happened: ' + error);
838 } finally {
839 alert('Leaving the try form');
840 };")
842 (test-ps-js the-html-generator-1
843 (ps-html ((:a :href "foobar") "blorg"))
844 "'<A HREF=\"foobar\">blorg</A>';")
846 (test-ps-js the-html-generator-2
847 (ps-html ((:a :href (generate-a-link)) "blorg"))
848 "['<A HREF=\"', generateALink(), '\">blorg</A>'].join('');")
850 (test-ps-js the-html-generator-3
851 (funcall (getprop document 'write)
852 (ps-html ((:a :href "#"
853 :onclick (ps-inline (transport))) "link")))
854 "document.write(['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">link</A>'].join(''));")
856 (test-ps-js the-html-generator-4
857 (let ((disabled nil)
858 (authorized t))
859 (setf (getprop element 'inner-h-t-m-l)
860 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
861 "Edit me"))))
862 "(function () {
863 var disabled = null;
864 var authorized = true;
865 return element.innerHTML = ['<TEXTAREA', disabled || !authorized ? [' DISABLED=\"', 'disabled', '\"'].join('') : '', '>Edit me</TEXTAREA>'].join('');
866 })();")
868 (test-ps-js plus-is-not-commutative
869 (setf x (+ "before" x "after"))
870 "x = 'before' + x + 'after';")
872 (test-ps-js plus-works-if-first
873 (setf x (+ x "middle" "after"))
874 "x = x + 'middle' + 'after';")
876 (test-ps-js method-call-op-form
877 (funcall (getprop (+ "" x) 'to-string))
878 "('' + x).toString();")
880 (test-ps-js method-call-op-form-args
881 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
882 "('' + x).foo(1, 2, 'baz', 3);")
884 (test-ps-js method-call-string
885 ((getprop "hi" 'to-string))
886 "'hi'.toString();")
888 (test-ps-js method-call-conditional
889 ((if a x y) 1)
890 "(a ? x : y)(1);")
892 (test-ps-js method-call-variable
893 ((@ x to-string))
894 "x.toString();")
896 (test-ps-js method-call-array
897 ((@ (list 10 20) to-string))
898 "[ 10, 20 ].toString();")
900 (test-ps-js method-call-lambda-call
901 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
902 "(function (x) { return x; })(10).toString();")
904 (test no-whitespace-before-dot
905 (let* ((str (ps* '((@ ((lambda (x) x) 10) to-string))))
906 (dot-pos (position #\. str :test #'char=))
907 (char-before (elt str (1- dot-pos)))
908 (a-parenthesis #\)))
909 (is (char= char-before a-parenthesis))))
911 (test-ps-js simple-getprop
912 (let ((foo (create a 1)))
913 (alert (getprop foo 'a)))
914 "(function () {
915 var foo = { a : 1 };
916 return alert(foo.a);
917 })();")
919 (test-ps-js buggy-getprop
920 (getprop foo slot-name)
921 "foo[slotName];")
923 (test-ps-js buggy-getprop-two
924 (getprop foo (get-slot-name))
925 "foo[getSlotName()];")
927 (test-ps-js old-case-is-now-switch
928 ;; Switch was "case" before, but that was very non-lispish.
929 ;; For example, this code makes three messages and not one
930 ;; which may have been expected. This is because a switch
931 ;; statment must have a break statement for it to return
932 ;; after the alert. Otherwise it continues on the next
933 ;; clause.
934 (switch (aref blorg i)
935 (1 (alert "one"))
936 (2 (alert "two"))
937 (default (alert "default clause")))
938 "switch (blorg[i]) {
939 case 1: alert('one');
940 case 2: alert('two');
941 default: alert('default clause');
942 };")
944 (test-ps-js lisp-like-case
945 (case (aref blorg i)
946 (1 (alert "one"))
947 (2 (alert "two"))
948 (t (alert "default clause")))
949 "switch (blorg[i]) {
950 case 1:
951 alert('one');
952 break;
953 case 2:
954 alert('two');
955 break;
956 default: alert('default clause');
957 };")
960 (test-ps-js even-lispier-case
961 (case (aref blorg i)
962 ((1 2) (alert "Below three"))
963 (3 (alert "Three"))
964 (t (alert "Something else")))
965 "switch (blorg[i]) {
966 case 1:
967 case 2:
968 alert('Below three');
969 break;
970 case 3:
971 alert('Three');
972 break;
973 default: alert('Something else');
974 };")
976 (test-ps-js otherwise-case
977 (case (aref blorg i)
978 (1 (alert "one"))
979 (otherwise (alert "default clause")))
980 "switch (blorg[i]) {
981 case 1:
982 alert('one');
983 break;
984 default: alert('default clause');
985 };")
987 (test escape-sequences-in-string
988 (let ((escapes `((#\\ . #\\)
989 (#\b . #\Backspace)
990 (#\f . ,(code-char 12))
991 ("u000B" . ,(code-char #x000b));;Vertical tab, too uncommon to bother with
992 (#\n . #\Newline)
993 (#\r . #\Return)
994 (#\' . #\');;Double quote need not be quoted because parenscript strings are single quoted
995 (#\t . #\Tab)
996 ("u001F" . ,(code-char #x001f));; character below 32
997 ("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
998 ("uABCD" . ,(code-char #xabcd)))));; Really above ascii.
999 (loop for (js-escape . lisp-char) in escapes
1000 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
1001 for wanted = (format nil "'hello\\~ahi';" js-escape)
1002 do (is (string= (normalize-js-code generated) wanted)))))
1004 (test-ps-js getprop-setf
1005 (setf (getprop x 'y) (+ (+ a 3) 4))
1006 "x.y = (a + 3) + 4;")
1008 (test-ps-js getprop-conditional1
1009 (getprop (if zoo foo bar) 'x)
1010 "(zoo ? foo : bar).x;")
1012 (test-ps-js getprop-conditional2
1013 (getprop (if (not zoo) foo bar) 'x)
1014 "(!zoo ? foo : bar).x;")
1016 (test script-star-eval1
1017 (is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x 1) '(setf y 2))))))
1019 (test script-star-eval2
1020 (is (string= "x = 1;" (normalize-js-code (ps* '(setf x 1))))))
1022 (test-ps-js list-with-single-nil
1023 (array nil)
1024 "[null];")
1026 (test-ps-js quoted-nil-is-array
1027 'nil
1028 "[];")
1030 (test-ps-js quoted-nil-is-array1
1032 "[];")
1034 (test-ps-js literal-nil
1035 (foo ())
1036 "foo(null);")
1038 (test-ps-js quoted-quoted-nil
1039 '(())
1040 "[null];")
1042 (test-ps-js quoted-quoted-nil1
1043 '(1 ())
1044 "[1, null];")
1046 (test-ps-js defsetf1
1047 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1048 (setf (baz 1 2) 3))
1049 "(function () {
1050 var _js2 = 1;
1051 var _js3 = 2;
1052 var _js1 = 3;
1053 return setBaz(_js2, _js3, _js1);
1054 })();")
1056 (test-ps-js setf-macroexpands1
1057 (macrolet ((bar (x y)
1058 `(aref ,x ,y 1)))
1059 (setf (bar foo 2) 3))
1060 "foo[2][1] = 3;")
1062 (test-ps-js defsetf-short
1063 (progn (defsetf baz set-baz "docstring")
1064 (setf (baz 1 2 3) "foo"))
1065 "setBaz(1, 2, 3, 'foo');")
1067 (test-ps-js defun-setf1
1068 (progn (defun (setf some-thing) (new-val i1 i2)
1069 (setf (aref *some-thing* i1 i2) new-val))
1070 (setf (some-thing 1 2) "foo"))
1071 "function __setf_someThing(newVal, i1, i2) {
1072 return SOMETHING[i1][i2] = newVal;
1074 __setf_someThing('foo', 1, 2);")
1076 (test-ps-js defun-optional1
1077 (defun test-opt (&optional x)
1078 (if x "yes" "no"))
1079 "function testOpt(x) {
1080 return x ? 'yes' : 'no';
1081 };")
1083 (test-ps-js defun-optional2
1084 (defun foo (x &optional y)
1085 (+ x y))
1086 "function foo(x, y) {
1087 return x + y;
1088 };")
1090 (test-ps-js defun-optional3
1091 (defun blah (&optional (x 0))
1093 "function blah(x) {
1094 if (x === undefined) {
1095 x = 0;
1097 return x;
1098 };")
1100 (test-ps-js arglist-optional4
1101 (lambda (&optional (x 0 supplied?))
1103 "(function (x) {
1104 var suppliedwhat = x !== undefined;
1105 if (!suppliedwhat) {
1106 x = 0;
1108 return x;
1109 });")
1111 (test-ps-js return-nothing
1112 (defun foo () (return-from foo))
1113 "function foo() {
1114 return null;
1115 };")
1117 (test-ps-js return-values
1118 (defun foo () (return-from foo (values 1 2 3)))
1119 "function foo() {
1120 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [2, 3] };
1121 return 1;
1122 };")
1124 (test-ps-js set-timeout
1125 (set-timeout (lambda () (alert "foo")) 10)
1126 "setTimeout(function () { return alert('foo'); }, 10);")
1128 (test-ps-js operator-precedence
1129 (* 3 (+ 4 5) 6)
1130 "3 * (4 + 5) * 6;")
1132 (test-ps-js operators-1
1133 (in prop obj)
1134 "prop in obj;")
1136 (test-ps-js incf1
1137 (incf foo bar)
1138 "foo += bar;")
1140 (test-ps-js decf1
1141 (decf foo bar)
1142 "foo -= bar;")
1144 (test-ps-js incf2
1145 (incf x 5)
1146 "x += 5;")
1148 (test-ps-js decf2
1149 (decf y 10)
1150 "y -= 10;")
1152 (test-ps-js setf-conditional
1153 (setf foo (if x 1 2))
1154 "foo = x ? 1 : 2;")
1156 (test-ps-js obj-literal-numbers
1157 (create 1 "foo")
1158 "({ 1 : 'foo' });")
1160 (test-ps-js obj-literal-strings
1161 (create "foo" 2)
1162 "({ 'foo' : 2 });")
1164 (test-ps-js getprop-string
1165 (getprop foo "bar")
1166 "foo['bar'];")
1168 (test-ps-js getprop-string1
1169 (getprop "bar" 'length)
1170 "'bar'.length;")
1172 (test-ps-js getprop-progn
1173 (getprop (progn (some-fun "abc") "123") "length")
1174 "(someFun('abc'), '123')['length'];")
1176 (test-ps-js method-call-block
1177 ((@ (progn (some-fun "abc") "123") to-string))
1178 "(someFun('abc'), '123').toString();")
1180 (test-ps-js create-blank
1181 (create)
1182 "({ });")
1184 (test-ps-js blank-object-literal
1186 "({ });")
1188 (test-ps-js array-literal1
1190 "[];")
1192 (test-ps-js array-literal2
1193 ([])
1194 "[];")
1196 (test-ps-js array-literal3
1197 ([] 1 2 3)
1198 "[1, 2, 3];")
1200 (test-ps-js array-literal4
1201 ([] 1 (2 3))
1202 "[1, [2, 3]];")
1204 (test-ps-js array-literal5
1205 ([] (1 2) ("a" "b"))
1206 "[[1, 2], ['a', 'b']];")
1208 (test-ps-js defun-rest1
1209 (defun foo (&rest bar)
1210 (alert (aref bar 1)))
1211 "function foo() {
1212 var bar = Array.prototype.slice.call(arguments, 0);
1213 return alert(bar[1]);
1214 };")
1216 (test-ps-js defun-rest2
1217 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1218 "function foo(baz) {
1219 var bar = Array.prototype.slice.call(arguments, 1);
1220 return baz + bar[1];
1221 };")
1223 (test-ps-js defun-keyword1
1224 (defun zoo (foo bar &key baz) (+ foo bar baz))
1225 "function zoo(foo, bar) {
1226 var _js2 = arguments.length;
1227 for (var n1 = 2; n1 < _js2; n1 += 2) {
1228 switch (arguments[n1]) {
1229 case 'baz':
1230 baz = arguments[n1 + 1];
1233 var baz;
1234 return foo + bar + baz;
1235 };")
1237 (test-ps-js defun-keyword2
1238 (defun zoo (&key baz) (* baz baz))
1239 "function zoo() {
1240 var _js2 = arguments.length;
1241 for (var n1 = 0; n1 < _js2; n1 += 2) {
1242 switch (arguments[n1]) {
1243 case 'baz':
1244 baz = arguments[n1 + 1];
1247 var baz;
1248 return baz * baz;
1249 };")
1251 (test-ps-js defun-keyword3
1252 (defun zoo (&key baz (bar 4)) (* baz bar))
1253 "function zoo() {
1254 var _js2 = arguments.length;
1255 for (var n1 = 0; n1 < _js2; n1 += 2) {
1256 switch (arguments[n1]) {
1257 case 'baz':
1258 baz = arguments[n1 + 1];
1259 break;
1260 case 'bar':
1261 bar = arguments[n1 + 1];
1264 var baz;
1265 var bar = 'undefined' === typeof bar ? 4 : bar;
1266 return baz * bar;
1267 };")
1269 (test-ps-js defun-keyword4
1270 (defun hello-world (&key ((:my-name-key my-name) 1))
1271 my-name)
1272 "function helloWorld() {
1273 var _js2 = arguments.length;
1274 for (var n1 = 0; n1 < _js2; n1 += 2) {
1275 switch (arguments[n1]) {
1276 case 'my-name-key':
1277 myName = arguments[n1 + 1];
1280 var myName = 'undefined' === typeof myName ? 1 : myName;
1281 return myName;
1282 };")
1284 (test-ps-js arglist-keyword-supplied
1285 (lambda (&key (foo 1 supplied?))
1286 foo)
1287 "(function () {
1288 var _js2 = arguments.length;
1289 for (var n1 = 0; n1 < _js2; n1 += 2) {
1290 switch (arguments[n1]) {
1291 case 'foo':
1292 foo = arguments[n1 + 1];
1293 suppliedwhat = true;
1296 var suppliedwhat;
1297 var foo = 'undefined' === typeof foo ? 1 : foo;
1298 return foo;
1299 });")
1301 (test-ps-js keyword-funcall1
1302 (func :baz 1)
1303 "func('baz', 1);")
1305 (test-ps-js keyword-funcall2
1306 (func :baz 1 :bar foo)
1307 "func('baz', 1, 'bar', foo);")
1309 (test-ps-js keyword-funcall3
1310 (fun a b :baz c)
1311 "fun(a, b, 'baz', c);")
1313 (test-ps-js cond1
1314 (cond ((= x 1) 1))
1315 "if (x === 1) {
1317 };")
1319 (test-ps-js cond2
1320 (cond ((= x 1) 2)
1321 ((= y (* x 4)) (foo "blah") (* x y)))
1322 "if (x === 1) {
1324 } else if (y === x * 4) {
1325 foo('blah');
1326 x * y;
1327 };")
1329 (test-ps-js if-exp-without-else-return
1330 (defun foo () (return-from foo (if x 1)))
1331 "function foo() {
1332 return x ? 1 : null;
1333 };")
1335 (test-ps-js progn-expression-single-statement
1336 (defun foo () (return-from foo (progn (* x y))))
1337 "function foo() {
1338 return x * y;
1339 };")
1341 (test-ps-js cond-expression1
1342 (defun foo ()
1343 (cond ((< 1 2) (bar "foo") (* 4 5))))
1344 "function foo() {
1345 if (1 < 2) {
1346 bar('foo');
1347 return 4 * 5;
1349 };")
1351 (test-ps-js cond-expression2
1352 (defun foo ()
1353 (cond ((< 2 1) "foo")
1354 ((= 7 7) "bar")))
1355 "function foo() {
1356 if (2 < 1) {
1357 return 'foo';
1358 } else if (7 === 7) {
1359 return 'bar';
1361 };")
1363 (test-ps-js cond-expression-final-t-clause
1364 (defun foo ()
1365 (cond ((< 1 2) (bar "foo") (* 4 5))
1366 ((= a b) (+ c d))
1367 ((< 1 2 3 4 5) x)
1368 (t "foo")))
1369 "function foo() {
1370 var _cmp1;
1371 var _cmp2;
1372 var _cmp3;
1373 if (1 < 2) {
1374 bar('foo');
1375 return 4 * 5;
1376 } else if (a === b) {
1377 return c + d;
1378 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1379 return x;
1380 } else {
1381 return 'foo';
1383 };")
1385 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1386 (defun foo ()
1387 (cond ((< 2 1) 5)
1388 (t "foo")
1389 ((< 1 2) "bar")))
1390 "function foo() {
1391 if (2 < 1) {
1392 return 5;
1393 } else {
1394 return 'foo';
1396 };")
1398 (test-ps-js funcall-if-expression
1399 (funcall (getprop document 'write)
1400 (if (= *linkornot* 1)
1401 (ps-html ((:a :href "#"
1402 :onclick (ps-inline (transport)))
1403 img))
1404 img))
1405 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>'].join('') : img);")
1407 (test-ps-js negate-number-literal
1408 (- 1)
1409 "-1;")
1411 (test macro-environment1
1412 (is (string= (normalize-js-code (let* ((macroname (gensym)))
1413 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1414 `(defun test1 ()
1415 (macrolet ((,macroname (x) `(aref data ,x)))
1416 (when (,macroname x)
1417 (setf (,macroname x) 123)))))))
1418 (normalize-js-code
1419 "function test1() {
1420 return data[x] ? (data[x] = 123) : null;
1421 };"))))
1423 (test macro-environment2
1424 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
1425 (defpsmacro macro-environment2-macro (x)
1426 `(+ ,outer-lexical-variable ,x))
1427 (ps* '(macro-environment2-macro 2))))
1428 (normalize-js-code "1 + 2;"))))
1430 (test-ps-js ampersand-whole-1
1431 (macrolet ((foo (&whole foo bar baz)
1432 (declare (ignore bar baz))
1433 (with-standard-io-syntax (format nil "~a" foo))))
1434 (foo 1 2))
1435 "'(FOO 1 2)';")
1437 (test-ps-js keyword-consistent
1439 "'x';")
1441 (test-ps-js simple-symbol-macrolet
1442 (symbol-macrolet ((x 1)) x)
1443 "1;")
1445 (test-ps-js compound-symbol-macrolet
1446 (symbol-macrolet ((x 123)
1447 (y (* 2 x)))
1449 "2 * 123;")
1451 (test-ps-js define-symbol-macro
1452 (progn (define-symbol-macro tst-sym-macro 2)
1453 tst-sym-macro)
1454 "2;")
1456 (test-ps-js define-symbol-macro1
1457 (progn (define-symbol-macro tst-sym-macro1 2)
1458 (foo tst-sym-macro1))
1459 "foo(2);")
1461 (test-ps-js expression-progn
1462 (1+ (progn (foo) (if x 1 2)))
1463 "(foo(), x ? 1 : 2) + 1;")
1465 (test-ps-js let-decl-in-expression
1466 (defun f (x)
1467 (if x 1 (let* ((foo x)) foo)))
1468 "function f(x) {
1469 if (x) {
1470 return 1;
1471 } else {
1472 var foo = x;
1473 return foo;
1475 };")
1477 (test-ps-js special-var1
1478 (progn (defvar *foo*)
1479 (let* ((*foo* 2))
1480 (* *foo* 2)))
1481 "var FOO;
1482 (function () {
1483 var FOO_TMPSTACK1;
1484 try {
1485 FOO_TMPSTACK1 = FOO;
1486 FOO = 2;
1487 return FOO * 2;
1488 } finally {
1489 FOO = FOO_TMPSTACK1;
1491 })();")
1493 (test-ps-js special-var2
1494 (progn (defvar *foo*)
1495 (let* ((*baz* 3)
1496 (*foo* 2))
1497 (* *foo* 2 *baz*)))
1498 "var FOO;
1499 (function () {
1500 var BAZ = 3;
1501 var FOO_TMPSTACK1;
1502 try {
1503 FOO_TMPSTACK1 = FOO;
1504 FOO = 2;
1505 return FOO * 2 * BAZ;
1506 } finally {
1507 FOO = FOO_TMPSTACK1;
1509 })();")
1511 (test-ps-js literal1
1512 (setf x undefined)
1513 "x = undefined;")
1515 (test-ps-js literal2
1516 (aref this x)
1517 "this[x];")
1519 (test-ps-js setf-dec1
1520 (setf x (- 1 x 2))
1521 "x = 1 - x - 2;")
1523 (test-ps-js setf-dec2
1524 (setf x (- x 1 2))
1525 "x = x - 1 - 2;")
1527 (test-ps-js special-char-equals
1528 blah=
1529 "blahequals;")
1531 (test-ps-js setf-operator-priority
1532 (defun foo ()
1533 (or (getprop cache id)
1534 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1535 "function foo() {
1536 return cache[id] || (cache[id] = document.getElementById(id));
1537 };")
1539 (test-ps-js aref-operator-priority
1540 (aref (if (and x (> (length x) 0))
1541 (aref x 0)
1544 "(x && x.length > 0 ? x[0] : y)[z];")
1546 (test-ps-js aref-operator-priority1
1547 (aref (or (getprop x 'y)
1548 (getprop a 'b))
1550 "(x.y || a.b)[z];")
1552 (test-ps-js aref-operator-priority2
1553 (aref (if a b c) 0)
1554 "(a ? b : c)[0];")
1556 (test-ps-js negate-operator-priority
1557 (- (if x y z))
1558 "-(x ? y : z);")
1560 (test-ps-js op-p1
1561 (new (or a b))
1562 "new (a || b);")
1564 (test-ps-js op-p2
1565 (delete (if a (or b c) d))
1566 "delete (a ? b || c : d);")
1568 (test-ps-js op-p3
1569 (not (if (or x (not y)) z))
1570 "!(x || !y ? z : null);")
1572 (test-ps-js op-p4
1573 (- (- (* 1 2) 3))
1574 "-(1 * 2 - 3);")
1576 (test-ps-js op-p5
1577 (instanceof (or a b) (if x y z))
1578 "((a || b) instanceof (x ? y : z));")
1580 (test-ps-js op-p7
1581 (or x (if (= x 0) "zero" "empty"))
1582 "x || (x === 0 ? 'zero' : 'empty');")
1584 (test-ps-js named-op-expression
1585 (throw (if a b c))
1586 "throw a ? b : c;")
1588 (test-ps-js named-op-expression1
1589 (typeof (or x y))
1590 "typeof (x || y);")
1592 (test-ps-js aref-array-expression
1593 (aref (or a b c) 0)
1594 "(a || b || c)[0];")
1596 (test-ps-js getprop-operator
1597 (getprop (or a b c) 'd)
1598 "(a || b || c).d;")
1600 (test-ps-js getprop-parens
1601 (getprop (getprop foo 'bar) 'baz)
1602 "foo.bar.baz;")
1604 (test-ps-js funcall-funcall
1605 ((foo))
1606 "foo()();")
1608 (test-ps-js expression-funcall
1609 ((or (@ window eval) eval) foo nil)
1610 "(window.eval || eval)(foo, null);")
1612 (test-ps-js expression-funcall1
1613 (((or (@ window eval) eval) foo nil))
1614 "(window.eval || eval)(foo, null)();")
1616 (test-ps-js expression-funcall2
1617 (((or (@ window eval) eval)) foo nil)
1618 "(window.eval || eval)()(foo, null);")
1620 (test-ps-js who-html1
1621 (who-ps-html (:span :class "ticker-symbol"
1622 :ticker-symbol symbol
1623 (:a :href "http://foo.com"
1624 symbol)
1625 (:span :class "ticker-symbol-popup")))
1626 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>'].join('');")
1628 (test-ps-js who-html2
1629 (who-ps-html (:p "t0" (:span "t1")))
1630 "'<P>t0<SPAN>t1</SPAN></P>';")
1632 (test-ps-js flet1
1633 ((lambda () (flet ((foo (x)
1634 (1+ x)))
1635 (foo 1))))
1636 "(function () {
1637 var foo = function (x) {
1638 return x + 1;
1640 return foo(1);
1641 })();")
1643 (test-ps-js flet2
1644 (flet ((foo (x) (1+ x))
1645 (bar (y) (+ 2 y)))
1646 (bar (foo 1)))
1647 "(function () {
1648 var foo = function (x) {
1649 return x + 1;
1651 var bar = function (y) {
1652 return 2 + y;
1654 return bar(foo(1));
1655 })();")
1657 (test-ps-js flet3
1658 (flet ((foo (x) (+ 2 x)))
1659 (flet ((foo (x) (1+ x))
1660 (bar (y) (+ 2 (foo y))))
1661 (bar (foo 1))))
1662 "(function () {
1663 var foo = function (x) {
1664 return 2 + x;
1666 var foo1 = function (x) {
1667 return x + 1;
1669 var bar = function (y) {
1670 return 2 + foo(y);
1672 return bar(foo1(1));
1673 })();")
1675 (test-ps-js labels1
1676 ((lambda () (labels ((foo (x)
1677 (if (= 0 x)
1679 (+ x (foo (1- x))))))
1680 (foo 3))))
1681 "(function () {
1682 var foo = function (x) {
1683 return 0 === x ? 0 : x + foo(x - 1);
1685 return foo(3);
1686 })();")
1688 (test-ps-js labels2
1689 (labels ((foo (x) (1+ (bar x)))
1690 (bar (y) (+ 2 (foo y))))
1691 (bar (foo 1)))
1692 "(function () {
1693 var foo = function (x) {
1694 return bar(x) + 1;
1696 var bar = function (y) {
1697 return 2 + foo(y);
1699 return bar(foo(1));
1700 })();")
1702 (test-ps-js labels3
1703 (labels ((foo (x) (1+ x))
1704 (bar (y) (+ 2 (foo y))))
1705 (bar (foo 1)))
1706 "(function () {
1707 var foo = function (x) {
1708 return x + 1;
1710 var bar = function (y) {
1711 return 2 + foo(y);
1713 return bar(foo(1));
1714 })();")
1716 (test-ps-js labels-lambda-list
1717 (labels ((foo (x &optional (y 0))
1718 (+ x y)))
1719 (foo 1))
1720 "(function () {
1721 var foo = function (x, y) {
1722 if (y === undefined) {
1723 y = 0;
1725 return x + y;
1727 return foo(1);
1728 })();")
1730 (test-ps-js for-loop-var-init-exp
1731 ((lambda (x)
1732 (do* ((y (if x 0 1) (1+ y))
1733 (z 0 (1+ z)))
1734 ((= y 3) z)))
1736 "(function (x) {
1737 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1739 return z;
1740 })(true);")
1742 (test-ps-js math-pi
1744 "Math.PI;")
1746 (test-ps-js literal-array
1747 '(1 2 3)
1748 "[1, 2, 3];")
1750 (test-ps-js literal-array-1
1751 '(1 foo 3)
1752 "[1, 'foo', 3];")
1754 (test-ps-js literal-array-literal
1756 "[];")
1758 (test-ps-js literal-array-literal1
1759 '(1 [])
1760 "[1, []];")
1762 (test ps-lisp-expands-in-lexical-environment
1763 (is (string= "5;" (let ((x 5))
1764 (ps (lisp x))))))
1766 (test ps-lisp-expands-in-lexical-environment1
1767 (is (string= "1 + 5;" (let ((x 5))
1768 (ps (+ 1 (lisp x)))))))
1770 (test ps-lisp-expands-in-lexical-environment2
1771 (is (string= "1 + 2 + 3;" (let ((x 2))
1772 (ps (+ 1 (lisp x) 3))))))
1774 (test ps*-lisp-expands-in-null-lexical-environment
1775 (signals unbound-variable (let ((x 5))
1776 (declare (ignore x))
1777 (ps* '(lisp x)))))
1779 (test ps*-lisp-expands-in-dynamic-environment
1780 (is (string= "1 + 2;"
1781 (let ((foo 2))
1782 (declare (special foo))
1783 (ps* '(+ 1 (lisp (locally (declare (special foo)) foo))))))))
1785 (test ps-lisp-dynamic-environment
1786 (is (string= "1 + 2;"
1787 (let ((foo 2))
1788 (declare (special foo))
1789 (ps (+ 1 (lisp foo)))))))
1791 (test-ps-js nested-if-expressions1
1792 (defun foo ()
1793 (return-from foo (if (if x y z) a b)))
1794 "function foo() {
1795 if (x ? y : z) {
1796 return a;
1797 } else {
1798 return b;
1800 };")
1802 (test-ps-js nested-if-expressions2
1803 (defun foo ()
1804 (if x y (if z a b)))
1805 "function foo() {
1806 if (x) {
1807 return y;
1808 } else {
1809 return z ? a : b;
1811 };")
1813 (test-ps-js let1
1814 (let (x)
1815 (+ x x))
1816 "(function () {
1817 var x = null;
1818 return x + x;
1819 })();")
1821 (test-ps-js let2
1822 (let ((x 1))
1823 (+ x x))
1824 "(function () {
1825 var x = 1;
1826 return x + x;
1827 })();")
1829 (test-ps-js let-x-x
1830 (let ((x (1+ x)))
1831 (+ x x))
1832 "(function () {
1833 var x1 = x + 1;
1834 return x1 + x1;
1835 })();")
1837 (test-ps-js let3
1838 (let ((x 1)
1839 (y 2))
1840 (+ x x))
1841 "(function () {
1842 var x = 1;
1843 var y = 2;
1844 return x + x;
1845 })();")
1847 (test-ps-js let4
1848 (let ((x 1)
1849 (y (1+ x)))
1850 (+ x y))
1851 "(function () {
1852 var x1 = 1;
1853 var y = x + 1;
1854 return x1 + y;
1855 })();")
1857 (test-ps-js let5
1858 (let ((x 1))
1859 (+ x 1)
1860 (let ((x (+ x 5)))
1861 (+ x 1))
1862 (+ x 1))
1863 "(function () {
1864 var x = 1;
1865 x + 1;
1866 var x1 = x + 5;
1867 x1 + 1;
1868 return x + 1;
1869 })();")
1871 (test-ps-js let6
1872 (let ((x 2))
1873 (let ((x 1)
1874 (y (1+ x)))
1875 (+ x y)))
1876 "(function () {
1877 var x = 2;
1878 var x1 = 1;
1879 var y = x + 1;
1880 return x1 + y;
1881 })();")
1883 (test-ps-js let-exp1
1884 (lambda ()
1885 (let (x)
1886 (+ x x)))
1887 "(function () {
1888 var x = null;
1889 return x + x;
1890 });")
1892 (test-ps-js let*1
1893 (let* ((x 1))
1894 (+ x x))
1895 "(function () {
1896 var x = 1;
1897 return x + x;
1898 })();")
1900 (test-ps-js let*2
1901 (let* ((x 1)
1902 (y (+ x 2)))
1903 (+ x y))
1904 "(function () {
1905 var x = 1;
1906 var y = x + 2;
1907 return x + y;
1908 })();")
1910 (test-ps-js let*3
1911 (let ((x 3))
1912 (let* ((x 1)
1913 (y (+ x 2)))
1914 (+ x y)))
1915 "(function () {
1916 var x = 3;
1917 var x1 = 1;
1918 var y = x1 + 2;
1919 return x1 + y;
1920 })();")
1922 (test-ps-js let*4
1923 (let ((x 3))
1924 (let* ((y (+ x 2))
1925 (x 1))
1926 (+ x y)))
1927 "(function () {
1928 var x = 3;
1929 var y = x + 2;
1930 var x1 = 1;
1931 return x1 + y;
1932 })();")
1934 (test-ps-js symbol-macrolet-var
1935 (symbol-macrolet ((x y))
1936 (var x))
1937 "var y;")
1939 (test-ps-js setf-conditional1
1940 (setf x (unless (null a) (1+ a)))
1941 "x = a != null ? a + 1 : null;")
1943 (test-ps-js setf-let1
1944 (setf x (let ((a 1)) a))
1945 "x = (function () {
1946 var a = 1;
1947 return a;
1948 })();")
1950 (test-ps-js setf-let2
1951 (setf x (let ((a (foo)))
1952 (unless (null a)
1953 (1+ a))))
1954 "x = (function () {
1955 var a = foo();
1956 return a != null ? a + 1 : null;
1957 })();")
1959 (test-ps-js symbol-macro-env1
1960 (symbol-macrolet ((bar 1))
1961 (macrolet ((bar (x y) `(+ ,x ,y)))
1962 (bar bar bar)))
1963 "1 + 1;")
1965 (test-ps-js symbol-macrolet-fun1
1966 (symbol-macrolet ((baz +))
1967 (baz 1 2))
1968 "baz(1, 2);")
1970 (test-ps-js lisp2-namespaces1
1971 (let ((list nil))
1972 (setf list (list 1 2 3)))
1973 "(function () {
1974 var list = null;
1975 return list = [1, 2, 3];
1976 })();")
1978 (test-ps-js let-shadows-symbol-macrolet
1979 (symbol-macrolet ((x y))
1980 (let ((x 1))
1981 (+ x x))
1982 (+ x x))
1983 "(function () {
1984 var x1 = 1;
1985 return x1 + x1;
1986 })();
1987 y + y;")
1989 (test-ps-js let-rename-optimization1
1990 (let ((x 1))
1991 (+ x x))
1992 "(function () {
1993 var x = 1;
1994 return x + x;
1995 })();")
1997 (test-ps-js let-rename-optimization2
1998 (lambda (x)
1999 (let ((x (+ 1 x)))
2001 "(function (x) {
2002 var x1 = 1 + x;
2003 return x1;
2004 });")
2006 (test-ps-js symbol-macro-array
2007 (symbol-macrolet ((x 1))
2008 (list x))
2009 "[1];")
2011 (test-ps-js symbol-macro-obj
2012 (symbol-macrolet ((x y))
2013 (create x 1))
2014 "({ x : 1 });")
2016 (test-ps-js symbol-macro-conditional1
2017 (symbol-macrolet ((x y))
2018 (if x x x))
2019 "if (y) {
2021 } else {
2023 };")
2025 (test-ps-js symbol-macro-conditional2
2026 (symbol-macrolet ((x y))
2027 (1+ (if x x x)))
2028 "(y ? y : y) + 1;")
2030 (test-ps-js preserve-this
2031 (defun foo ()
2032 (let ((y (block nil (bar this))))
2033 (baz y)))
2034 "function foo() {
2035 var y = (function () {
2036 return bar(this);
2037 }).call(this);
2038 return baz(y);
2039 };")
2041 (test-ps-js flet-apply
2042 (flet ((foo () 'bar))
2043 (apply (function foo) nil))
2044 "(function () {
2045 var foo = function () {
2046 return 'bar';
2048 return foo.apply(this, null);
2049 }).call(this);")
2051 (test-ps-js let-apply
2052 (let ((foo (lambda () 1)))
2053 (let ((foo (lambda () 2)))
2054 (apply foo nil)))
2055 "(function () {
2056 var foo = function () {
2057 return 1;
2059 var foo1 = function () {
2060 return 2;
2062 return foo1.apply(this, null);
2063 }).call(this);")
2065 (test-ps-js flet-let
2066 (flet ((x (x) (1+ x)))
2067 (let ((x 2))
2068 (x x)))
2069 "(function () {
2070 var x = function (x) {
2071 return x + 1;
2073 var x1 = 2;
2074 return x(x1);
2075 })();")
2077 (test-ps-js let-flet
2078 (let ((x 2))
2079 (flet ((x (x) (1+ x)))
2080 (x x)))
2081 "(function () {
2082 var x = 2;
2083 var x1 = function (x) {
2084 return x + 1;
2086 return x1(x);
2087 })();")
2089 (test-ps-js labels-let
2090 (labels ((x (x) (1+ x)))
2091 (let ((x 2))
2092 (x x)))
2093 "(function () {
2094 var x = function (x) {
2095 return x + 1;
2097 var x1 = 2;
2098 return x(x1);
2099 })();")
2101 (test-ps-js let-labels
2102 (let ((x 2))
2103 (labels ((x (x) (1+ x)))
2104 (x x)))
2105 "(function () {
2106 var x = 2;
2107 var x1 = function (x) {
2108 return x + 1;
2110 return x1(x);
2111 })();")
2113 (test-ps-js macrolet-let-inteference
2114 (macrolet ((a (n) `(+ ,n 5)))
2115 (let ((a (a 1)))
2116 (let ((b (a (- a 4))))
2117 (+ a b))))
2118 "(function () {
2119 var a = 1 + 5;
2120 var b = (a - 4) + 5;
2121 return a + b;
2122 })();")
2124 (test-ps-js let-subtract-add
2125 (let ((x 1))
2126 (let ((x 2))
2127 (- x x)
2128 (- x)
2129 (decf x)
2130 (incf x)))
2131 "(function () {
2132 var x = 1;
2133 var x1 = 2;
2134 x1 - x1;
2135 -x1;
2136 --x1;
2137 return ++x1;
2138 })();")
2140 (test-ps-js create-reserved-word
2141 (create :default 1)
2142 "({ 'default' : 1 });")
2144 (test-ps-js getprop-reserved-word
2145 (getprop foo :default)
2146 "foo['default'];")
2148 (test-ps-js getprop-reserved-word1
2149 (getprop foo 'default)
2150 "foo['default'];")
2152 (test-ps-js eval-when-ps-side
2153 (eval-when (:execute)
2155 "5;")
2157 (defvar *lisp-output* nil)
2159 (test eval-when-lisp-side ()
2160 (setf *lisp-output* 'original-value)
2161 (let ((js-output (normalize-js-code
2162 (ps-doc* `(eval-when (:compile-toplevel)
2163 (setf *lisp-output* 'it-works))))))
2164 (is (eql 'it-works *lisp-output*))
2165 (is (string= "" js-output))))
2167 (defpsmacro my-in-package (package-name)
2168 `(eval-when (:compile-toplevel)
2169 (setf *lisp-output* ,package-name)))
2171 (test eval-when-macro-expansion ()
2172 (setf *lisp-output* 'original-value)
2173 (let ((js-output (normalize-js-code
2174 (ps-doc* `(progn
2175 (my-in-package :cl-user)
2176 3)))))
2177 (declare (ignore js-output))
2178 (is (eql :cl-user *lisp-output*))))
2180 (test eval-when-macrolet-expansion ()
2181 (setf *lisp-output* 'original-value)
2182 (let ((js-output (normalize-js-code
2183 (ps-doc* `(macrolet ((my-in-package2 (package-name)
2184 `(eval-when (:compile-toplevel)
2185 (setf *lisp-output* ,package-name))))
2186 (my-in-package2 :cl-user)
2187 3)))))
2188 (declare (ignore js-output))
2189 (is (eql :cl-user *lisp-output*))))
2191 (test-ps-js getprop-keyword
2192 (getprop foo :bar)
2193 "foo['bar'];")
2195 (test-ps-js nary-comparison1
2196 (lambda () (< 1 2 3))
2197 "(function () {
2198 var _cmp1;
2199 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2200 });")
2202 (test-ps-js chain-getprop1
2203 (chain ($ "foo") (bar x z) frob (baz 5))
2204 "$('foo').bar(x, z).frob.baz(5);")
2206 (test-ps-js chain-getprop2
2207 (chain ($ "foo") bar baz)
2208 "$('foo').bar.baz;")
2210 (test-ps-js chain-getprop3
2211 (chain ($ "foo") bar (x y) baz)
2212 "$('foo').bar.x(y).baz;")
2214 (test-ps-js flet-expression
2215 (1+ (flet ((foo (x) (1+ x)))
2216 (foo 1)))
2217 "(function () {
2218 var foo = function (x) {
2219 return x + 1;
2221 return foo(1);
2222 })() + 1;")
2224 (test-ps-js flet-lambda-list
2225 (flet ((foo (x &key (y 0))
2226 (+ x y)))
2227 (foo 1 :y 2))
2228 "(function () {
2229 var foo = function (x) {
2230 var _js2 = arguments.length;
2231 for (var n1 = 1; n1 < _js2; n1 += 2) {
2232 switch (arguments[n1]) {
2233 case 'y':
2234 y = arguments[n1 + 1];
2237 var y = 'undefined' === typeof y ? 0 : y;
2238 return x + y;
2240 return foo(1, 'y', 2);
2241 })();")
2243 (test-ps-js return-case-break-elimination
2244 (defun foo ()
2245 (return-from foo
2246 (case 1
2247 (0 1)
2248 (otherwise 2))))
2249 "function foo() {
2250 switch (1) {
2251 case 0:
2252 return 1;
2253 default:
2254 return 2;
2256 };")
2258 (test-ps-js aplusplus
2260 "aplusplus;")
2262 (test-ps-js astarstar
2264 "astarstar;")
2266 (test-ps-js switch-return-fallthrough
2267 (defun foo ()
2268 (return-from foo
2269 (switch x
2270 (1 (foo) break)
2271 (2 (bar))
2272 (default 4))))
2273 "function foo() {
2274 switch (x) {
2275 case 1:
2276 return foo();
2277 case 2:
2278 bar();
2279 default:
2280 return 4;
2282 };")
2284 (test-ps-js return-last-case
2285 (defun foo ()
2286 (return-from foo
2287 (case x
2288 (:a 'eh)
2289 (:b 'bee))))
2290 "function foo() {
2291 switch (x) {
2292 case 'a':
2293 return 'eh';
2294 case 'b':
2295 return 'bee';
2297 };")
2299 (test-ps-js return-macrolet
2300 (defun foo ()
2301 (return-from foo
2302 (macrolet ((x () 1))
2303 (case (x)
2304 (:a 'eh)
2305 (:b 'bee)))))
2306 "function foo() {
2307 switch (1) {
2308 case 'a':
2309 return 'eh';
2310 case 'b':
2311 return 'bee';
2313 };")
2315 (test-ps-js mv-bind1
2316 (multiple-value-bind (a b)
2317 (progn
2318 (returns-mv)
2319 (doesnt))
2320 (alert a)
2321 (alert b))
2322 "returnsMv();
2323 (function () {
2324 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2325 try {
2326 var a = doesnt();
2327 var _db2 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2328 var b = _db2[0];
2329 alert(a);
2330 return alert(b);
2331 } finally {
2332 __PS_MV_REG = prevMv1;
2334 })();")
2336 (test-ps-js mv-bind2
2337 (multiple-value-bind (a b)
2338 (let ((a 1))
2339 (returns-mv a)
2340 (doesnt b))
2341 (alert a)
2342 (alert b))
2343 "(function () {
2344 var a = 1;
2345 returnsMv(a);
2346 var prevMv2 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2347 try {
2348 var a3 = doesnt(b);
2349 var _db4 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2350 var b = _db4[0];
2351 alert(a3);
2352 return alert(b);
2353 } finally {
2354 __PS_MV_REG = prevMv2;
2356 })();")
2358 (test-ps-js multiple-value-bind-simple
2359 (multiple-value-bind (a b) (blah)
2360 (+ a b))
2361 "(function () {
2362 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2363 try {
2364 var a = blah();
2365 var _db2 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2366 var b = _db2[0];
2367 return a + b;
2368 } finally {
2369 __PS_MV_REG = prevMv1;
2371 })();")
2373 (test-ps-js values0
2374 (lambda () (values))
2375 "(function () {
2376 __PS_MV_REG = {};
2377 return null;
2378 });")
2380 (test-ps-js values1
2381 (values x)
2382 "x;")
2384 (test-ps-js values2
2385 (lambda () (values x y))
2386 "(function () {
2387 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2388 return x;
2389 });")
2391 (test-ps-js values3
2392 (lambda () (values x y z))
2393 "(function () {
2394 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2395 return x;
2396 });")
2398 (test-ps-js values-return
2399 (defun foo (x y)
2400 (return-from foo (values (* x x) y)))
2401 "function foo(x, y) {
2402 var val1_1 = x * x;
2403 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2404 return val1_1;
2405 };")
2407 (test-ps-js return-macrolet1
2408 (defun foo ()
2409 (return-from foo
2410 (symbol-macrolet ((x 2))
2411 (loop do (+ x x)))))
2412 "function foo() {
2413 while (true) {
2414 2 + 2;
2416 };")
2418 (test-ps-js return-cond
2419 (defun foo ()
2420 (return-from foo
2421 (cond ((foo? x) (loop for y in x do (foo y)))
2422 ((bar? x) x)
2423 (t 3))))
2424 "function foo() {
2425 if (foowhat(x)) {
2426 var _js2 = x.length;
2427 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2428 var y = x[_js1];
2429 foo(y);
2431 } else if (barwhat(x)) {
2432 return x;
2433 } else {
2434 return 3;
2436 };")
2438 (test-ps-js return-case
2439 (defun foo ()
2440 (return-from foo
2441 (case x
2442 (1 (loop for y in x do (foo y)))
2443 (2 x)
2444 ((t) 3))))
2445 "function foo() {
2446 switch (x) {
2447 case 1:
2448 var _js2 = x.length;
2449 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2450 var y = x[_js1];
2451 foo(y);
2453 return;
2454 case 2:
2455 return x;
2456 case true:
2457 return 3;
2459 };")
2461 (test-ps-js return-case1
2462 (defun foo ()
2463 (return-from foo
2464 (case x
2465 (1 (if a 1 2))
2466 (2 x)
2467 ((t) 3))))
2468 "function foo() {
2469 switch (x) {
2470 case 1:
2471 return a ? 1 : 2;
2472 case 2:
2473 return x;
2474 case true:
2475 return 3;
2477 };")
2479 (test-ps-js lambda-loop-if-return
2480 (lambda ()
2481 (if a
2482 (loop for y in x do (foo y))
2484 "(function () {
2485 if (a) {
2486 var _js4 = x.length;
2487 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2488 var y = x[_js3];
2489 foo(y);
2491 } else {
2492 return c;
2494 });")
2496 (test-ps-js lambda-loop-if-return1
2497 (defun baz ()
2498 (foo (lambda ()
2499 (if a
2500 (progn (loop for y in x do (foo y))
2501 (return-from baz))
2502 c))))
2503 "function baz() {
2504 try {
2505 return foo(function () {
2506 if (a) {
2507 var _js4 = x.length;
2508 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2509 var y = x[_js3];
2510 foo(y);
2512 throw { '__ps_block_tag' : 'baz',
2513 '__ps_value1' : null };
2514 } else {
2515 return c;
2518 } catch (_ps_err5) {
2519 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2520 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2521 return _ps_err5['__ps_value1'];
2522 } else {
2523 throw _ps_err5;
2526 };")
2528 (test-ps-js switch-loop
2529 (defun foo (x)
2530 (case x
2531 (1 (dolist (a b)))))
2532 "function foo(x) {
2533 switch (x) {
2534 case 1:
2535 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2536 a = b[_js_idx1];
2538 return;
2540 };")
2542 (test-ps-js switch-folds-blocks
2543 (defun foo ()
2544 (case x
2545 (1 (loop repeat 3 do (alert "foo")))
2546 (2 "bar")))
2547 "function foo() {
2548 switch (x) {
2549 case 1:
2550 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2551 alert('foo');
2553 return;
2554 case 2:
2555 return 'bar';
2557 };")
2559 (test-ps-js setf-places-before-macros
2560 (lambda ()
2561 (defsetf left (el) (offset)
2562 `(setf (@ ,el style left) ,offset))
2563 (macrolet ((left (el)
2564 `(@ ,el offset-left)))
2565 (setf (left x) 10)
2566 (left x)))
2567 "(function () {
2568 var _js2 = x;
2569 var _js1 = 10;
2570 _js2.style.left = _js1;
2571 return x.offsetLeft;
2572 });")
2574 (test-ps-js for-return
2575 (lambda () (dolist (arg args) (foo arg)))
2576 "(function () {
2577 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2578 arg = args[_js_idx1];
2579 foo(arg);
2581 });")
2583 (test-ps-js try-catch-return
2584 (defun foo ()
2585 (return-from foo
2586 (try (foo)
2587 (:catch (e)
2588 (bar))
2589 (:finally
2590 (cleanup)))))
2591 "function foo() {
2592 try {
2593 return foo();
2594 } catch (e) {
2595 return bar();
2596 } finally {
2597 cleanup();
2599 };")
2601 (test-ps-js defun-setf-optional
2602 (defun (setf foo) (new-value b &optional c)
2603 (setf (aref b (or c 0)) new-value))
2604 "function __setf_foo(newValue, b, c) {
2605 return b[c || 0] = newValue;
2606 };")
2608 (test-ps-js defun-setf-rest
2609 (progn (defun (setf foo) (new-value b &rest foo)
2610 (do-something b foo new-value))
2611 (setf (foo x 1 2 3 4) 5))
2612 "function __setf_foo(newValue, b) {
2613 var foo = Array.prototype.slice.call(arguments, 2);
2614 return doSomething(b, foo, newValue);
2616 __setf_foo(5, x, 1, 2, 3, 4);")
2618 (test-ps-js return-null
2619 (defun foo () (return-from foo nil))
2620 "function foo() {
2621 return null;
2622 };")
2624 (test-ps-js implicit-return-null
2625 (lambda ()
2627 "(function () {
2628 return null;
2629 });")
2631 (test-ps-js implicit-return-null
2632 (lambda ()
2633 nil)
2634 "(function () {
2635 return null;
2636 });")
2638 (test-ps-js return-conditional-nested
2639 (defun blep (ss x y)
2640 (when foo?
2641 (let ((pair (bar)))
2642 (unless (null pair)
2643 (destructuring-bind (a b) pair
2644 (unless (or (null a) (null b))
2645 (let ((val (baz a b)))
2646 (unless (null val)
2647 (when (blah val)
2648 (unless (blee)
2649 t))))))))))
2650 "function blep(ss, x, y) {
2651 if (foowhat) {
2652 var pair = bar();
2653 if (pair != null) {
2654 var a = pair[0];
2655 var b = pair[1];
2656 if (!(a == null || b == null)) {
2657 var val = baz(a, b);
2658 if (val != null) {
2659 if (blah(val)) {
2660 return !blee() ? true : null;
2666 };")
2668 ;; this test needs to be rewritten when named blocks are implemented!!!!
2669 (test-ps-js return-when-returns-broken-return
2670 (defun foo ()
2671 (return-from foo (when x 1))
2672 (+ 2 3))
2673 "function foo() {
2674 return x ? 1 : null;
2675 return 2 + 3;
2676 };")
2678 (test-ps-js return-case-conditional
2679 (defun foo ()
2680 (return-from foo
2681 (case foo
2682 (123 (when (bar) t))
2683 (345 (blah)))))
2684 "function foo() {
2685 switch (foo) {
2686 case 123:
2687 return bar() ? true : null;
2688 case 345:
2689 return blah();
2691 };")
2693 (test-ps-js return-try-conditional
2694 (defun foo ()
2695 (return-from foo
2696 (try (when x 1)
2697 (:catch (x) 2)
2698 (:finally (bar)))))
2699 "function foo() {
2700 try {
2701 return x ? 1 : null;
2702 } catch (x) {
2703 return 2;
2704 } finally {
2705 bar();
2707 };")
2709 (test-ps-js function-declare-special
2710 (lambda ()
2711 (declare (special *foo*))
2712 (let ((*foo* 1))
2713 (1+ *foo*)))
2714 "(function () {
2715 var FOO_TMPSTACK1;
2716 try {
2717 FOO_TMPSTACK1 = FOO;
2718 FOO = 1;
2719 return FOO + 1;
2720 } finally {
2721 FOO = FOO_TMPSTACK1;
2723 });")
2725 (test-ps-js declare-special-let
2726 (let ((*foo* 123))
2727 (declare (special *foo*))
2728 (blah))
2729 "(function () {
2730 var FOO_TMPSTACK1;
2731 try {
2732 FOO_TMPSTACK1 = FOO;
2733 FOO = 123;
2734 return blah();
2735 } finally {
2736 FOO = FOO_TMPSTACK1;
2738 })();")
2740 (test-ps-js declare-special-let*
2741 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
2742 (declare (special *foo* *bar*))
2743 (blah))
2744 "(function () {
2745 var FOO_TMPSTACK1;
2746 try {
2747 FOO_TMPSTACK1 = FOO;
2748 FOO = 123;
2749 var BAR_TMPSTACK2;
2750 try {
2751 BAR_TMPSTACK2 = BAR;
2752 BAR = FOO + BAR;
2753 return blah();
2754 } finally {
2755 BAR = BAR_TMPSTACK2;
2757 } finally {
2758 FOO = FOO_TMPSTACK1;
2760 })();")
2762 (test-ps-js defun-multiple-declarations-around-docstring
2763 (defun foo (x y)
2764 (declare (ignorable x y))
2765 (declare (integer x) (float y))
2766 "Fooes X while barring Y."
2767 (declare (special *foo*) (special *bar*))
2768 (let ((*bar* (bar y)))
2769 (funcall *foo* x)))
2770 "/** Fooes X while barring Y. */
2771 function foo(x, y) {
2772 var BAR_TMPSTACK1;
2773 try {
2774 BAR_TMPSTACK1 = BAR;
2775 BAR = bar(y);
2776 return FOO(x);
2777 } finally {
2778 BAR = BAR_TMPSTACK1;
2780 };")
2782 (test-ps-js macro-null-toplevel
2783 (progn
2784 (defmacro macro-null-toplevel ()
2785 nil)
2786 (macro-null-toplevel))
2789 (test-ps-js define-symbol-macro-let
2790 (progn
2791 (define-symbol-macro test-symbol-macro 1)
2792 (let ((test-symbol-macro 2))
2793 (1+ test-symbol-macro))
2794 (1+ test-symbol-macro))
2795 "(function () {
2796 var testSymbolMacro1 = 2;
2797 return testSymbolMacro1 + 1;
2798 })();
2799 1 + 1;")
2801 (test-ps-js define-symbol-macro-flet
2802 (progn
2803 (define-symbol-macro test-symbol-macro1 1)
2804 (flet ((test-symbol-macro1 () 2))
2805 (foo test-symbol-macro1)
2806 (test-symbol-macro1))
2807 (bar test-symbol-macro1))
2808 "(function () {
2809 var testSymbolMacro1_1 = function () {
2810 return 2;
2812 foo(1);
2813 return testSymbolMacro1_1();
2814 })();
2815 bar(1);")
2817 (test compile-stream-nulls
2818 (is (string=
2820 (with-input-from-string (s "
2821 (defmacro macro-null-toplevel ()
2822 nil)
2823 (macro-null-toplevel)")
2824 (ps-compile-stream s)))))
2826 (test compile-stream1
2827 (is (string=
2828 "(function () {
2829 var testSymbolMacro1_1 = function () {
2830 return 2;
2832 foo(1);
2833 return testSymbolMacro1_1();
2834 })();
2835 bar(1);
2837 (with-input-from-string (s "
2838 (define-symbol-macro test-symbol-macro1 1)
2839 (flet ((test-symbol-macro1 () 2))
2840 (foo test-symbol-macro1)
2841 (test-symbol-macro1))
2842 (bar test-symbol-macro1)")
2843 (ps::with-blank-compilation-environment (ps-compile-stream s))))))
2845 (test-ps-js equality-nary1
2846 (let ((x 10) (y 10) (z 10))
2847 (= x y z))
2848 "(function () {
2849 var _cmp1;
2850 var x = 10;
2851 var y = 10;
2852 var z = 10;
2853 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
2854 })();")
2856 (test-ps-js equality1
2857 (progn
2858 (equal a b)
2859 (eql a b)
2860 (eq a b)
2861 (= a b))
2862 "a == b;
2863 a === b;
2864 a === b;
2865 a === b;")
2867 (test-ps-js getprop-quote-reserved
2868 (getprop foo ':break)
2869 "foo['break'];")
2871 (test-ps-js defun-block-return-from
2872 (defun foo (x)
2873 (baz 4)
2874 (return-from foo x)
2875 (bar 5))
2876 "function foo(x) {
2877 baz(4);
2878 return x;
2879 return bar(5);
2880 }; ")
2882 (test-ps-js block-return-from
2883 (block scope
2884 (foo)
2885 (when (bar)
2886 (return-from scope))
2887 (blee))
2888 "(function () {
2889 foo();
2890 if (bar()) {
2891 return null;
2893 return blee();
2894 })();")
2896 (test-ps-js block-return-from0
2897 (defun baz ()
2898 (block scope
2899 (foo)
2900 (when (bar)
2901 (return-from scope))
2902 (blee)))
2903 "function baz() {
2904 foo();
2905 if (bar()) {
2906 return null;
2908 return blee();
2909 };")
2911 (test-ps-js block-return-from01
2912 (defun baz ()
2913 (block scope
2914 (foo)
2915 (when (bar)
2916 (return-from scope))
2917 (blee))
2919 "function baz() {
2920 scope: {
2921 foo();
2922 if (bar()) {
2923 break scope;
2925 blee();
2927 return 2;
2928 };")
2930 (test-ps-js block-return-from02
2931 (defun baz ()
2932 (block scope
2933 (foo)
2934 (when (bar)
2935 (return-from scope (foobar)))
2936 (blee))
2938 "function baz() {
2939 scope: {
2940 foo();
2941 if (bar()) {
2942 foobar();
2943 break scope;
2945 blee();
2947 return 2;
2948 };")
2950 (test-ps-js block-return-from1
2951 (lambda ()
2952 (block scope
2953 (foo)
2954 (when (bar)
2955 (return-from scope))
2956 (blee))
2957 (+ 1 2))
2958 "(function () {
2959 scope: {
2960 foo();
2961 if (bar()) {
2962 break scope;
2964 blee();
2966 return 1 + 2;
2967 });")
2969 (test-ps-js block-return-from2
2970 (lambda ()
2971 (bar 5)
2972 (block scope
2973 (foo)
2974 (when (bar)
2975 (return-from scope 6))
2976 (blee)))
2977 "(function () {
2978 bar(5);
2979 foo();
2980 if (bar()) {
2981 return 6;
2983 return blee();
2984 });")
2986 (test-ps-js let-funcall
2987 (let ((x foo))
2988 (funcall x)
2989 (let ((x bar))
2990 (funcall x))
2991 (funcall x))
2992 "(function () {
2993 var x = foo;
2994 x();
2995 var x1 = bar;
2996 x1();
2997 return x();
2998 })();")
3000 (test-ps-js symbol-macrolet-funcall
3001 (symbol-macrolet ((foo bar))
3002 (funcall foo 1 2 3))
3003 "bar(1, 2, 3);")
3005 (test-ps-js times-assign
3006 (setf x (* x 1000))
3007 "x *= 1000;")
3009 (test-ps-js vector-literal
3010 #(1 2 3)
3011 "[1, 2, 3];")
3013 (test-ps-js rem1
3014 (+ 1 (rem 2 (+ 3 4)))
3015 "1 + 2 % (3 + 4);")
3017 (test-ps-js non-associative
3018 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3019 "1 / (2 / 3) + (1 - (2 - 3));")
3021 (test-ps-js lambda-apply
3022 (lambda (x)
3023 (apply (lambda (y) (bar (1+ y))) x))
3024 "(function (x) {
3025 return (function (y) {
3026 return bar(y + 1);
3027 }).apply(this, x);
3028 });")
3030 (test-ps-js operator-expressions-nested-let
3031 (let ((x (let ((y 1))
3032 y)))
3034 "(function () {
3035 var y;
3036 var x = (y = 1, y);
3037 return x;
3038 })();")
3040 (test-ps-js operator-expressions-array-nested-let
3041 (list (let ((y 1)) y) 2)
3042 "[(function () {
3043 var y = 1;
3044 return y;
3045 })(), 2];")
3047 (test-ps-js add-subtract-precedence
3048 (- x (+ y z))
3049 "x - (y + z);")
3051 (test-ps-js ps-inline-toplevel
3052 (ps-inline (foo))
3053 "'javascript:' + 'foo()';")
3055 (test-ps-js no-clause-progn-exp
3056 (setf x (progn))
3057 "x = null;")
3059 (test-ps-js no-clause-progn-return
3060 (defun foo ()
3061 (return-from foo (progn)))
3062 "function foo() {
3063 return null;
3064 };")
3066 (test-ps-js empty-cond-clause
3067 (setf x (cond ((foo))))
3068 "x = (function () { var testResult1 = foo(); return testResult1 ? testResult1 : null; })();")
3070 (test-ps-js empty-cond-clause1
3071 (setf x (cond ((foo) 123)
3072 ((bar))
3073 (t 456)))
3074 "x = foo() ? 123 :
3075 (function () {
3076 var testResult1 = bar();
3077 if (testResult1) {
3078 return testResult1;
3079 } else {
3080 if (true) { return 456; };
3082 })();")
3084 (test-ps-js let-no-body
3085 (defun foo ()
3086 (return-from foo (let ((foo bar)))))
3087 "function foo() {
3088 var foo1 = bar;
3089 return null;
3090 };")
3092 (test-ps-js rename-lexical-dupes
3093 (lambda ()
3094 (list (let ((foo 12)) (* foo 2))
3095 (let ((foo 13)) (* foo 3))))
3096 "(function () {
3097 var foo;
3098 var foo1;
3099 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3100 });")
3102 (test-ps-js defun-comment1
3103 (defun foo (x)
3104 "BARBAR is a revolutionary new foobar.
3105 X y and x."
3106 (1+ x))
3107 "/**
3108 * BARBAR is a revolutionary new foobar.
3109 * X y and x.
3111 function foo(x) {
3112 return x + 1;
3113 };")
3115 (test-ps-js var-comment
3116 (var x 1 "foo")
3117 "/** foo */
3118 var x = 1;")
3120 (test-ps-js case-return-break-broken-return
3121 (defun foo ()
3122 (case x
3123 ("bar" (if y (return-from foo t) nil))
3124 ("baz" nil)))
3125 "function foo() {
3126 switch (x) {
3127 case 'bar':
3128 if (y) {
3129 return true;
3130 } else {
3131 return null;
3133 case 'baz':
3134 return null;
3136 };")
3138 (test-ps-js case-return-break1-broken-return
3139 (defun foo ()
3140 (case x
3141 ("bar" (if y (return-from foo t)))
3142 ("baz" nil)))
3143 "function foo() {
3144 switch (x) {
3145 case 'bar':
3146 if (y) {
3147 return true;
3148 } else {
3149 return null;
3151 case 'baz':
3152 return null;
3154 };")
3156 (test-ps-js setf-progn
3157 (setf foo (progn (bar) (baz) 3))
3158 "bar();
3159 baz();
3160 foo = 3;")
3162 (test-ps-js var-progn
3163 (var x (progn (foo) (bar)))
3164 "foo();
3165 var x = bar();")
3167 (test-ps-js implicit-return-loop
3168 (lambda ()
3169 (if baz 7
3170 (progn
3171 (loop :repeat 100 :do (bar))
3172 42)))
3173 "(function () {
3174 if (baz) {
3175 return 7;
3176 } else {
3177 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3178 bar();
3180 return 42;
3182 });")
3184 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
3185 (test-ps-js loop-closures
3186 (dotimes (i 10) (lambda () (+ i 1)))
3187 "(function () {
3188 for (var i = 0; i < 10; i += 1) {
3189 with ({ i : i }) {
3190 function () {
3191 return i + 1;
3195 })();")
3197 (test-ps-js loop-closures-let
3198 (dotimes (i 10)
3199 (let ((x (+ i 1)))
3200 (lambda () (+ i x))))
3201 "(function () {
3202 for (var i = 0; i < 10; i += 1) {
3203 with ({ i : i, x : null }) {
3204 var x = i + 1;
3205 function () {
3206 return i + x;
3210 })();")
3212 (test-ps-js loop-closures-flet
3213 (dotimes (i 10) (flet ((foo (x) (+ i x))) (lambda () (foo i))))
3214 "(function () {
3215 for (var i = 0; i < 10; i += 1) {
3216 with ({ foo : null, i : i }) {
3217 var foo = function (x) {
3218 return i + x;
3220 function () {
3221 return foo(i);
3225 })();")
3227 (test-ps-js while-closures-let
3228 (while (foo)
3229 (let ((x (bar)))
3230 (lambda () (+ 1 x))))
3231 "while (foo()) {
3232 with ({ x : null }) {
3233 var x = bar();
3234 function () {
3235 return 1 + x;
3238 };")
3240 (test-ps-js dotted-list-form
3241 (defun foo (a)
3242 (when a
3243 (destructuring-bind (b . c)
3245 (list b c))))
3246 "function foo(a) {
3247 if (a) {
3248 var b = bar[0];
3249 var c = bar.length > 1 ? bar.slice(1) : [];
3250 return [b, c];
3252 };")
3254 (test-ps-js explicit-nil-block
3255 (defun bar ()
3256 (foo 1)
3257 (block nil (return (foo 2)) (+ 1 2))
3259 "function bar() {
3260 foo(1);
3261 nilBlock: {
3262 foo(2);
3263 break nilBlock;
3264 1 + 2;
3266 return 2;
3267 };")
3269 (test-ps-js dynamic-extent-function-return
3270 (defun foo ()
3271 ((lambda ()
3272 (return-from foo 6))))
3273 "function foo() {
3274 try {
3275 return (function () {
3276 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3277 })();
3278 } catch (_ps_err1) {
3279 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3280 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3281 return _ps_err1['__ps_value1'];
3282 } else {
3283 throw _ps_err1;
3286 };")
3288 (test-ps-js dynamic-extent-function-return-nothing
3289 (defun foo ()
3290 ((lambda ()
3291 (return-from foo))))
3292 "function foo() {
3293 try {
3294 return (function () {
3295 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3296 })();
3297 } catch (_ps_err1) {
3298 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3299 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3300 return _ps_err1['__ps_value1'];
3301 } else {
3302 throw _ps_err1;
3305 };")
3307 (test-ps-js dynamic-extent-function-return-values
3308 (defun foo ()
3309 ((lambda ()
3310 (return-from foo (values 1 2 3)))))
3311 "function foo() {
3312 try {
3313 __PS_MV_REG = {};
3314 return (function () {
3315 throw { '__ps_block_tag' : 'foo',
3316 '__ps_value1' : 1,
3317 '__ps_values' : [2, 3] };
3318 })();
3319 } catch (_ps_err1) {
3320 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3321 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3322 return _ps_err1['__ps_value1'];
3323 } else {
3324 throw _ps_err1;
3327 };")
3329 (test-ps-js dynamic-extent-function-return-funcall
3330 (defun foo ()
3331 ((lambda ()
3332 (return-from foo (if baz 6 5)))))
3333 "function foo() {
3334 try {
3335 return (function () {
3336 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3337 })();
3338 } catch (_ps_err1) {
3339 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3340 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3341 return _ps_err1['__ps_value1'];
3342 } else {
3343 throw _ps_err1;
3346 };")
3348 (test-ps-js block-dynamic-return
3349 (var foo ((lambda ()
3350 (block nil
3351 ((lambda () (return 6)))
3352 (+ 1 2)))))
3353 "var foo = (function () {
3354 try {
3355 (function () {
3356 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3357 })();
3358 return 1 + 2;
3359 } catch (_ps_err1) {
3360 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3361 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3362 return _ps_err1['__ps_value1'];
3363 } else {
3364 throw _ps_err1;
3367 })();")
3369 (test-ps-js block-dynamic-return1
3370 (var foo ((lambda ()
3371 (block nil
3372 ((lambda () (return 6)))
3373 (+ 1 2))
3374 (foobar 1 2))))
3375 "var foo = (function () {
3376 nilBlock: {
3377 (function () {
3378 break nilBlock;
3379 })();
3380 1 + 2;
3382 return foobar(1, 2);
3383 })();")
3385 (test-ps-js iteration-lambda-capture-no-need
3386 (dolist (x y) (lambda (x) (1+ x))) ;; there's really no need to create a 'with' scope in this case
3387 "(function () {
3388 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3389 with ({ x : x }) {
3390 x = y[_js_idx1];
3391 function (x) {
3392 return x + 1;
3396 })();")
3398 (test-ps-js case-invert1
3399 (encodeURIComponent fooBar)
3400 "encodeURIComponent(fooBar);")
3402 (test-ps-js simple-ash
3403 (+ (ash 4 1) (ash 4 -1))
3404 "(4 << 1) + (4 >> 1);")
3406 (test-ps-js progn-nil-expression
3407 (bar (progn (foo) nil))
3408 "bar((foo(), null));")
3410 (test-ps-js other-progn-nil-exp
3411 (defun blah ()
3412 (or (foo) (progn (bar) nil)))
3413 "function blah() {
3414 return foo() || (bar(), null);
3415 };")
3417 (test-ps-js lambda-nil-return
3418 (lambda (x)
3419 (block nil
3420 (when x
3421 (return 1))
3423 "(function (x) {
3424 if (x) {
3425 return 1;
3427 return 2;
3428 });")
3430 (test-ps-js lambda-nil-return-implicit-nested2
3431 (lambda (x)
3432 (block foo
3433 (if x
3434 (return-from foo 1)
3435 (dotimes (i 4)
3436 (return-from foo i)))
3438 "(function (x) {
3439 if (x) {
3440 return 1;
3441 } else {
3442 for (var i = 0; i < 4; i += 1) {
3443 return i;
3446 return 2;
3447 });")
3449 (test-ps-js throw-is-a-statement
3450 (defun blah ()
3451 (let ((result (foo)))
3452 (unless (null result)
3453 (throw result))))
3454 "function blah() {
3455 var result = foo();
3456 if (result != null) {
3457 throw result;
3459 };")
3461 (test-ps-js expressify1
3462 (defun blah ()
3463 (when (some-condition)
3464 (foo)
3465 (bar)
3466 (baz)))
3467 "function blah() {
3468 if (someCondition()) {
3469 foo();
3470 bar();
3471 return baz();
3473 };")
3475 (test-ps-js case-when-return
3476 (defun blah (a)
3477 (case a
3478 ("a" (when (foo) (return-from blah 111)))
3479 ("b" t)))
3480 "function blah(a) {
3481 switch (a) {
3482 case 'a':
3483 if (foo()) {
3484 return 111;
3485 } else {
3486 return null;
3488 case 'b':
3489 return true;
3491 };")
3493 (test-ps-js flet-return-from
3494 (defun abc ()
3495 (flet ((foo ()
3496 (return-from foo 123)))
3497 (foo)))
3498 "function abc() {
3499 var foo = function () {
3500 return 123;
3502 return foo();
3503 };")
3505 (test-ps-js flet-return-from1
3506 (flet ((foo ()
3507 (return-from foo 123)))
3508 (foo))
3509 "(function () {
3510 var foo = function () {
3511 return 123;
3513 return foo();
3514 })();")
3516 (test-ps-js lambda-docstring-declarations
3517 (lambda (x)
3518 "This is a docstring"
3519 (declare (ignore x))
3521 "(function (x) {
3522 return 2;
3523 });")
3525 (test-ps-js setf-let-exp
3526 (setf foo (let ((x (+ 1 2)))
3527 (if x 123 456)))
3528 "foo = (function () {
3529 var x = 1 + 2;
3530 return x ? 123 : 456;
3531 })();")
3533 (test-ps-js create-let-exp
3534 (create :abc (let ((x (+ 1 2)))
3535 (if x 123 456)))
3536 "({ 'abc' : (function () {
3537 var x = 1 + 2;
3538 return x ? 123 : 456;
3539 })() });")
3541 (test-ps-js eql-eql-eql-precedence
3542 (unless (equal (= 3 3) (= 3 4))
3543 (chain console (log 1)))
3544 "if ((3 === 3) != (3 === 4)) {
3545 console.log(1);
3546 };")
3548 (test-ps-js case-cond-breaks
3549 (defun blah (x)
3550 (case x
3551 (123 (cond ((foo1)
3552 (when (foo2)
3553 (when (foo3)
3554 (return-from blah nil))
3555 t))))
3556 (456 (foo7))))
3557 "function blah(x) {
3558 switch (x) {
3559 case 123:
3560 if (foo1()) {
3561 if (foo2()) {
3562 if (foo3()) {
3563 return null;
3565 return true;
3566 } else {
3567 return null;
3569 } else {
3570 return null;
3572 case 456:
3573 return foo7();
3575 };")
3577 (test-ps-js cond-double-t
3578 (lambda ()
3579 (cond (foo 1)
3580 (t 2)
3581 (t 3)))
3582 "(function () {
3583 if (foo) {
3584 return 1;
3585 } else {
3586 return 2;
3588 });")
3590 (test-ps-js let-let-funcall-lambda
3591 (let ((x 5))
3592 (let ((x 7))
3593 (funcall (lambda (x) (+ x 9)) x)))
3594 "(function () {
3595 var x = 5;
3596 var x1 = 7;
3597 return (function (x) {
3598 return x + 9;
3599 })(x1);
3600 })();")
3602 (test-ps-js let-let-lambda
3603 (let ((x 5))
3604 (let ((x 7))
3605 (lambda (x) (+ x 9))))
3606 "(function () {
3607 var x = 5;
3608 var x1 = 7;
3609 return function (x) {
3610 return x + 9;
3612 })();")
3614 (test-ps-js let-lambda
3615 (let ((x 5))
3616 (lambda (x) (+ x 9)))
3617 "(function () {
3618 var x = 5;
3619 return function (x) {
3620 return x + 9;
3622 })();")
3624 (test-ps-js symbol-macrolet-no-shadow-lambda
3625 (symbol-macrolet ((x y))
3626 (lambda (x) (+ x x)))
3627 "(function (x) {
3628 return x + x;
3629 });")
3631 (test-ps-js divide-one-arg-reciprocal
3632 (/ 2)
3633 "1 / 2;")
3635 (test-ps-js division-not-associative
3636 (/ a (* b c))
3637 "a / (b * c);")
3639 (test-ps-js divide-expressions
3640 (/ (foo) (bar))
3641 "foo() / bar();")
3643 (test-ps-js divide-expressions1
3644 (floor (1- x) y)
3645 "Math.floor((x - 1) / y);")
3647 (test-ps-js lexical-funargs-shadow1
3648 (lambda (x)
3649 (let ((x 1))
3650 (foo x))
3651 (incf x))
3652 "(function (x) {
3653 var x1 = 1;
3654 foo(x1);
3655 return ++x;
3656 });")
3658 (test-ps-js times-rem
3659 (* x (rem y z))
3660 "x * (y % z);")
3662 (test-ps-js rem-divide
3663 (/ x (rem y z))
3664 "x / (y % z);")
3666 (test-ps-js case-break-return
3667 (lambda () (case x (:foo) (:bar 1)))
3668 "(function () {
3669 switch (x) {
3670 case 'foo':
3671 return null;
3672 case 'bar':
3673 return 1;
3675 });")
3677 (test-ps-js trivial-expression-switch
3678 (foobar (case x (1 2)))
3679 "foobar((function () {
3680 switch (x) {
3681 case 1:
3682 return 2;
3684 })());")
3686 (test-ps-js trivial-expression-while
3687 (foobar (while (< 0 x) (decf x)))
3688 "foobar((function () {
3689 while (0 < x) {
3690 --x;
3692 })());")
3694 (test-ps-js funcall-block-expression-loop-lambda
3695 (foobar (loop for i from 0 to 10 do (1+ i)))
3696 "foobar((function () {
3697 for (var i = 0; i <= 10; i += 1) {
3698 i + 1;
3700 })());")
3702 (test-ps-js plus-block-expression-loop-lambda
3703 (1+ (loop for i from 0 to 10 do (1+ i)))
3704 "(function () {
3705 for (var i = 0; i <= 10; i += 1) {
3706 i + 1;
3708 })() + 1;")
3710 (test-ps-js let-closures-rename
3711 (lambda ()
3712 (let ((x 1)) (lambda () (1+ x)))
3713 (let ((x 2)) (lambda () (1+ x))))
3714 "(function () {
3715 var x = 1;
3716 function () {
3717 return x + 1;
3719 var x1 = 2;
3720 return function () {
3721 return x1 + 1;
3723 });")
3725 (test-ps-js let-closures-rename1
3726 (lambda ()
3727 (let ((x 1))
3728 (let ((y 2))
3729 (lambda () (+ x y))))
3730 (let ((x 2))
3731 (let ((y 3))
3732 (lambda () (+ x y)))))
3733 "(function () {
3734 var x = 1;
3735 var y = 2;
3736 function () {
3737 return x + y;
3739 var x1 = 2;
3740 var y2 = 3;
3741 return function () {
3742 return x1 + y2;
3744 });")
3746 (test-ps-js let-closures-rename2
3747 (defun make-closures ()
3748 (list
3749 (let ((x 1)) (lambda () (1+ x)))
3750 (let ((x 2)) (lambda () (1+ x)))))
3751 "function makeClosures() {
3752 var x;
3753 var x1;
3754 return [(x = 1, function () {
3755 return x + 1;
3756 }), (x1 = 2, function () {
3757 return x1 + 1;
3758 })];
3760 };")
3762 (test-ps-js conditional-not-used-up
3763 (lambda (bar)
3764 (when bar
3765 (let ((x 1))
3766 (1+ x))))
3767 "(function (bar) {
3768 if (bar) {
3769 var x = 1;
3770 return x + 1;
3772 });")
3774 (test-ps-js toplevel-local-scope
3775 (create "fn" (let ((x 5)) (lambda () x)))
3776 "({ 'fn' : (function () {
3777 var x = 5;
3778 return function () {
3779 return x;
3781 })() });")
3783 (test-ps-js toplevel-local-scope1
3784 (defvar foo (create "fn" (let ((x 5)) (lambda () x))))
3785 "var foo = { 'fn' : (function () {
3786 var x = 5;
3787 return function () {
3788 return x;
3790 })() };")
3792 (test-ps-js block-let
3793 (block foobar
3794 (let ((x 1))
3795 (return-from foobar x)
3797 "(function () {
3798 var x = 1;
3799 return x;
3800 return 2;
3801 })();")
3803 (test-ps-js expressionize-if-macroexpand-error
3804 (progn (defmacro xbaz () `(blah))
3806 (defun foo (xbaz)
3807 (unless (blah)
3808 (cond (xbaz (blah))
3809 (t (blahblah))))))
3810 "function foo(xbaz) {
3811 if (!blah()) {
3812 if (xbaz) {
3813 return blah();
3814 } else {
3815 return blahblah();
3818 };")
3820 (test-ps-js toplevel-defun-macroexpand
3821 (progn (defmacro defun-js (name lambda-list &body body)
3822 `(defun ,name ,lambda-list ,@body))
3824 (let ((foo 0))
3825 (defun-js bar () (1+ foo))
3826 (defvar baz 2)))
3827 "var foo = 0;
3828 function bar() {
3829 return foo + 1;
3831 var baz = 2;")
3833 (test-ps-js js-ir-package-unique-symbols
3834 (loop :for i :from 0 :below 5 :do
3835 (let ((block (elt blocks i)))
3836 (foo block)
3837 (lambda () nil)))
3838 "(function () {
3839 for (var i = 0; i < 5; i += 1) {
3840 var block = blocks[i];
3841 foo(block);
3842 function () {
3843 return null;
3846 })();")
3848 (test-ps-js broken-quote-expansion1
3849 (lambda (p)
3850 (with-slots (x y) p
3851 (if (< x 0) y x)))
3852 "(function (p) {
3853 return p.x < 0 ? p.y : p.x;
3854 });")
3856 (test-ps-js broken-quote-expansion2
3857 (progn
3858 (define-symbol-macro foo123 (ps:@ a foo123))
3859 (lambda () (when (> foo123 1) 2)))
3860 "(function () {
3861 return a.foo123 > 1 ? 2 : null;
3862 });")
3864 (test-ps-js unused-named-block-not-printed1
3865 (block foobar
3866 (+ 1 2 3))
3867 "(function () {
3868 return 1 + 2 + 3;
3869 })();")
3871 (test-ps-js unused-named-block-not-printed2
3872 (block nil
3873 (block nil
3874 (+ 1 2 3)))
3875 "(function () {
3876 return 1 + 2 + 3;
3877 })();")
3879 (test-ps-js unused-named-block-not-printed3
3880 (block foobar
3881 (block nil
3882 (+ 1 2 3)))
3883 "(function () {
3884 return 1 + 2 + 3;
3885 })();")
3887 (test-ps-js unused-named-block-not-printed4
3888 (block nil
3889 (block foobar
3890 (block nil
3891 (+ 1 2 3))))
3892 "(function () {
3893 return 1 + 2 + 3;
3894 })();")
3896 (test-ps-js trig-no-bind1
3897 (cosh 3.14)
3898 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
3900 (test-ps-js trig-bind1
3901 (acosh (blah 3.14))
3902 "(function () {
3903 var x1 = blah(3.14);
3904 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
3905 })();")
3907 ;;; broken
3909 ;; (test-ps-js let-defun-toplevel
3910 ;; (progn (let ((foo 0))
3911 ;; (defun bar () foo))
3912 ;; (bar))
3913 ;; "var bar_foo1 = 0;
3914 ;; function bar() {
3915 ;; return bar_foo1;
3916 ;; };
3917 ;; bar();")
3919 ;; (test-ps-js let-defvar-toplevel
3920 ;; (progn (let ((foo 0))
3921 ;; (defvar bar (1+ foo)))
3922 ;; bar)
3923 ;; "var bar_foo1 = 0;
3924 ;; var bar = bar_foo1 + 1;
3925 ;; bar;")
3927 ;; (test-ps-js setf-side-effects
3928 ;; (progn
3929 ;; (let ((x 10))
3930 ;; (defun side-effect()
3931 ;; (setf x 4)
3932 ;; 3)
3933 ;; (setf x (+ 2 (side-effect) x 5))))
3934 ;; "var sideEffect_x1 = 10;
3935 ;; function sideEffect() {
3936 ;; sideEffect_x1 = 4;
3937 ;; return 3;
3938 ;; };
3939 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")