Tests to clarify behavior of SYMBOL-MACROLET wrt CREATE and GETPROP
[parenscript.git] / tests / output-tests.lisp
blob5a1c4482829050a01df1abb7f00b2e21176c597a
1 ;; SPDX-License-Identifier: BSD-3-Clause
3 (in-package #:parenscript.tests)
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 getprop-multi1
1177 (getprop foo 1 "two" three 'bar 1 2)
1178 "foo[1]['two'][three].bar[1][2];")
1180 (test-ps-js method-call-block
1181 ((@ (progn (some-fun "abc") "123") to-string))
1182 "(someFun('abc'), '123').toString();")
1184 (test-ps-js create-blank
1185 (create)
1186 "({ });")
1188 (test-ps-js blank-object-literal
1190 "({ });")
1192 (test-ps-js array-literal1
1194 "[];")
1196 (test-ps-js array-literal2
1197 ([])
1198 "[];")
1200 (test-ps-js array-literal3
1201 ([] 1 2 3)
1202 "[1, 2, 3];")
1204 (test-ps-js array-literal4
1205 ([] 1 (2 3))
1206 "[1, [2, 3]];")
1208 (test-ps-js array-literal5
1209 ([] (1 2) ("a" "b"))
1210 "[[1, 2], ['a', 'b']];")
1212 (test-ps-js defun-rest1
1213 (defun foo (&rest bar)
1214 (alert (aref bar 1)))
1215 "function foo() {
1216 var bar = Array.prototype.slice.call(arguments, 0);
1217 return alert(bar[1]);
1218 };")
1220 (test-ps-js defun-rest2
1221 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1222 "function foo(baz) {
1223 var bar = Array.prototype.slice.call(arguments, 1);
1224 return baz + bar[1];
1225 };")
1227 (test-ps-js defun-keyword1
1228 (defun zoo (foo bar &key baz) (+ foo bar baz))
1229 "function zoo(foo, bar) {
1230 var _js2 = arguments.length;
1231 for (var n1 = 2; n1 < _js2; n1 += 2) {
1232 switch (arguments[n1]) {
1233 case 'baz':
1234 baz = arguments[n1 + 1];
1237 var baz;
1238 return foo + bar + baz;
1239 };")
1241 (test-ps-js defun-keyword2
1242 (defun zoo (&key baz) (* baz baz))
1243 "function zoo() {
1244 var _js2 = arguments.length;
1245 for (var n1 = 0; n1 < _js2; n1 += 2) {
1246 switch (arguments[n1]) {
1247 case 'baz':
1248 baz = arguments[n1 + 1];
1251 var baz;
1252 return baz * baz;
1253 };")
1255 (test-ps-js defun-keyword3
1256 (defun zoo (&key baz (bar 4)) (* baz bar))
1257 "function zoo() {
1258 var _js2 = arguments.length;
1259 for (var n1 = 0; n1 < _js2; n1 += 2) {
1260 switch (arguments[n1]) {
1261 case 'baz':
1262 baz = arguments[n1 + 1];
1263 break;
1264 case 'bar':
1265 bar = arguments[n1 + 1];
1268 var baz;
1269 var bar = 'undefined' === typeof bar ? 4 : bar;
1270 return baz * bar;
1271 };")
1273 (test-ps-js defun-keyword4
1274 (defun hello-world (&key ((:my-name-key my-name) 1))
1275 my-name)
1276 "function helloWorld() {
1277 var _js2 = arguments.length;
1278 for (var n1 = 0; n1 < _js2; n1 += 2) {
1279 switch (arguments[n1]) {
1280 case 'my-name-key':
1281 myName = arguments[n1 + 1];
1284 var myName = 'undefined' === typeof myName ? 1 : myName;
1285 return myName;
1286 };")
1288 (test-ps-js arglist-keyword-supplied
1289 (lambda (&key (foo 1 supplied?))
1290 foo)
1291 "(function () {
1292 var _js2 = arguments.length;
1293 for (var n1 = 0; n1 < _js2; n1 += 2) {
1294 switch (arguments[n1]) {
1295 case 'foo':
1296 foo = arguments[n1 + 1];
1297 suppliedwhat = true;
1300 var suppliedwhat;
1301 var foo = 'undefined' === typeof foo ? 1 : foo;
1302 return foo;
1303 });")
1305 (test-ps-js keyword-funcall1
1306 (func :baz 1)
1307 "func('baz', 1);")
1309 (test-ps-js keyword-funcall2
1310 (func :baz 1 :bar foo)
1311 "func('baz', 1, 'bar', foo);")
1313 (test-ps-js keyword-funcall3
1314 (fun a b :baz c)
1315 "fun(a, b, 'baz', c);")
1317 (test-ps-js cond1
1318 (cond ((= x 1) 1))
1319 "if (x === 1) {
1321 };")
1323 (test-ps-js cond2
1324 (cond ((= x 1) 2)
1325 ((= y (* x 4)) (foo "blah") (* x y)))
1326 "if (x === 1) {
1328 } else if (y === x * 4) {
1329 foo('blah');
1330 x * y;
1331 };")
1333 (test-ps-js if-exp-without-else-return
1334 (defun foo () (return-from foo (if x 1)))
1335 "function foo() {
1336 return x ? 1 : null;
1337 };")
1339 (test-ps-js progn-expression-single-statement
1340 (defun foo () (return-from foo (progn (* x y))))
1341 "function foo() {
1342 return x * y;
1343 };")
1345 (test-ps-js cond-expression1
1346 (defun foo ()
1347 (cond ((< 1 2) (bar "foo") (* 4 5))))
1348 "function foo() {
1349 if (1 < 2) {
1350 bar('foo');
1351 return 4 * 5;
1353 };")
1355 (test-ps-js cond-expression2
1356 (defun foo ()
1357 (cond ((< 2 1) "foo")
1358 ((= 7 7) "bar")))
1359 "function foo() {
1360 if (2 < 1) {
1361 return 'foo';
1362 } else if (7 === 7) {
1363 return 'bar';
1365 };")
1367 (test-ps-js cond-expression-final-t-clause
1368 (defun foo ()
1369 (cond ((< 1 2) (bar "foo") (* 4 5))
1370 ((= a b) (+ c d))
1371 ((< 1 2 3 4 5) x)
1372 (t "foo")))
1373 "function foo() {
1374 var _cmp1;
1375 var _cmp2;
1376 var _cmp3;
1377 if (1 < 2) {
1378 bar('foo');
1379 return 4 * 5;
1380 } else if (a === b) {
1381 return c + d;
1382 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1383 return x;
1384 } else {
1385 return 'foo';
1387 };")
1389 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1390 (defun foo ()
1391 (cond ((< 2 1) 5)
1392 (t "foo")
1393 ((< 1 2) "bar")))
1394 "function foo() {
1395 if (2 < 1) {
1396 return 5;
1397 } else {
1398 return 'foo';
1400 };")
1402 (test-ps-js funcall-if-expression
1403 (funcall (getprop document 'write)
1404 (if (= *linkornot* 1)
1405 (ps-html ((:a :href "#"
1406 :onclick (ps-inline (transport)))
1407 img))
1408 img))
1409 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>'].join('') : img);")
1411 (test-ps-js negate-number-literal
1412 (- 1)
1413 "-1;")
1415 (test macro-environment1
1416 (is (string= (normalize-js-code (let* ((macroname (gensym)))
1417 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1418 `(defun test1 ()
1419 (macrolet ((,macroname (x) `(aref data ,x)))
1420 (when (,macroname x)
1421 (setf (,macroname x) 123)))))))
1422 (normalize-js-code
1423 "function test1() {
1424 return data[x] ? (data[x] = 123) : null;
1425 };"))))
1427 (test macro-environment2
1428 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
1429 (defpsmacro macro-environment2-macro (x)
1430 `(+ ,outer-lexical-variable ,x))
1431 (ps* '(macro-environment2-macro 2))))
1432 (normalize-js-code "1 + 2;"))))
1434 (test-ps-js ampersand-whole-1
1435 (macrolet ((foo (&whole foo bar baz)
1436 (declare (ignore bar baz))
1437 (with-standard-io-syntax (format nil "~a" foo))))
1438 (foo 1 2))
1439 "'(FOO 1 2)';")
1441 (test-ps-js ampersand-whole-2
1442 (macrolet ((foo (&whole foo bar baz)
1443 `(+ ,bar ,baz)))
1444 (foo 1 2))
1445 "1 + 2;")
1447 (test-ps-js keyword-consistent
1449 "'x';")
1451 (test-ps-js simple-symbol-macrolet
1452 (symbol-macrolet ((x 1)) x)
1453 "1;")
1455 (test-ps-js compound-symbol-macrolet
1456 (symbol-macrolet ((x 123)
1457 (y (* 2 x)))
1459 "2 * 123;")
1461 (test-ps-js define-symbol-macro
1462 (progn (define-symbol-macro tst-sym-macro 2)
1463 tst-sym-macro)
1464 "2;")
1466 (test-ps-js define-symbol-macro1
1467 (progn (define-symbol-macro tst-sym-macro1 2)
1468 (foo tst-sym-macro1))
1469 "foo(2);")
1471 (test-ps-js expression-progn
1472 (1+ (progn (foo) (if x 1 2)))
1473 "(foo(), x ? 1 : 2) + 1;")
1475 (test-ps-js let-decl-in-expression
1476 (defun f (x)
1477 (if x 1 (let* ((foo x)) foo)))
1478 "function f(x) {
1479 if (x) {
1480 return 1;
1481 } else {
1482 var foo = x;
1483 return foo;
1485 };")
1487 (test-ps-js special-var1
1488 (progn (defvar *foo*)
1489 (let* ((*foo* 2))
1490 (* *foo* 2)))
1491 "var FOO;
1492 (function () {
1493 var FOO_TMPSTACK1;
1494 try {
1495 FOO_TMPSTACK1 = FOO;
1496 FOO = 2;
1497 return FOO * 2;
1498 } finally {
1499 FOO = FOO_TMPSTACK1;
1501 })();")
1503 (test-ps-js special-var2
1504 (progn (defvar *foo*)
1505 (let* ((*baz* 3)
1506 (*foo* 2))
1507 (* *foo* 2 *baz*)))
1508 "var FOO;
1509 (function () {
1510 var BAZ = 3;
1511 var FOO_TMPSTACK1;
1512 try {
1513 FOO_TMPSTACK1 = FOO;
1514 FOO = 2;
1515 return FOO * 2 * BAZ;
1516 } finally {
1517 FOO = FOO_TMPSTACK1;
1519 })();")
1521 (test-ps-js literal1
1522 (setf x undefined)
1523 "x = undefined;")
1525 (test-ps-js literal2
1526 (aref this x)
1527 "this[x];")
1529 (test-ps-js setf-dec1
1530 (setf x (- 1 x 2))
1531 "x = 1 - x - 2;")
1533 (test-ps-js setf-dec2
1534 (setf x (- x 1 2))
1535 "x = x - 1 - 2;")
1537 (test-ps-js special-char-equals
1538 blah=
1539 "blahequals;")
1541 (test-ps-js setf-operator-priority
1542 (defun foo ()
1543 (or (getprop cache id)
1544 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1545 "function foo() {
1546 return cache[id] || (cache[id] = document.getElementById(id));
1547 };")
1549 (test-ps-js aref-operator-priority
1550 (aref (if (and x (> (length x) 0))
1551 (aref x 0)
1554 "(x && x.length > 0 ? x[0] : y)[z];")
1556 (test-ps-js aref-operator-priority1
1557 (aref (or (getprop x 'y)
1558 (getprop a 'b))
1560 "(x.y || a.b)[z];")
1562 (test-ps-js aref-operator-priority2
1563 (aref (if a b c) 0)
1564 "(a ? b : c)[0];")
1566 (test-ps-js negate-operator-priority
1567 (- (if x y z))
1568 "-(x ? y : z);")
1570 (test-ps-js op-p1
1571 (new (or a b))
1572 "new (a || b);")
1574 (test-ps-js op-p2
1575 (delete (if a (or b c) d))
1576 "delete (a ? b || c : d);")
1578 (test-ps-js op-p3
1579 (not (if (or x (not y)) z))
1580 "!(x || !y ? z : null);")
1582 (test-ps-js op-p4
1583 (- (- (* 1 2) 3))
1584 "-(1 * 2 - 3);")
1586 (test-ps-js op-p5
1587 (instanceof (or a b) (if x y z))
1588 "((a || b) instanceof (x ? y : z));")
1590 (test-ps-js op-p7
1591 (or x (if (= x 0) "zero" "empty"))
1592 "x || (x === 0 ? 'zero' : 'empty');")
1594 (test-ps-js named-op-expression
1595 (throw (if a b c))
1596 "throw a ? b : c;")
1598 (test-ps-js named-op-expression1
1599 (typeof (or x y))
1600 "typeof (x || y);")
1602 (test-ps-js aref-array-expression
1603 (aref (or a b c) 0)
1604 "(a || b || c)[0];")
1606 (test-ps-js getprop-operator
1607 (getprop (or a b c) 'd)
1608 "(a || b || c).d;")
1610 (test-ps-js getprop-parens
1611 (getprop (getprop foo 'bar) 'baz)
1612 "foo.bar.baz;")
1614 (test-ps-js funcall-funcall
1615 ((foo))
1616 "foo()();")
1618 (test-ps-js expression-funcall
1619 ((or (@ window eval) eval) foo nil)
1620 "(window.eval || eval)(foo, null);")
1622 (test-ps-js expression-funcall1
1623 (((or (@ window eval) eval) foo nil))
1624 "(window.eval || eval)(foo, null)();")
1626 (test-ps-js expression-funcall2
1627 (((or (@ window eval) eval)) foo nil)
1628 "(window.eval || eval)()(foo, null);")
1630 (test-ps-js who-html1
1631 (who-ps-html (:span :class "ticker-symbol"
1632 :ticker-symbol symbol
1633 (:a :href "http://foo.com"
1634 symbol)
1635 (:span :class "ticker-symbol-popup")))
1636 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>'].join('');")
1638 (test-ps-js who-html2
1639 (who-ps-html (:p "t0" (:span "t1")))
1640 "'<P>t0<SPAN>t1</SPAN></P>';")
1642 (test-ps-js flet1
1643 ((lambda () (flet ((foo (x)
1644 (1+ x)))
1645 (foo 1))))
1646 "(function () {
1647 var foo = function (x) {
1648 return x + 1;
1650 return foo(1);
1651 })();")
1653 (test-ps-js flet2
1654 (flet ((foo (x) (1+ x))
1655 (bar (y) (+ 2 y)))
1656 (bar (foo 1)))
1657 "(function () {
1658 var foo = function (x) {
1659 return x + 1;
1661 var bar = function (y) {
1662 return 2 + y;
1664 return bar(foo(1));
1665 })();")
1667 (test-ps-js flet3
1668 (flet ((foo (x) (+ 2 x)))
1669 (flet ((foo (x) (1+ x))
1670 (bar (y) (+ 2 (foo y))))
1671 (bar (foo 1))))
1672 "(function () {
1673 var foo = function (x) {
1674 return 2 + x;
1676 var foo1 = function (x) {
1677 return x + 1;
1679 var bar = function (y) {
1680 return 2 + foo(y);
1682 return bar(foo1(1));
1683 })();")
1685 (test-ps-js labels1
1686 ((lambda () (labels ((foo (x)
1687 (if (= 0 x)
1689 (+ x (foo (1- x))))))
1690 (foo 3))))
1691 "(function () {
1692 var foo = function (x) {
1693 return 0 === x ? 0 : x + foo(x - 1);
1695 return foo(3);
1696 })();")
1698 (test-ps-js labels2
1699 (labels ((foo (x) (1+ (bar x)))
1700 (bar (y) (+ 2 (foo y))))
1701 (bar (foo 1)))
1702 "(function () {
1703 var foo = function (x) {
1704 return bar(x) + 1;
1706 var bar = function (y) {
1707 return 2 + foo(y);
1709 return bar(foo(1));
1710 })();")
1712 (test-ps-js labels3
1713 (labels ((foo (x) (1+ x))
1714 (bar (y) (+ 2 (foo y))))
1715 (bar (foo 1)))
1716 "(function () {
1717 var foo = function (x) {
1718 return x + 1;
1720 var bar = function (y) {
1721 return 2 + foo(y);
1723 return bar(foo(1));
1724 })();")
1726 (test-ps-js labels-lambda-list
1727 (labels ((foo (x &optional (y 0))
1728 (+ x y)))
1729 (foo 1))
1730 "(function () {
1731 var foo = function (x, y) {
1732 if (y === undefined) {
1733 y = 0;
1735 return x + y;
1737 return foo(1);
1738 })();")
1740 (test-ps-js for-loop-var-init-exp
1741 ((lambda (x)
1742 (do* ((y (if x 0 1) (1+ y))
1743 (z 0 (1+ z)))
1744 ((= y 3) z)))
1746 "(function (x) {
1747 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1749 return z;
1750 })(true);")
1752 (test-ps-js math-pi
1754 "Math.PI;")
1756 (test-ps-js literal-array
1757 '(1 2 3)
1758 "[1, 2, 3];")
1760 (test-ps-js literal-array-1
1761 '(1 foo 3)
1762 "[1, 'foo', 3];")
1764 (test-ps-js literal-array-literal
1766 "[];")
1768 (test-ps-js literal-array-literal1
1769 '(1 [])
1770 "[1, []];")
1772 (test ps-lisp-expands-in-lexical-environment
1773 (is (string= "5;" (let ((x 5))
1774 (ps (lisp x))))))
1776 (test ps-lisp-expands-in-lexical-environment1
1777 (is (string= "1 + 5;" (let ((x 5))
1778 (ps (+ 1 (lisp x)))))))
1780 (test ps-lisp-expands-in-lexical-environment2
1781 (is (string= "1 + 2 + 3;" (let ((x 2))
1782 (ps (+ 1 (lisp x) 3))))))
1784 (test ps*-lisp-expands-in-null-lexical-environment
1785 (signals unbound-variable (let ((x 5))
1786 (declare (ignore x))
1787 (ps* '(lisp x)))))
1789 (test ps*-lisp-expands-in-dynamic-environment
1790 (is (string= "1 + 2;"
1791 (let ((foo 2))
1792 (declare (special foo))
1793 (ps* '(+ 1 (lisp (locally (declare (special foo)) foo))))))))
1795 (test ps-lisp-dynamic-environment
1796 (is (string= "1 + 2;"
1797 (let ((foo 2))
1798 (declare (special foo))
1799 (ps (+ 1 (lisp foo)))))))
1801 (test-ps-js nested-if-expressions1
1802 (defun foo ()
1803 (return-from foo (if (if x y z) a b)))
1804 "function foo() {
1805 if (x ? y : z) {
1806 return a;
1807 } else {
1808 return b;
1810 };")
1812 (test-ps-js nested-if-expressions2
1813 (defun foo ()
1814 (if x y (if z a b)))
1815 "function foo() {
1816 if (x) {
1817 return y;
1818 } else {
1819 return z ? a : b;
1821 };")
1823 (test-ps-js let1
1824 (let (x)
1825 (+ x x))
1826 "(function () {
1827 var x = null;
1828 return x + x;
1829 })();")
1831 (test-ps-js let2
1832 (let ((x 1))
1833 (+ x x))
1834 "(function () {
1835 var x = 1;
1836 return x + x;
1837 })();")
1839 (test-ps-js let-x-x
1840 (let ((x (1+ x)))
1841 (+ x x))
1842 "(function () {
1843 var x1 = x + 1;
1844 return x1 + x1;
1845 })();")
1847 (test-ps-js let3
1848 (let ((x 1)
1849 (y 2))
1850 (+ x x))
1851 "(function () {
1852 var x = 1;
1853 var y = 2;
1854 return x + x;
1855 })();")
1857 (test-ps-js let4
1858 (let ((x 1)
1859 (y (1+ x)))
1860 (+ x y))
1861 "(function () {
1862 var x1 = 1;
1863 var y = x + 1;
1864 return x1 + y;
1865 })();")
1867 (test-ps-js let5
1868 (let ((x 1))
1869 (+ x 1)
1870 (let ((x (+ x 5)))
1871 (+ x 1))
1872 (+ x 1))
1873 "(function () {
1874 var x = 1;
1875 x + 1;
1876 var x1 = x + 5;
1877 x1 + 1;
1878 return x + 1;
1879 })();")
1881 (test-ps-js let6
1882 (let ((x 2))
1883 (let ((x 1)
1884 (y (1+ x)))
1885 (+ x y)))
1886 "(function () {
1887 var x = 2;
1888 var x1 = 1;
1889 var y = x + 1;
1890 return x1 + y;
1891 })();")
1893 (test-ps-js let-exp1
1894 (lambda ()
1895 (let (x)
1896 (+ x x)))
1897 "(function () {
1898 var x = null;
1899 return x + x;
1900 });")
1902 (test-ps-js let*1
1903 (let* ((x 1))
1904 (+ x x))
1905 "(function () {
1906 var x = 1;
1907 return x + x;
1908 })();")
1910 (test-ps-js let*2
1911 (let* ((x 1)
1912 (y (+ x 2)))
1913 (+ x y))
1914 "(function () {
1915 var x = 1;
1916 var y = x + 2;
1917 return x + y;
1918 })();")
1920 (test-ps-js let*3
1921 (let ((x 3))
1922 (let* ((x 1)
1923 (y (+ x 2)))
1924 (+ x y)))
1925 "(function () {
1926 var x = 3;
1927 var x1 = 1;
1928 var y = x1 + 2;
1929 return x1 + y;
1930 })();")
1932 (test-ps-js let*4
1933 (let ((x 3))
1934 (let* ((y (+ x 2))
1935 (x 1))
1936 (+ x y)))
1937 "(function () {
1938 var x = 3;
1939 var y = x + 2;
1940 var x1 = 1;
1941 return x1 + y;
1942 })();")
1944 (test-ps-js symbol-macrolet-var
1945 (symbol-macrolet ((x y))
1946 (var x))
1947 "var y;")
1949 (test-ps-js setf-conditional1
1950 (setf x (unless (null a) (1+ a)))
1951 "x = a != null ? a + 1 : null;")
1953 (test-ps-js setf-let1
1954 (setf x (let ((a 1)) a))
1955 "x = (function () {
1956 var a = 1;
1957 return a;
1958 })();")
1960 (test-ps-js setf-let2
1961 (setf x (let ((a (foo)))
1962 (unless (null a)
1963 (1+ a))))
1964 "x = (function () {
1965 var a = foo();
1966 return a != null ? a + 1 : null;
1967 })();")
1969 (test-ps-js symbol-macro-env1
1970 (symbol-macrolet ((bar 1))
1971 (macrolet ((bar (x y) `(+ ,x ,y)))
1972 (bar bar bar)))
1973 "1 + 1;")
1975 (test-ps-js symbol-macrolet-fun1
1976 (symbol-macrolet ((baz +))
1977 (baz 1 2))
1978 "baz(1, 2);")
1980 (test-ps-js lisp2-namespaces1
1981 (let ((list nil))
1982 (setf list (list 1 2 3)))
1983 "(function () {
1984 var list = null;
1985 return list = [1, 2, 3];
1986 })();")
1988 (test-ps-js let-shadows-symbol-macrolet
1989 (symbol-macrolet ((x y))
1990 (let ((x 1))
1991 (+ x x))
1992 (+ x x))
1993 "(function () {
1994 var x1 = 1;
1995 return x1 + x1;
1996 })();
1997 y + y;")
1999 (test-ps-js let-rename-optimization1
2000 (let ((x 1))
2001 (+ x x))
2002 "(function () {
2003 var x = 1;
2004 return x + x;
2005 })();")
2007 (test-ps-js let-rename-optimization2
2008 (lambda (x)
2009 (let ((x (+ 1 x)))
2011 "(function (x) {
2012 var x1 = 1 + x;
2013 return x1;
2014 });")
2016 (test-ps-js symbol-macro-array
2017 (symbol-macrolet ((x 1))
2018 (list x))
2019 "[1];")
2021 (test-ps-js symbol-macro-obj
2022 (symbol-macrolet ((x (+ 1 2)))
2023 (create x 1))
2024 "({ x : 1 });")
2026 (test-ps-js symbol-macro-obj1
2027 (symbol-macrolet ((x (+ 1 2)))
2028 (ps:create x x))
2029 "({ x : 1 + 2 });")
2031 (test-ps-js symbol-macro-getprop1
2032 (symbol-macrolet ((x (+ 1 2)))
2033 (ps:getprop a x))
2034 "a[1 + 2];")
2036 (test-ps-js symbol-macro-getprop1
2037 (symbol-macrolet ((x (+ 1 2)))
2038 (ps:getprop a 'x))
2039 "a.x;")
2041 (test-ps-js let-let-create
2042 (let ((a 99))
2043 (let ((a 22))
2044 (create a 33)))
2045 "(function () {
2046 var a = 99;
2047 var a1 = 22;
2048 return { a : 33 };
2049 })();")
2051 (test-ps-js symbol-macro-conditional1
2052 (symbol-macrolet ((x y))
2053 (if x x x))
2054 "if (y) {
2056 } else {
2058 };")
2060 (test-ps-js symbol-macro-conditional2
2061 (symbol-macrolet ((x y))
2062 (1+ (if x x x)))
2063 "(y ? y : y) + 1;")
2065 (test-ps-js preserve-this
2066 (defun foo ()
2067 (let ((y (block nil (bar this))))
2068 (baz y)))
2069 "function foo() {
2070 var y = (function () {
2071 return bar(this);
2072 }).call(this);
2073 return baz(y);
2074 };")
2076 (test-ps-js flet-apply
2077 (flet ((foo () 'bar))
2078 (apply (function foo) nil))
2079 "(function () {
2080 var foo = function () {
2081 return 'bar';
2083 return foo.apply(this, null);
2084 }).call(this);")
2086 (test-ps-js let-apply
2087 (let ((foo (lambda () 1)))
2088 (let ((foo (lambda () 2)))
2089 (apply foo nil)))
2090 "(function () {
2091 var foo = function () {
2092 return 1;
2094 var foo1 = function () {
2095 return 2;
2097 return foo1.apply(this, null);
2098 }).call(this);")
2100 (test-ps-js flet-let
2101 (flet ((x (x) (1+ x)))
2102 (let ((x 2))
2103 (x x)))
2104 "(function () {
2105 var x = function (x) {
2106 return x + 1;
2108 var x1 = 2;
2109 return x(x1);
2110 })();")
2112 (test-ps-js let-flet
2113 (let ((x 2))
2114 (flet ((x (x) (1+ x)))
2115 (x x)))
2116 "(function () {
2117 var x = 2;
2118 var x1 = function (x) {
2119 return x + 1;
2121 return x1(x);
2122 })();")
2124 (test-ps-js labels-let
2125 (labels ((x (x) (1+ x)))
2126 (let ((x 2))
2127 (x x)))
2128 "(function () {
2129 var x = function (x) {
2130 return x + 1;
2132 var x1 = 2;
2133 return x(x1);
2134 })();")
2136 (test-ps-js let-labels
2137 (let ((x 2))
2138 (labels ((x (x) (1+ x)))
2139 (x x)))
2140 "(function () {
2141 var x = 2;
2142 var x1 = function (x) {
2143 return x + 1;
2145 return x1(x);
2146 })();")
2148 (test-ps-js macrolet-let-inteference
2149 (macrolet ((a (n) `(+ ,n 5)))
2150 (let ((a (a 1)))
2151 (let ((b (a (- a 4))))
2152 (+ a b))))
2153 "(function () {
2154 var a = 1 + 5;
2155 var b = (a - 4) + 5;
2156 return a + b;
2157 })();")
2159 (test-ps-js let-subtract-add
2160 (let ((x 1))
2161 (let ((x 2))
2162 (- x x)
2163 (- x)
2164 (decf x)
2165 (incf x)))
2166 "(function () {
2167 var x = 1;
2168 var x1 = 2;
2169 x1 - x1;
2170 -x1;
2171 --x1;
2172 return ++x1;
2173 })();")
2175 (test-ps-js create-reserved-word
2176 (create :default 1)
2177 "({ 'default' : 1 });")
2179 (test-ps-js getprop-reserved-word
2180 (getprop foo :default)
2181 "foo['default'];")
2183 (test-ps-js getprop-reserved-word1
2184 (getprop foo 'default)
2185 "foo['default'];")
2187 (test-ps-js eval-when-ps-side
2188 (eval-when (:execute)
2190 "5;")
2192 (defvar *lisp-output* nil)
2194 (test eval-when-lisp-side ()
2195 (setf *lisp-output* 'original-value)
2196 (let ((js-output (normalize-js-code
2197 (ps-doc* `(eval-when (:compile-toplevel)
2198 (setf *lisp-output* 'it-works))))))
2199 (is (eql 'it-works *lisp-output*))
2200 (is (string= "" js-output))))
2202 (defpsmacro my-in-package (package-name)
2203 `(eval-when (:compile-toplevel)
2204 (setf *lisp-output* ,package-name)))
2206 (test eval-when-macro-expansion ()
2207 (setf *lisp-output* 'original-value)
2208 (let ((js-output (normalize-js-code
2209 (ps-doc* `(progn
2210 (my-in-package :cl-user)
2211 3)))))
2212 (declare (ignore js-output))
2213 (is (eql :cl-user *lisp-output*))))
2215 (test eval-when-macrolet-expansion ()
2216 (setf *lisp-output* 'original-value)
2217 (let ((js-output (normalize-js-code
2218 (ps-doc* `(macrolet ((my-in-package2 (package-name)
2219 `(eval-when (:compile-toplevel)
2220 (setf *lisp-output* ,package-name))))
2221 (my-in-package2 :cl-user)
2222 3)))))
2223 (declare (ignore js-output))
2224 (is (eql :cl-user *lisp-output*))))
2226 (test-ps-js getprop-keyword
2227 (getprop foo :bar)
2228 "foo['bar'];")
2230 (test-ps-js nary-comparison1
2231 (lambda () (< 1 2 3))
2232 "(function () {
2233 var _cmp1;
2234 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2235 });")
2237 (test-ps-js chain-getprop1
2238 (chain ($ "foo") (bar x z) frob (baz 5))
2239 "$('foo').bar(x, z).frob.baz(5);")
2241 (test-ps-js chain-getprop2
2242 (chain ($ "foo") bar baz)
2243 "$('foo').bar.baz;")
2245 (test-ps-js chain-getprop3
2246 (chain ($ "foo") bar (x y) baz)
2247 "$('foo').bar.x(y).baz;")
2249 (test-ps-js flet-expression
2250 (1+ (flet ((foo (x) (1+ x)))
2251 (foo 1)))
2252 "(function () {
2253 var foo = function (x) {
2254 return x + 1;
2256 return foo(1);
2257 })() + 1;")
2259 (test-ps-js flet-lambda-list
2260 (flet ((foo (x &key (y 0))
2261 (+ x y)))
2262 (foo 1 :y 2))
2263 "(function () {
2264 var foo = function (x) {
2265 var _js2 = arguments.length;
2266 for (var n1 = 1; n1 < _js2; n1 += 2) {
2267 switch (arguments[n1]) {
2268 case 'y':
2269 y = arguments[n1 + 1];
2272 var y = 'undefined' === typeof y ? 0 : y;
2273 return x + y;
2275 return foo(1, 'y', 2);
2276 })();")
2278 (test-ps-js return-case-break-elimination
2279 (defun foo ()
2280 (return-from foo
2281 (case 1
2282 (0 1)
2283 (otherwise 2))))
2284 "function foo() {
2285 switch (1) {
2286 case 0:
2287 return 1;
2288 default:
2289 return 2;
2291 };")
2293 (test-ps-js aplusplus
2295 "aplusplus;")
2297 (test-ps-js astarstar
2299 "astarstar;")
2301 (test-ps-js switch-return-fallthrough
2302 (defun foo ()
2303 (return-from foo
2304 (switch x
2305 (1 (foo) break)
2306 (2 (bar))
2307 (default 4))))
2308 "function foo() {
2309 switch (x) {
2310 case 1:
2311 return foo();
2312 case 2:
2313 bar();
2314 default:
2315 return 4;
2317 };")
2319 (test-ps-js return-last-case
2320 (defun foo ()
2321 (return-from foo
2322 (case x
2323 (:a 'eh)
2324 (:b 'bee))))
2325 "function foo() {
2326 switch (x) {
2327 case 'a':
2328 return 'eh';
2329 case 'b':
2330 return 'bee';
2332 };")
2334 (test-ps-js return-macrolet
2335 (defun foo ()
2336 (return-from foo
2337 (macrolet ((x () 1))
2338 (case (x)
2339 (:a 'eh)
2340 (:b 'bee)))))
2341 "function foo() {
2342 switch (1) {
2343 case 'a':
2344 return 'eh';
2345 case 'b':
2346 return 'bee';
2348 };")
2350 (test-ps-js mv-bind1
2351 (multiple-value-bind (a b)
2352 (progn
2353 (returns-mv)
2354 (doesnt))
2355 (alert a)
2356 (alert b))
2357 "returnsMv();
2358 (function () {
2359 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2360 try {
2361 var a = doesnt();
2362 var _db2 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2363 var b = _db2[0];
2364 alert(a);
2365 return alert(b);
2366 } finally {
2367 __PS_MV_REG = prevMv1;
2369 })();")
2371 (test-ps-js mv-bind2
2372 (multiple-value-bind (a b)
2373 (let ((a 1))
2374 (returns-mv a)
2375 (doesnt b))
2376 (alert a)
2377 (alert b))
2378 "(function () {
2379 var a = 1;
2380 returnsMv(a);
2381 var prevMv2 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2382 try {
2383 var a3 = doesnt(b);
2384 var _db4 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2385 var b = _db4[0];
2386 alert(a3);
2387 return alert(b);
2388 } finally {
2389 __PS_MV_REG = prevMv2;
2391 })();")
2393 (test-ps-js multiple-value-bind-simple
2394 (multiple-value-bind (a b) (blah)
2395 (+ a b))
2396 "(function () {
2397 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2398 try {
2399 var a = blah();
2400 var _db2 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2401 var b = _db2[0];
2402 return a + b;
2403 } finally {
2404 __PS_MV_REG = prevMv1;
2406 })();")
2408 (test-ps-js values0
2409 (lambda () (values))
2410 "(function () {
2411 __PS_MV_REG = {};
2412 return null;
2413 });")
2415 (test-ps-js values1
2416 (values x)
2417 "x;")
2419 (test-ps-js values2
2420 (lambda () (values x y))
2421 "(function () {
2422 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2423 return x;
2424 });")
2426 (test-ps-js values3
2427 (lambda () (values x y z))
2428 "(function () {
2429 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2430 return x;
2431 });")
2433 (test-ps-js values-return
2434 (defun foo (x y)
2435 (return-from foo (values (* x x) y)))
2436 "function foo(x, y) {
2437 var val1_1 = x * x;
2438 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2439 return val1_1;
2440 };")
2442 (test-ps-js return-macrolet1
2443 (defun foo ()
2444 (return-from foo
2445 (symbol-macrolet ((x 2))
2446 (loop do (+ x x)))))
2447 "function foo() {
2448 while (true) {
2449 2 + 2;
2451 };")
2453 (test-ps-js return-cond
2454 (defun foo ()
2455 (return-from foo
2456 (cond ((foo? x) (loop for y in x do (foo y)))
2457 ((bar? x) x)
2458 (t 3))))
2459 "function foo() {
2460 if (foowhat(x)) {
2461 var _js2 = x.length;
2462 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2463 var y = x[_js1];
2464 foo(y);
2466 } else if (barwhat(x)) {
2467 return x;
2468 } else {
2469 return 3;
2471 };")
2473 (test-ps-js return-case
2474 (defun foo ()
2475 (return-from foo
2476 (case x
2477 (1 (loop for y in x do (foo y)))
2478 (2 x)
2479 ((t) 3))))
2480 "function foo() {
2481 switch (x) {
2482 case 1:
2483 var _js2 = x.length;
2484 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2485 var y = x[_js1];
2486 foo(y);
2488 return;
2489 case 2:
2490 return x;
2491 case true:
2492 return 3;
2494 };")
2496 (test-ps-js return-case1
2497 (defun foo ()
2498 (return-from foo
2499 (case x
2500 (1 (if a 1 2))
2501 (2 x)
2502 ((t) 3))))
2503 "function foo() {
2504 switch (x) {
2505 case 1:
2506 return a ? 1 : 2;
2507 case 2:
2508 return x;
2509 case true:
2510 return 3;
2512 };")
2514 (test-ps-js lambda-loop-if-return
2515 (lambda ()
2516 (if a
2517 (loop for y in x do (foo y))
2519 "(function () {
2520 if (a) {
2521 var _js4 = x.length;
2522 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2523 var y = x[_js3];
2524 foo(y);
2526 } else {
2527 return c;
2529 });")
2531 (test-ps-js lambda-loop-if-return1
2532 (defun baz ()
2533 (foo (lambda ()
2534 (if a
2535 (progn (loop for y in x do (foo y))
2536 (return-from baz))
2537 c))))
2538 "function baz() {
2539 try {
2540 return foo(function () {
2541 if (a) {
2542 var _js4 = x.length;
2543 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2544 var y = x[_js3];
2545 foo(y);
2547 throw { '__ps_block_tag' : 'baz',
2548 '__ps_value1' : null };
2549 } else {
2550 return c;
2553 } catch (_ps_err5) {
2554 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2555 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2556 return _ps_err5['__ps_value1'];
2557 } else {
2558 throw _ps_err5;
2561 };")
2563 (test-ps-js switch-loop
2564 (defun foo (x)
2565 (case x
2566 (1 (dolist (a b)))))
2567 "function foo(x) {
2568 switch (x) {
2569 case 1:
2570 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2571 a = b[_js_idx1];
2573 return;
2575 };")
2577 (test-ps-js switch-folds-blocks
2578 (defun foo ()
2579 (case x
2580 (1 (loop repeat 3 do (alert "foo")))
2581 (2 "bar")))
2582 "function foo() {
2583 switch (x) {
2584 case 1:
2585 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2586 alert('foo');
2588 return;
2589 case 2:
2590 return 'bar';
2592 };")
2594 (test-ps-js setf-places-before-macros
2595 (lambda ()
2596 (defsetf left (el) (offset)
2597 `(setf (@ ,el style left) ,offset))
2598 (macrolet ((left (el)
2599 `(@ ,el offset-left)))
2600 (setf (left x) 10)
2601 (left x)))
2602 "(function () {
2603 var _js2 = x;
2604 var _js1 = 10;
2605 _js2.style.left = _js1;
2606 return x.offsetLeft;
2607 });")
2609 (test-ps-js for-return
2610 (lambda () (dolist (arg args) (foo arg)))
2611 "(function () {
2612 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2613 arg = args[_js_idx1];
2614 foo(arg);
2616 });")
2618 (test-ps-js try-catch-return
2619 (defun foo ()
2620 (return-from foo
2621 (try (foo)
2622 (:catch (e)
2623 (bar))
2624 (:finally
2625 (cleanup)))))
2626 "function foo() {
2627 try {
2628 return foo();
2629 } catch (e) {
2630 return bar();
2631 } finally {
2632 cleanup();
2634 };")
2636 (test-ps-js defun-setf-optional
2637 (defun (setf foo) (new-value b &optional c)
2638 (setf (aref b (or c 0)) new-value))
2639 "function __setf_foo(newValue, b, c) {
2640 return b[c || 0] = newValue;
2641 };")
2643 (test-ps-js defun-setf-rest
2644 (progn (defun (setf foo) (new-value b &rest foo)
2645 (do-something b foo new-value))
2646 (setf (foo x 1 2 3 4) 5))
2647 "function __setf_foo(newValue, b) {
2648 var foo = Array.prototype.slice.call(arguments, 2);
2649 return doSomething(b, foo, newValue);
2651 __setf_foo(5, x, 1, 2, 3, 4);")
2653 (test-ps-js return-null
2654 (defun foo () (return-from foo nil))
2655 "function foo() {
2656 return null;
2657 };")
2659 (test-ps-js implicit-return-null
2660 (lambda ()
2662 "(function () {
2663 return null;
2664 });")
2666 (test-ps-js implicit-return-null
2667 (lambda ()
2668 nil)
2669 "(function () {
2670 return null;
2671 });")
2673 (test-ps-js return-conditional-nested
2674 (defun blep (ss x y)
2675 (when foo?
2676 (let ((pair (bar)))
2677 (unless (null pair)
2678 (destructuring-bind (a b) pair
2679 (unless (or (null a) (null b))
2680 (let ((val (baz a b)))
2681 (unless (null val)
2682 (when (blah val)
2683 (unless (blee)
2684 t))))))))))
2685 "function blep(ss, x, y) {
2686 if (foowhat) {
2687 var pair = bar();
2688 if (pair != null) {
2689 var a = pair[0];
2690 var b = pair[1];
2691 if (!(a == null || b == null)) {
2692 var val = baz(a, b);
2693 if (val != null) {
2694 if (blah(val)) {
2695 return !blee() ? true : null;
2701 };")
2703 ;; this test needs to be rewritten when named blocks are implemented!!!!
2704 (test-ps-js return-when-returns-broken-return
2705 (defun foo ()
2706 (return-from foo (when x 1))
2707 (+ 2 3))
2708 "function foo() {
2709 return x ? 1 : null;
2710 return 2 + 3;
2711 };")
2713 (test-ps-js return-case-conditional
2714 (defun foo ()
2715 (return-from foo
2716 (case foo
2717 (123 (when (bar) t))
2718 (345 (blah)))))
2719 "function foo() {
2720 switch (foo) {
2721 case 123:
2722 return bar() ? true : null;
2723 case 345:
2724 return blah();
2726 };")
2728 (test-ps-js return-try-conditional
2729 (defun foo ()
2730 (return-from foo
2731 (try (when x 1)
2732 (:catch (x) 2)
2733 (:finally (bar)))))
2734 "function foo() {
2735 try {
2736 return x ? 1 : null;
2737 } catch (x) {
2738 return 2;
2739 } finally {
2740 bar();
2742 };")
2744 (test-ps-js function-declare-special
2745 (lambda ()
2746 (declare (special *foo*))
2747 (let ((*foo* 1))
2748 (1+ *foo*)))
2749 "(function () {
2750 var FOO_TMPSTACK1;
2751 try {
2752 FOO_TMPSTACK1 = FOO;
2753 FOO = 1;
2754 return FOO + 1;
2755 } finally {
2756 FOO = FOO_TMPSTACK1;
2758 });")
2760 (test-ps-js declare-special-let
2761 (let ((*foo* 123))
2762 (declare (special *foo*))
2763 (blah))
2764 "(function () {
2765 var FOO_TMPSTACK1;
2766 try {
2767 FOO_TMPSTACK1 = FOO;
2768 FOO = 123;
2769 return blah();
2770 } finally {
2771 FOO = FOO_TMPSTACK1;
2773 })();")
2775 (test-ps-js declare-special-let*
2776 (let* ((*foo* 123) (*bar* (+ *foo* *bar*)))
2777 (declare (special *foo* *bar*))
2778 (blah))
2779 "(function () {
2780 var FOO_TMPSTACK1;
2781 try {
2782 FOO_TMPSTACK1 = FOO;
2783 FOO = 123;
2784 var BAR_TMPSTACK2;
2785 try {
2786 BAR_TMPSTACK2 = BAR;
2787 BAR = FOO + BAR;
2788 return blah();
2789 } finally {
2790 BAR = BAR_TMPSTACK2;
2792 } finally {
2793 FOO = FOO_TMPSTACK1;
2795 })();")
2797 (test-ps-js defun-multiple-declarations-around-docstring
2798 (defun foo (x y)
2799 (declare (ignorable x y))
2800 (declare (integer x) (float y))
2801 "Fooes X while barring Y."
2802 (declare (special *foo*) (special *bar*))
2803 (let ((*bar* (bar y)))
2804 (funcall *foo* x)))
2805 "/** Fooes X while barring Y. */
2806 function foo(x, y) {
2807 var BAR_TMPSTACK1;
2808 try {
2809 BAR_TMPSTACK1 = BAR;
2810 BAR = bar(y);
2811 return FOO(x);
2812 } finally {
2813 BAR = BAR_TMPSTACK1;
2815 };")
2817 (test-ps-js macro-null-toplevel
2818 (progn
2819 (defmacro macro-null-toplevel ()
2820 nil)
2821 (macro-null-toplevel))
2824 (test-ps-js define-symbol-macro-let
2825 (progn
2826 (define-symbol-macro test-symbol-macro 1)
2827 (let ((test-symbol-macro 2))
2828 (1+ test-symbol-macro))
2829 (1+ test-symbol-macro))
2830 "(function () {
2831 var testSymbolMacro1 = 2;
2832 return testSymbolMacro1 + 1;
2833 })();
2834 1 + 1;")
2836 (test-ps-js define-symbol-macro-flet
2837 (progn
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 "(function () {
2844 var testSymbolMacro1_1 = function () {
2845 return 2;
2847 foo(1);
2848 return testSymbolMacro1_1();
2849 })();
2850 bar(1);")
2852 (test compile-stream-nulls
2853 (is (string=
2855 (with-input-from-string (s "
2856 (defmacro macro-null-toplevel ()
2857 nil)
2858 (macro-null-toplevel)")
2859 (ps-compile-stream s)))))
2861 (test compile-stream1
2862 (is (string=
2863 "(function () {
2864 var testSymbolMacro1_1 = function () {
2865 return 2;
2867 foo(1);
2868 return testSymbolMacro1_1();
2869 })();
2870 bar(1);
2872 (with-input-from-string (s "
2873 (define-symbol-macro test-symbol-macro1 1)
2874 (flet ((test-symbol-macro1 () 2))
2875 (foo test-symbol-macro1)
2876 (test-symbol-macro1))
2877 (bar test-symbol-macro1)")
2878 (ps::with-blank-compilation-environment (ps-compile-stream s))))))
2880 (test-ps-js equality-nary1
2881 (let ((x 10) (y 10) (z 10))
2882 (= x y z))
2883 "(function () {
2884 var _cmp1;
2885 var x = 10;
2886 var y = 10;
2887 var z = 10;
2888 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
2889 })();")
2891 (test-ps-js equality1
2892 (progn
2893 (equal a b)
2894 (eql a b)
2895 (eq a b)
2896 (= a b))
2897 "a == b;
2898 a === b;
2899 a === b;
2900 a === b;")
2902 (test-ps-js getprop-quote-reserved
2903 (getprop foo ':break)
2904 "foo['break'];")
2906 (test-ps-js defun-block-return-from
2907 (defun foo (x)
2908 (baz 4)
2909 (return-from foo x)
2910 (bar 5))
2911 "function foo(x) {
2912 baz(4);
2913 return x;
2914 return bar(5);
2915 }; ")
2917 (test-ps-js block-return-from
2918 (block scope
2919 (foo)
2920 (when (bar)
2921 (return-from scope))
2922 (blee))
2923 "(function () {
2924 foo();
2925 if (bar()) {
2926 return null;
2928 return blee();
2929 })();")
2931 (test-ps-js block-return-from0
2932 (defun baz ()
2933 (block scope
2934 (foo)
2935 (when (bar)
2936 (return-from scope))
2937 (blee)))
2938 "function baz() {
2939 foo();
2940 if (bar()) {
2941 return null;
2943 return blee();
2944 };")
2946 (test-ps-js block-return-from01
2947 (defun baz ()
2948 (block scope
2949 (foo)
2950 (when (bar)
2951 (return-from scope))
2952 (blee))
2954 "function baz() {
2955 scope: {
2956 foo();
2957 if (bar()) {
2958 break scope;
2960 blee();
2962 return 2;
2963 };")
2965 (test-ps-js block-return-from02
2966 (defun baz ()
2967 (block scope
2968 (foo)
2969 (when (bar)
2970 (return-from scope (foobar)))
2971 (blee))
2973 "function baz() {
2974 scope: {
2975 foo();
2976 if (bar()) {
2977 foobar();
2978 break scope;
2980 blee();
2982 return 2;
2983 };")
2985 (test-ps-js block-return-from1
2986 (lambda ()
2987 (block scope
2988 (foo)
2989 (when (bar)
2990 (return-from scope))
2991 (blee))
2992 (+ 1 2))
2993 "(function () {
2994 scope: {
2995 foo();
2996 if (bar()) {
2997 break scope;
2999 blee();
3001 return 1 + 2;
3002 });")
3004 (test-ps-js block-return-from2
3005 (lambda ()
3006 (bar 5)
3007 (block scope
3008 (foo)
3009 (when (bar)
3010 (return-from scope 6))
3011 (blee)))
3012 "(function () {
3013 bar(5);
3014 foo();
3015 if (bar()) {
3016 return 6;
3018 return blee();
3019 });")
3021 (test-ps-js let-funcall
3022 (let ((x foo))
3023 (funcall x)
3024 (let ((x bar))
3025 (funcall x))
3026 (funcall x))
3027 "(function () {
3028 var x = foo;
3029 x();
3030 var x1 = bar;
3031 x1();
3032 return x();
3033 })();")
3035 (test-ps-js symbol-macrolet-funcall
3036 (symbol-macrolet ((foo bar))
3037 (funcall foo 1 2 3))
3038 "bar(1, 2, 3);")
3040 (test-ps-js times-assign
3041 (setf x (* x 1000))
3042 "x *= 1000;")
3044 (test-ps-js vector-literal
3045 #(1 2 3)
3046 "[1, 2, 3];")
3048 (test-ps-js rem1
3049 (+ 1 (rem 2 (+ 3 4)))
3050 "1 + 2 % (3 + 4);")
3052 (test-ps-js non-associative
3053 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3054 "1 / (2 / 3) + (1 - (2 - 3));")
3056 (test-ps-js lambda-apply
3057 (lambda (x)
3058 (apply (lambda (y) (bar (1+ y))) x))
3059 "(function (x) {
3060 return (function (y) {
3061 return bar(y + 1);
3062 }).apply(this, x);
3063 });")
3065 (test-ps-js operator-expressions-nested-let
3066 (let ((x (let ((y 1))
3067 y)))
3069 "(function () {
3070 var y;
3071 var x = (y = 1, y);
3072 return x;
3073 })();")
3075 (test-ps-js operator-expressions-array-nested-let
3076 (list (let ((y 1)) y) 2)
3077 "[(function () {
3078 var y = 1;
3079 return y;
3080 })(), 2];")
3082 (test-ps-js add-subtract-precedence
3083 (- x (+ y z))
3084 "x - (y + z);")
3086 (test-ps-js ps-inline-toplevel
3087 (ps-inline (foo))
3088 "'javascript:' + 'foo()';")
3090 (test-ps-js no-clause-progn-exp
3091 (setf x (progn))
3092 "x = null;")
3094 (test-ps-js no-clause-progn-return
3095 (defun foo ()
3096 (return-from foo (progn)))
3097 "function foo() {
3098 return null;
3099 };")
3101 (test-ps-js empty-cond-clause
3102 (setf x (cond ((foo))))
3103 "x = (function () { var testResult1 = foo(); return testResult1 ? testResult1 : null; })();")
3105 (test-ps-js empty-cond-clause1
3106 (setf x (cond ((foo) 123)
3107 ((bar))
3108 (t 456)))
3109 "x = foo() ? 123 :
3110 (function () {
3111 var testResult1 = bar();
3112 if (testResult1) {
3113 return testResult1;
3114 } else {
3115 if (true) { return 456; };
3117 })();")
3119 (test-ps-js let-no-body
3120 (defun foo ()
3121 (return-from foo (let ((foo bar)))))
3122 "function foo() {
3123 var foo1 = bar;
3124 return null;
3125 };")
3127 (test-ps-js rename-lexical-dupes
3128 (lambda ()
3129 (list (let ((foo 12)) (* foo 2))
3130 (let ((foo 13)) (* foo 3))))
3131 "(function () {
3132 var foo;
3133 var foo1;
3134 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3135 });")
3137 (test-ps-js defun-comment1
3138 (defun foo (x)
3139 "BARBAR is a revolutionary new foobar.
3140 X y and x."
3141 (1+ x))
3142 "/**
3143 * BARBAR is a revolutionary new foobar.
3144 * X y and x.
3146 function foo(x) {
3147 return x + 1;
3148 };")
3150 (test-ps-js var-comment
3151 (var x 1 "foo")
3152 "/** foo */
3153 var x = 1;")
3155 (test-ps-js case-return-break-broken-return
3156 (defun foo ()
3157 (case x
3158 ("bar" (if y (return-from foo t) nil))
3159 ("baz" nil)))
3160 "function foo() {
3161 switch (x) {
3162 case 'bar':
3163 if (y) {
3164 return true;
3165 } else {
3166 return null;
3168 case 'baz':
3169 return null;
3171 };")
3173 (test-ps-js case-return-break1-broken-return
3174 (defun foo ()
3175 (case x
3176 ("bar" (if y (return-from foo t)))
3177 ("baz" nil)))
3178 "function foo() {
3179 switch (x) {
3180 case 'bar':
3181 if (y) {
3182 return true;
3183 } else {
3184 return null;
3186 case 'baz':
3187 return null;
3189 };")
3191 (test-ps-js setf-progn
3192 (setf foo (progn (bar) (baz) 3))
3193 "bar();
3194 baz();
3195 foo = 3;")
3197 (test-ps-js var-progn
3198 (var x (progn (foo) (bar)))
3199 "foo();
3200 var x = bar();")
3202 (test-ps-js implicit-return-loop
3203 (lambda ()
3204 (if baz 7
3205 (progn
3206 (loop :repeat 100 :do (bar))
3207 42)))
3208 "(function () {
3209 if (baz) {
3210 return 7;
3211 } else {
3212 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3213 bar();
3215 return 42;
3217 });")
3219 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
3220 (test-ps-js loop-closures
3221 (dotimes (i 10) (lambda () (+ i 1)))
3222 "(function () {
3223 for (var i = 0; i < 10; i += 1) {
3224 with ({ i : i }) {
3225 function () {
3226 return i + 1;
3230 })();")
3232 (test-ps-js loop-closures-let
3233 (dotimes (i 10)
3234 (let ((x (+ i 1)))
3235 (lambda () (+ i x))))
3236 "(function () {
3237 for (var i = 0; i < 10; i += 1) {
3238 with ({ i : i, x : null }) {
3239 var x = i + 1;
3240 function () {
3241 return i + x;
3245 })();")
3247 (test-ps-js loop-closures-flet
3248 (dotimes (i 10) (flet ((foo (x) (+ i x))) (lambda () (foo i))))
3249 "(function () {
3250 for (var i = 0; i < 10; i += 1) {
3251 with ({ foo : null, i : i }) {
3252 var foo = function (x) {
3253 return i + x;
3255 function () {
3256 return foo(i);
3260 })();")
3262 (test-ps-js while-closures-let
3263 (while (foo)
3264 (let ((x (bar)))
3265 (lambda () (+ 1 x))))
3266 "while (foo()) {
3267 with ({ x : null }) {
3268 var x = bar();
3269 function () {
3270 return 1 + x;
3273 };")
3275 (test-ps-js dotted-list-form
3276 (defun foo (a)
3277 (when a
3278 (destructuring-bind (b . c)
3280 (list b c))))
3281 "function foo(a) {
3282 if (a) {
3283 var b = bar[0];
3284 var c = bar.length > 1 ? bar.slice(1) : [];
3285 return [b, c];
3287 };")
3289 (test-ps-js explicit-nil-block
3290 (defun bar ()
3291 (foo 1)
3292 (block nil (return (foo 2)) (+ 1 2))
3294 "function bar() {
3295 foo(1);
3296 nilBlock: {
3297 foo(2);
3298 break nilBlock;
3299 1 + 2;
3301 return 2;
3302 };")
3304 (test-ps-js dynamic-extent-function-return
3305 (defun foo ()
3306 ((lambda ()
3307 (return-from foo 6))))
3308 "function foo() {
3309 try {
3310 return (function () {
3311 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3312 })();
3313 } catch (_ps_err1) {
3314 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3315 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3316 return _ps_err1['__ps_value1'];
3317 } else {
3318 throw _ps_err1;
3321 };")
3323 (test-ps-js dynamic-extent-function-return-nothing
3324 (defun foo ()
3325 ((lambda ()
3326 (return-from foo))))
3327 "function foo() {
3328 try {
3329 return (function () {
3330 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3331 })();
3332 } catch (_ps_err1) {
3333 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3334 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3335 return _ps_err1['__ps_value1'];
3336 } else {
3337 throw _ps_err1;
3340 };")
3342 (test-ps-js dynamic-extent-function-return-values
3343 (defun foo ()
3344 ((lambda ()
3345 (return-from foo (values 1 2 3)))))
3346 "function foo() {
3347 try {
3348 __PS_MV_REG = {};
3349 return (function () {
3350 throw { '__ps_block_tag' : 'foo',
3351 '__ps_value1' : 1,
3352 '__ps_values' : [2, 3] };
3353 })();
3354 } catch (_ps_err1) {
3355 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3356 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3357 return _ps_err1['__ps_value1'];
3358 } else {
3359 throw _ps_err1;
3362 };")
3364 (test-ps-js dynamic-extent-function-return-funcall
3365 (defun foo ()
3366 ((lambda ()
3367 (return-from foo (if baz 6 5)))))
3368 "function foo() {
3369 try {
3370 return (function () {
3371 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3372 })();
3373 } catch (_ps_err1) {
3374 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3375 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3376 return _ps_err1['__ps_value1'];
3377 } else {
3378 throw _ps_err1;
3381 };")
3383 (test-ps-js block-dynamic-return
3384 (var foo ((lambda ()
3385 (block nil
3386 ((lambda () (return 6)))
3387 (+ 1 2)))))
3388 "var foo = (function () {
3389 try {
3390 (function () {
3391 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3392 })();
3393 return 1 + 2;
3394 } catch (_ps_err1) {
3395 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3396 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3397 return _ps_err1['__ps_value1'];
3398 } else {
3399 throw _ps_err1;
3402 })();")
3404 (test-ps-js block-dynamic-return1
3405 (var foo ((lambda ()
3406 (block nil
3407 ((lambda () (return 6)))
3408 (+ 1 2))
3409 (foobar 1 2))))
3410 "var foo = (function () {
3411 nilBlock: {
3412 (function () {
3413 break nilBlock;
3414 })();
3415 1 + 2;
3417 return foobar(1, 2);
3418 })();")
3420 (test-ps-js iteration-lambda-capture-no-need
3421 (dolist (x y) (lambda (x) (1+ x))) ;; there's really no need to create a 'with' scope in this case
3422 "(function () {
3423 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3424 with ({ x : x }) {
3425 x = y[_js_idx1];
3426 function (x) {
3427 return x + 1;
3431 })();")
3433 (test-ps-js case-invert1
3434 (encodeURIComponent fooBar)
3435 "encodeURIComponent(fooBar);")
3437 (test-ps-js simple-ash
3438 (+ (ash 4 1) (ash 4 -1))
3439 "(4 << 1) + (4 >> 1);")
3441 (test-ps-js progn-nil-expression
3442 (bar (progn (foo) nil))
3443 "bar((foo(), null));")
3445 (test-ps-js other-progn-nil-exp
3446 (defun blah ()
3447 (or (foo) (progn (bar) nil)))
3448 "function blah() {
3449 return foo() || (bar(), null);
3450 };")
3452 (test-ps-js lambda-nil-return
3453 (lambda (x)
3454 (block nil
3455 (when x
3456 (return 1))
3458 "(function (x) {
3459 if (x) {
3460 return 1;
3462 return 2;
3463 });")
3465 (test-ps-js lambda-nil-return-implicit-nested2
3466 (lambda (x)
3467 (block foo
3468 (if x
3469 (return-from foo 1)
3470 (dotimes (i 4)
3471 (return-from foo i)))
3473 "(function (x) {
3474 if (x) {
3475 return 1;
3476 } else {
3477 for (var i = 0; i < 4; i += 1) {
3478 return i;
3481 return 2;
3482 });")
3484 (test-ps-js throw-is-a-statement
3485 (defun blah ()
3486 (let ((result (foo)))
3487 (unless (null result)
3488 (throw result))))
3489 "function blah() {
3490 var result = foo();
3491 if (result != null) {
3492 throw result;
3494 };")
3496 (test-ps-js expressify1
3497 (defun blah ()
3498 (when (some-condition)
3499 (foo)
3500 (bar)
3501 (baz)))
3502 "function blah() {
3503 if (someCondition()) {
3504 foo();
3505 bar();
3506 return baz();
3508 };")
3510 (test-ps-js case-when-return
3511 (defun blah (a)
3512 (case a
3513 ("a" (when (foo) (return-from blah 111)))
3514 ("b" t)))
3515 "function blah(a) {
3516 switch (a) {
3517 case 'a':
3518 if (foo()) {
3519 return 111;
3520 } else {
3521 return null;
3523 case 'b':
3524 return true;
3526 };")
3528 (test-ps-js flet-return-from
3529 (defun abc ()
3530 (flet ((foo ()
3531 (return-from foo 123)))
3532 (foo)))
3533 "function abc() {
3534 var foo = function () {
3535 return 123;
3537 return foo();
3538 };")
3540 (test-ps-js flet-return-from1
3541 (flet ((foo ()
3542 (return-from foo 123)))
3543 (foo))
3544 "(function () {
3545 var foo = function () {
3546 return 123;
3548 return foo();
3549 })();")
3551 (test-ps-js lambda-docstring-declarations
3552 (lambda (x)
3553 "This is a docstring"
3554 (declare (ignore x))
3556 "(function (x) {
3557 return 2;
3558 });")
3560 (test-ps-js setf-let-exp
3561 (setf foo (let ((x (+ 1 2)))
3562 (if x 123 456)))
3563 "foo = (function () {
3564 var x = 1 + 2;
3565 return x ? 123 : 456;
3566 })();")
3568 (test-ps-js create-let-exp
3569 (create :abc (let ((x (+ 1 2)))
3570 (if x 123 456)))
3571 "({ 'abc' : (function () {
3572 var x = 1 + 2;
3573 return x ? 123 : 456;
3574 })() });")
3576 (test-ps-js eql-eql-eql-precedence
3577 (unless (equal (= 3 3) (= 3 4))
3578 (chain console (log 1)))
3579 "if ((3 === 3) != (3 === 4)) {
3580 console.log(1);
3581 };")
3583 (test-ps-js case-cond-breaks
3584 (defun blah (x)
3585 (case x
3586 (123 (cond ((foo1)
3587 (when (foo2)
3588 (when (foo3)
3589 (return-from blah nil))
3590 t))))
3591 (456 (foo7))))
3592 "function blah(x) {
3593 switch (x) {
3594 case 123:
3595 if (foo1()) {
3596 if (foo2()) {
3597 if (foo3()) {
3598 return null;
3600 return true;
3601 } else {
3602 return null;
3604 } else {
3605 return null;
3607 case 456:
3608 return foo7();
3610 };")
3612 (test-ps-js cond-double-t
3613 (lambda ()
3614 (cond (foo 1)
3615 (t 2)
3616 (t 3)))
3617 "(function () {
3618 if (foo) {
3619 return 1;
3620 } else {
3621 return 2;
3623 });")
3625 (test-ps-js let-let-funcall-lambda
3626 (let ((x 5))
3627 (let ((x 7))
3628 (funcall (lambda (x) (+ x 9)) x)))
3629 "(function () {
3630 var x = 5;
3631 var x1 = 7;
3632 return (function (x) {
3633 return x + 9;
3634 })(x1);
3635 })();")
3637 (test-ps-js let-let-lambda
3638 (let ((x 5))
3639 (let ((x 7))
3640 (lambda (x) (+ x 9))))
3641 "(function () {
3642 var x = 5;
3643 var x1 = 7;
3644 return function (x) {
3645 return x + 9;
3647 })();")
3649 (test-ps-js let-lambda
3650 (let ((x 5))
3651 (lambda (x) (+ x 9)))
3652 "(function () {
3653 var x = 5;
3654 return function (x) {
3655 return x + 9;
3657 })();")
3659 (test-ps-js symbol-macrolet-no-shadow-lambda
3660 (symbol-macrolet ((x y))
3661 (lambda (x) (+ x x)))
3662 "(function (x) {
3663 return x + x;
3664 });")
3666 (test-ps-js divide-one-arg-reciprocal
3667 (/ 2)
3668 "1 / 2;")
3670 (test-ps-js division-not-associative
3671 (/ a (* b c))
3672 "a / (b * c);")
3674 (test-ps-js divide-expressions
3675 (/ (foo) (bar))
3676 "foo() / bar();")
3678 (test-ps-js divide-expressions1
3679 (floor (1- x) y)
3680 "Math.floor((x - 1) / y);")
3682 (test-ps-js lexical-funargs-shadow1
3683 (lambda (x)
3684 (let ((x 1))
3685 (foo x))
3686 (incf x))
3687 "(function (x) {
3688 var x1 = 1;
3689 foo(x1);
3690 return ++x;
3691 });")
3693 (test-ps-js times-rem
3694 (* x (rem y z))
3695 "x * (y % z);")
3697 (test-ps-js rem-divide
3698 (/ x (rem y z))
3699 "x / (y % z);")
3701 (test-ps-js case-break-return
3702 (lambda () (case x (:foo) (:bar 1)))
3703 "(function () {
3704 switch (x) {
3705 case 'foo':
3706 return null;
3707 case 'bar':
3708 return 1;
3710 });")
3712 (test-ps-js trivial-expression-switch
3713 (foobar (case x (1 2)))
3714 "foobar((function () {
3715 switch (x) {
3716 case 1:
3717 return 2;
3719 })());")
3721 (test-ps-js trivial-expression-while
3722 (foobar (while (< 0 x) (decf x)))
3723 "foobar((function () {
3724 while (0 < x) {
3725 --x;
3727 })());")
3729 (test-ps-js funcall-block-expression-loop-lambda
3730 (foobar (loop for i from 0 to 10 do (1+ i)))
3731 "foobar((function () {
3732 for (var i = 0; i <= 10; i += 1) {
3733 i + 1;
3735 })());")
3737 (test-ps-js plus-block-expression-loop-lambda
3738 (1+ (loop for i from 0 to 10 do (1+ i)))
3739 "(function () {
3740 for (var i = 0; i <= 10; i += 1) {
3741 i + 1;
3743 })() + 1;")
3745 (test-ps-js let-closures-rename
3746 (lambda ()
3747 (let ((x 1)) (lambda () (1+ x)))
3748 (let ((x 2)) (lambda () (1+ x))))
3749 "(function () {
3750 var x = 1;
3751 function () {
3752 return x + 1;
3754 var x1 = 2;
3755 return function () {
3756 return x1 + 1;
3758 });")
3760 (test-ps-js let-closures-rename1
3761 (lambda ()
3762 (let ((x 1))
3763 (let ((y 2))
3764 (lambda () (+ x y))))
3765 (let ((x 2))
3766 (let ((y 3))
3767 (lambda () (+ x y)))))
3768 "(function () {
3769 var x = 1;
3770 var y = 2;
3771 function () {
3772 return x + y;
3774 var x1 = 2;
3775 var y2 = 3;
3776 return function () {
3777 return x1 + y2;
3779 });")
3781 (test-ps-js let-closures-rename2
3782 (defun make-closures ()
3783 (list
3784 (let ((x 1)) (lambda () (1+ x)))
3785 (let ((x 2)) (lambda () (1+ x)))))
3786 "function makeClosures() {
3787 var x;
3788 var x1;
3789 return [(x = 1, function () {
3790 return x + 1;
3791 }), (x1 = 2, function () {
3792 return x1 + 1;
3793 })];
3795 };")
3797 (test-ps-js conditional-not-used-up
3798 (lambda (bar)
3799 (when bar
3800 (let ((x 1))
3801 (1+ x))))
3802 "(function (bar) {
3803 if (bar) {
3804 var x = 1;
3805 return x + 1;
3807 });")
3809 (test-ps-js toplevel-local-scope
3810 (create "fn" (let ((x 5)) (lambda () x)))
3811 "({ 'fn' : (function () {
3812 var x = 5;
3813 return function () {
3814 return x;
3816 })() });")
3818 (test-ps-js toplevel-local-scope1
3819 (defvar foo (create "fn" (let ((x 5)) (lambda () x))))
3820 "var foo = { 'fn' : (function () {
3821 var x = 5;
3822 return function () {
3823 return x;
3825 })() };")
3827 (test-ps-js block-let
3828 (block foobar
3829 (let ((x 1))
3830 (return-from foobar x)
3832 "(function () {
3833 var x = 1;
3834 return x;
3835 return 2;
3836 })();")
3838 (test-ps-js expressionize-if-macroexpand-error
3839 (progn (defmacro xbaz () `(blah))
3841 (defun foo (xbaz)
3842 (unless (blah)
3843 (cond (xbaz (blah))
3844 (t (blahblah))))))
3845 "function foo(xbaz) {
3846 if (!blah()) {
3847 if (xbaz) {
3848 return blah();
3849 } else {
3850 return blahblah();
3853 };")
3855 (test-ps-js toplevel-defun-macroexpand
3856 (progn (defmacro defun-js (name lambda-list &body body)
3857 `(defun ,name ,lambda-list ,@body))
3859 (let ((foo 0))
3860 (defun-js bar () (1+ foo))
3861 (defvar baz 2)))
3862 "var foo = 0;
3863 function bar() {
3864 return foo + 1;
3866 var baz = 2;")
3868 (test-ps-js js-ir-package-unique-symbols
3869 (loop :for i :from 0 :below 5 :do
3870 (let ((block (elt blocks i)))
3871 (foo block)
3872 (lambda () nil)))
3873 "(function () {
3874 for (var i = 0; i < 5; i += 1) {
3875 var block = blocks[i];
3876 foo(block);
3877 function () {
3878 return null;
3881 })();")
3883 (test-ps-js broken-quote-expansion1
3884 (lambda (p)
3885 (with-slots (x y) p
3886 (if (< x 0) y x)))
3887 "(function (p) {
3888 return p.x < 0 ? p.y : p.x;
3889 });")
3891 (test-ps-js broken-quote-expansion2
3892 (progn
3893 (define-symbol-macro foo123 (ps:@ a foo123))
3894 (lambda () (when (> foo123 1) 2)))
3895 "(function () {
3896 return a.foo123 > 1 ? 2 : null;
3897 });")
3899 (test-ps-js unused-named-block-not-printed1
3900 (block foobar
3901 (+ 1 2 3))
3902 "(function () {
3903 return 1 + 2 + 3;
3904 })();")
3906 (test-ps-js unused-named-block-not-printed2
3907 (block nil
3908 (block nil
3909 (+ 1 2 3)))
3910 "(function () {
3911 return 1 + 2 + 3;
3912 })();")
3914 (test-ps-js unused-named-block-not-printed3
3915 (block foobar
3916 (block nil
3917 (+ 1 2 3)))
3918 "(function () {
3919 return 1 + 2 + 3;
3920 })();")
3922 (test-ps-js unused-named-block-not-printed4
3923 (block nil
3924 (block foobar
3925 (block nil
3926 (+ 1 2 3))))
3927 "(function () {
3928 return 1 + 2 + 3;
3929 })();")
3931 (test-ps-js trig-no-bind1
3932 (cosh 3.14)
3933 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
3935 (test-ps-js trig-bind1
3936 (acosh (blah 3.14))
3937 "(function () {
3938 var x1 = blah(3.14);
3939 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
3940 })();")
3942 ;;; broken
3944 ;; (test-ps-js let-defun-toplevel
3945 ;; (progn (let ((foo 0))
3946 ;; (defun bar () foo))
3947 ;; (bar))
3948 ;; "var bar_foo1 = 0;
3949 ;; function bar() {
3950 ;; return bar_foo1;
3951 ;; };
3952 ;; bar();")
3954 ;; (test-ps-js let-defvar-toplevel
3955 ;; (progn (let ((foo 0))
3956 ;; (defvar bar (1+ foo)))
3957 ;; bar)
3958 ;; "var bar_foo1 = 0;
3959 ;; var bar = bar_foo1 + 1;
3960 ;; bar;")
3962 ;; (test-ps-js setf-side-effects
3963 ;; (progn
3964 ;; (let ((x 10))
3965 ;; (defun side-effect()
3966 ;; (setf x 4)
3967 ;; 3)
3968 ;; (setf x (+ 2 (side-effect) x 5))))
3969 ;; "var sideEffect_x1 = 10;
3970 ;; function sideEffect() {
3971 ;; sideEffect_x1 = 4;
3972 ;; return 3;
3973 ;; };
3974 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")