Fixed output test trig-bind1 to be consistent between Lisps that know that (floor...
[parenscript.git] / t / output-tests.lisp
blob361cd8b7b966ef9d4527ef678a43174465134315
1 ;; Copying and distribution of this file, with or without
2 ;; modification, are permitted in any medium without royalty. This
3 ;; file is offered as-is, without any warranty.
5 (in-package #:ps-test)
6 (named-readtables:in-readtable :parenscript)
8 (in-suite output-tests)
10 (test-ps-js statements-and-expressions-1
11 (+ i (if 1 2 3))
12 "i + (1 ? 2 : 3);")
14 (test-ps-js statements-and-expressions-2
15 (if 1 2 3)
16 "if (1) {
18 } else {
20 };")
22 (test-ps-js symbol-conversion-1
23 !?#@%
24 "bangwhathashatpercent;")
26 (test-ps-js symbol-conversion-2
27 bla-foo-bar
28 "blaFooBar;")
30 (test-ps-js symbol-conversion-3
31 *array
32 "Array;")
34 (test-ps-js symbol-conversion-4
35 *global-array*
36 "GLOBALARRAY;")
38 (test-ps-js symbol-conversion-5
39 encodeURIComponent
40 "encodeURIComponent;")
42 (test-ps-js symbol-conversion-6
43 URI
44 "URI;")
46 (test-ps-js number-literals-1
48 "1;")
50 (test-ps-js number-literals-2
51 123.123
52 "123.123;")
54 (test-ps-js number-literals-3
55 #x10
56 "16;")
58 (test-ps-js string-literals-1
59 "foobar"
60 "'foobar';")
62 (test-ps-js string-literals-2
63 "bratzel bub"
64 "'bratzel bub';")
66 (test-ps-js string-literals-3
67 " "
68 "'\\t';")
70 (test-ps-js array-literals-1
71 (array)
72 "[ ];")
74 (test-ps-js array-literals-2
75 (array 1 2 3)
76 "[ 1, 2, 3 ];")
78 (test-ps-js array-literals-3
79 (array (array 2 3)
80 (array "foobar" "bratzel bub"))
81 "[ [ 2, 3 ], [ 'foobar', 'bratzel bub' ] ];")
83 (test-ps-js array-literals-4
84 (make-array)
85 "new Array();")
87 (test-ps-js array-literals-5
88 (make-array 1 2 3)
89 "new Array(1, 2, 3);")
91 (test-ps-js array-literals-6
92 (make-array
93 (make-array 2 3)
94 (make-array "foobar" "bratzel bub"))
95 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
97 (test-ps-js array-init-1
98 (make-array 2 :initial-contents '(10 20))
99 "(function () {
100 var arr1 = new Array(2);
101 var init2 = [10, 20];
102 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
103 arr1[i4] = init2[i4];
105 return arr1;
106 })();")
108 (test-ps-js array-init-2
109 (make-array 5 :initial-element 10)
110 "(function () {
111 var arr1 = new Array(5);
112 var elt3 = 10;
113 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
114 arr1[i4] = elt3;
116 return arr1;
117 })();")
119 (test-ps-js object-literals-1
120 (create foo "bar" :blorg 1)
121 "({ foo : 'bar', 'blorg' : 1 });")
123 (test-ps-js object-literals-2
124 (create foo "hihi"
125 blorg (array 1 2 3)
126 another-object (create :schtrunz 1))
127 "({ foo : 'hihi',
128 blorg : [ 1, 2, 3 ],
129 anotherObject : { 'schtrunz' : 1 } });")
131 (test-ps-js object-literals-3
132 (getprop an-object 'foo)
133 "anObject.foo;")
135 (test-ps-js object-literals-4
136 (@ an-object foo bar)
137 "anObject.foo.bar;")
139 (test-ps-js object-literals-5
140 (with-slots (a b c) this
141 (+ a b c))
142 "this.a + this.b + this.c;")
144 (test-ps-js object-literal-quoted-symbols
145 (create 'test "bang" 'symbol-saved-my-life "parenscript")
146 "({ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' });")
148 (test-ps-js object-method-apply-1
149 (apply (@ an-object foo) nil)
150 "anObject.foo.apply(anObject, null);")
152 (test-ps-js object-method-apply-2
153 (apply (getprop (make-an-object) foo 'bar) nil)
154 "(function () {
155 var _js1 = makeAnObject()[foo];
156 var _js2 = _js1.bar;
157 return _js2.apply(_js1, null);
158 })();")
160 (test-ps-js object-method-apply-3
161 (apply (@ (make-an-object) foo) (bar))
162 "(function () {
163 var _js1 = makeAnObject();
164 var _js2 = _js1.foo;
165 return _js2.apply(_js1, bar());
166 })();")
168 (test-ps-js regular-expression-literals-1
169 (regex "foobar")
170 "/foobar/;")
172 (test-ps-js regular-expression-literals-2
173 (regex "/foobar/i")
174 "/foobar/i;")
176 (test-ps-js literal-symbols-1
178 "true;")
180 (test-ps-js literal-symbols-2
181 false
182 "false;")
184 (test-ps-js literal-symbols-3
186 "false;")
188 (test-ps-js literal-symbols-4
189 (lambda () nil)
190 "(function () {
191 return null;
192 });")
194 (test-ps-js literal-symbols-5
195 undefined
196 "undefined;")
198 (test-ps-js literal-symbols-6
199 this
200 "this;")
202 (test-ps-js variables-1
203 variable
204 "variable;")
206 (test-ps-js variables-2
207 a-variable
208 "aVariable;")
210 (test-ps-js variables-3
211 *math
212 "Math;")
214 (test-ps-js function-calls-and-method-calls-1
215 (blorg 1 2)
216 "blorg(1, 2);")
218 (test-ps-js function-calls-and-method-calls-2
219 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
220 "foobar(blorg(1, 2), blabla(3, 4), [ 2, 3, 4 ]);")
222 (test-ps-js function-calls-and-method-calls-3
223 ((getprop this 'blorg) 1 2)
224 "this.blorg(1, 2);")
226 (test-ps-js function-calls-and-method-calls-4
227 ((aref foo i) 1 2)
228 "foo[i](1, 2);")
230 (test-ps-js function-calls-and-method-calls-5
231 ((getprop (aref foobar 1) 'blorg) nil t)
232 "foobar[1].blorg(null, true);")
234 (test-ps-js operator-expressions-1
235 (* 1 2)
236 "1 * 2;")
238 (test-ps-js operator-expressions-2
239 (= 1 2)
240 "1 === 2;")
242 (test-ps-js operator-expressions-3
243 (* 1 (+ 2 3 4) 4 (/ 6 7))
244 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
246 (test-ps-js operator-expressions-4
247 (incf i)
248 "++i;")
250 (test-ps-js operator-expressions-5
251 (decf i)
252 "--i;")
254 (test-ps-js operator-expressions-6
255 (1- i)
256 "i - 1;")
258 (test-ps-js operator-expressions-7
259 (1+ i)
260 "i + 1;")
262 (test-ps-js operator-expressions-8
263 (not (< i 2))
264 "i >= 2;")
266 (test-ps-js body-forms-1
267 (progn (blorg i) (blafoo i))
268 "blorg(i);
269 blafoo(i);")
271 (test-ps-js body-forms-2
272 (+ i (progn (blorg i) (blafoo i)))
273 "i + (blorg(i), blafoo(i));")
275 (test-ps-js function-definition-1
276 (defun a-function (a b)
277 (+ a b))
278 "function aFunction(a, b) {
279 return a + b;
280 };")
282 (test-ps-js lambda-definition-2
283 (lambda (a b) (+ a b))
284 "(function (a, b) {
285 return a + b;
286 });")
288 (test-ps-js assignment-1
289 (setf a 1)
290 "a = 1;")
292 (test-ps-js assignment-2
293 (setf a 2 b 3 c 4 x (+ a b c))
294 "a = 2;
295 b = 3;
296 c = 4;
297 x = a + b + c;")
299 (test-ps-js assignment-3
300 (setf a (+ a 2 3 4 a))
301 "a = a + 2 + 3 + 4 + a;")
303 (test-ps-js assignment-4
304 (setf a (- 1 a))
305 "a = 1 - a;")
307 (test-ps-js assignment-5
308 (let ((a 1) (b 2))
309 (psetf a b b a))
310 "(function () {
311 var a = 1;
312 var b = 2;
313 var _js3 = b;
314 var _js4 = a;
315 a = _js3;
316 return b = _js4;
317 })();")
319 (test-ps-js assignment-6
320 (setq a 1)
321 "a = 1;")
323 (test-ps-js assignment-8
324 (progn
325 (defun (setf color) (new-color el)
326 (setf (getprop (getprop el 'style) 'color) new-color))
327 (setf (color some-div) (+ 23 "em")))
328 "function __setf_color(newColor, el) {
329 return el.style.color = newColor;
331 __setf_color(23 + 'em', someDiv);")
333 (test-ps-js assignment-10
334 (progn
335 (defsetf left (el) (offset)
336 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
337 (setf (left some-div) (+ 123 "px")))
338 "(function () {
339 var _js2 = someDiv;
340 var _js1 = 123 + 'px';
341 return _js2.style.left = _js1;
342 })();")
344 (test-ps-js assignment-12
345 (macrolet ((left (el)
346 `(getprop ,el 'offset-left)))
347 (left some-div))
348 "someDiv.offsetLeft;")
350 (test-ps-js nil-block-return-1
351 (block nil (return) 1)
352 "(function () {
353 return null;
354 return 1;
355 })();")
357 (test-ps-js single-argument-statements-2
358 (throw "foobar")
359 "throw 'foobar';")
361 (test-ps-js single-argument-expression-1
362 (delete (new (*foobar 2 3 4)))
363 "delete new Foobar(2, 3, 4);")
365 (test-ps-js single-argument-expression-2
366 (if (= (typeof blorg) *string)
367 (alert (+ "blorg is a string: " blorg))
368 (alert "blorg is not a string"))
369 "if (typeof blorg === String) {
370 alert('blorg is a string: ' + blorg);
371 } else {
372 alert('blorg is not a string');
373 };")
375 (test-ps-js conditional-statements-1
376 (defun foo ()
377 (if ((@ blorg is-correct))
378 (progn (carry-on) (return-from foo i))
379 (alert "blorg is not correct!")))
380 "function foo() {
381 if (blorg.isCorrect()) {
382 carryOn();
383 return i;
384 } else {
385 return alert('blorg is not correct!');
387 };")
389 (test-ps-js conditional-statements-2
390 (+ i (if ((@ blorg add-one)) 1 2))
391 "i + (blorg.addOne() ? 1 : 2);")
393 (test-ps-js conditional-statements-3
394 (defun foo ()
395 (when ((@ blorg is-correct))
396 (carry-on)
397 (return-from foo i)))
398 "function foo() {
399 if (blorg.isCorrect()) {
400 carryOn();
401 return i;
403 };")
405 (test-ps-js conditional-statements-4
406 (unless ((@ blorg is-correct))
407 (alert "blorg is not correct!"))
408 "if (!blorg.isCorrect()) {
409 alert('blorg is not correct!');
410 };")
412 (test-ps-js variable-declaration-1
413 (defvar *a* (array 1 2 3))
414 "var A = [ 1, 2, 3 ];")
416 (test-ps-js variable-declaration-2
417 (progn (defvar *a* 4)
418 (let ((x 1)
419 (*a* 2))
420 (let* ((y (+ x 1))
421 (x (+ x y)))
422 (+ *a* x y))))
423 "var A = 4;
424 (function () {
425 var x = 1;
426 var A_TMPSTACK1;
427 try {
428 A_TMPSTACK1 = A;
429 A = 2;
430 var y = x + 1;
431 var x2 = x + y;
432 return A + x2 + y;
433 } finally {
434 A = A_TMPSTACK1;
436 })();")
438 (test-ps-js iteration-constructs-1
439 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
440 (d 0 (1+ d))
441 (e (aref c d) (aref c d)))
442 ((or (= d (@ c length)) (string= e "x")))
443 (setf a d b e)
444 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
445 "(function () {
446 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
447 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
448 a = d;
449 b = e;
450 document.write('a: ' + a + ' b: ' + b + '<br/>');
452 })();")
454 (test-ps-js iteration-constructs-2
455 (do ((i 0 (1+ i))
456 (s 0 (+ s i (1+ i))))
457 ((> i 10))
458 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
459 "(function () {
460 var i = 0;
461 var s = 0;
462 for (; i <= 10; ) {
463 document.write('i: ' + i + ' s: ' + s + '<br/>');
464 var _js1 = i + 1;
465 var _js2 = s + i + (i + 1);
466 i = _js1;
467 s = _js2;
469 })();")
471 (test-ps-js iteration-constructs-3
472 (do* ((i 0 (1+ i))
473 (s 0 (+ s i (1- i))))
474 ((> i 10))
475 ((@ document write) (+ "i: " i " s: " s "<br/>")))
476 "(function () {
477 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
478 document.write('i: ' + i + ' s: ' + s + '<br/>');
480 })();")
482 (test-ps-js iteration-constructs-4
483 (let ((arr (array "a" "b" "c" "d" "e")))
484 (dotimes (i (@ arr length))
485 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
486 "(function () {
487 var arr = ['a', 'b', 'c', 'd', 'e'];
488 for (var i = 0; i < arr.length; i += 1) {
489 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
491 })();")
493 (test-ps-js iteration-constructs-5
494 (let ((res 0))
495 (alert (+ "Summation to 10 is "
496 (dotimes (i 10 res)
497 (incf res (1+ i))))))
498 "(function () {
499 var res = 0;
500 return alert('Summation to 10 is ' + (function () {
501 for (var i = 0; i < 10; i += 1) {
502 res += i + 1;
504 return res;
505 })());
506 })();")
508 (test-ps-js iteration-constructs-6
509 (let ((l (list 1 2 4 8 16 32)))
510 (dolist (c l)
511 ((@ document write) (+ "c: " c "<br/>"))))
512 "(function () {
513 var l = [1, 2, 4, 8, 16, 32];
514 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
515 c = l[_js_idx2];
516 document.write('c: ' + c + '<br/>');
518 })();")
520 (test-ps-js iteration-constructs-7
521 (let ((l '(1 2 4 8 16 32))
522 (s 0))
523 (alert (+ "Sum of " l " is: "
524 (dolist (c l s)
525 (incf s c)))))
526 "(function () {
527 var l = [1, 2, 4, 8, 16, 32];
528 var s = 0;
529 return alert('Sum of ' + l + ' is: ' + (function () {
530 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
531 c = l[_js_idx1];
532 s += c;
534 return s;
535 })());
536 })();")
538 (test-ps-js iteration-constructs-8
539 (let ((obj (create a 1 b 2 c 3)))
540 (for-in (i obj)
541 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
542 "(function () {
543 var obj = { a : 1, b : 2, c : 3 };
544 for (var i in obj) {
545 document.write(i + ': ' + obj[i] + '<br/>');
547 })();")
549 (test-ps-js iteration-constructs-9
550 (while ((@ film is-not-finished))
551 ((@ this eat) (new *popcorn)))
552 "while (film.isNotFinished()) {
553 this.eat(new Popcorn);
554 };")
556 (test-ps-js loop-for-bindings
557 (loop :for ((a b) (:c :d)) :in arr :do (foo a b c d))
558 "(function () {
559 var _js2 = arr.length;
560 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
561 var _db4 = arr[_js1];
562 var _db5 = _db4[0];
563 var a = _db5[0];
564 var b = _db5[1];
565 var _js3 = _db4[1];
566 var c = _js3['c'];
567 var d = _js3['d'];
568 foo(a, b, c, d);
570 })();")
572 (test-ps-js loop-for-on
573 (loop :for (k v) :on plist :by 2 :do (foo k v))
574 "(function () {
575 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
576 var k = _js1[0];
577 var v = _js1[1];
578 foo(k, v);
580 })();")
582 (test-ps-js loop-for-keys-of
583 (loop :for k :of obj :do (foo k))
584 "(function () {
585 for (var k in obj) {
586 foo(k);
588 })();")
590 (test-ps-js loop-for-key-val-pairs-of
591 (loop :for (k v) :of obj :do (foo k v))
592 "(function () {
593 for (var k in obj) {
594 var v = obj[k];
595 foo(k, v);
597 })();")
599 (test-ps-js loop-for-key-val-pairs-of-with-bindings
600 (loop :for (k (a b)) :of obj :do (foo k a b))
601 "(function () {
602 for (var k in obj) {
603 var _db1 = obj[k];
604 var a = _db1[0];
605 var b = _db1[1];
606 foo(k, a, b);
608 })();")
610 (test-ps-js loop-for-just-vals-of
611 (loop :for (nil v) :of obj :do (foo k v))
612 "(function () {
613 for (var _js1 in obj) {
614 var v = obj[_js1];
615 foo(k, v);
617 })();")
619 (test-ps-js loop-map-to
620 (loop :for str :in strs :map str :to (length str))
621 "(function () {
622 var _js2 = strs.length;
623 var map3 = { };
624 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
625 var str = strs[_js1];
626 map3[str] = str.length;
628 return map3;
629 })();")
631 (test-ps-js loop-for-of-map-to
632 (loop :for k :of obj :map k :to (foo k))
633 "(function () {
634 var map1 = { };
635 for (var k in obj) {
636 map1[k] = foo(k);
638 return map1;
639 })();")
641 (test-ps-js loop-for-of-when
642 (loop :for k :of obj :when (foo k) :map k :to (bar k))
643 "(function () {
644 var map1 = { };
645 for (var k in obj) {
646 if (foo(k)) {
647 map1[k] = bar(k);
650 return map1;
651 })();")
653 (test-ps-js loop-for-in-until-when
654 (loop :for a :in b :until (> a 100) :when (< a 50) :do (foo a))
655 "(function () {
656 var _js2 = b.length;
657 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
658 var a = b[_js1];
659 if (a > 100) {
660 break;
662 if (a < 50) {
663 foo(a);
666 })();")
668 (test-ps-js loop-with-for-when
669 (loop :with c = c1 :for d :from c1 :below c2
670 :when (foo c d) :do (setf c d)
671 :do (bar d))
672 "(function () {
673 var c = c1;
674 for (var d = c1; d < c2; d += 1) {
675 if (foo(c, d)) {
676 c = d;
678 bar(d);
680 })();")
682 (test-ps-js loop-for-then-for-in-while
683 (defun blah (c)
684 (loop :for a = (foo) :then (bar) :for b :in c :while b :do (foo a b c)))
685 "function blah(c) {
686 var _js2 = c.length;
687 var FIRST3 = true;
688 for (var a = foo(); true; a = bar()) {
689 var _js1 = FIRST3 ? 0 : _js1 + 1;
690 if (_js1 >= _js2) {
691 break;
693 var b = c[_js1];
694 if (!b) {
695 break;
697 foo(a, b, c);
698 FIRST3 = null;
700 };")
702 (test-ps-js loop-while-when
703 (loop :for a = (pop stack) :while a :for (b c) = (foo a) :when b :do (bar c))
704 "(function () {
705 for (var a = pop(stack); a; a = pop(stack)) {
706 var _db1 = foo(a);
707 var b = _db1[0];
708 var c = _db1[1];
709 if (b) {
710 bar(c);
713 })();")
715 (test-ps-js loop-for-of-for-in
716 (defun blah (obj b)
717 (loop :for k :of obj :for a :in b :do (foo k a)))
718 "function blah(obj, b) {
719 var _js2 = b.length;
720 var FIRST3 = true;
721 for (var k in obj) {
722 var _js1 = FIRST3 ? 0 : _js1 + 1;
723 if (_js1 >= _js2) {
724 break;
726 var a = b[_js1];
727 foo(k, a);
728 FIRST3 = null;
730 };")
732 (test-ps-js loop-for-dot
733 (loop :for (op . args) :in expr :do (foo op args))
734 "(function () {
735 var _js2 = expr.length;
736 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
737 var _db3 = expr[_js1];
738 var op = _db3[0];
739 var args = _db3.length > 1 ? _db3.slice(1) : [];
740 foo(op, args);
742 })();")
744 (test-ps-js loop-for-rest
745 (loop :for (op &rest args) :in expr :do (foo op args))
746 "(function () {
747 var _js2 = expr.length;
748 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
749 var _db3 = expr[_js1];
750 var op = _db3[0];
751 var args = _db3.length > 1 ? _db3.slice(1) : [];
752 foo(op, args);
754 })();")
756 (test-ps-js loop-collect
757 (setf x (loop :for a :in b :collect (foo a)))
758 "x = (function () {
759 var _js2 = b.length;
760 var collect3 = [];
761 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
762 var a = b[_js1];
763 collect3['push'](foo(a));
765 return collect3;
766 })();")
768 (test-ps-js loop-append
769 (loop :for a :in b :append a)
770 "(function () {
771 var _js2 = b.length;
772 var append3 = [];
773 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
774 var a = b[_js1];
775 append3 = append3.concat(a);
777 return append3;
778 })();")
780 (test-ps-js the-case-statement-1
781 (case (aref blorg i)
782 ((1 "one") (alert "one"))
783 (2 (alert "two"))
784 (t (alert "default clause")))
785 "switch (blorg[i]) {
786 case 1:
787 case 'one':
788 alert('one');
789 break;
790 case 2:
791 alert('two');
792 break;
793 default:
794 alert('default clause');
795 };")
797 (test-ps-js the-case-statement-2
798 (switch (aref blorg i)
799 (1 (alert "If I get here"))
800 (2 (alert "I also get here"))
801 (default (alert "I always get here")))
802 "switch (blorg[i]) {
803 case 1: alert('If I get here');
804 case 2: alert('I also get here');
805 default: alert('I always get here');
806 };")
808 (test-ps-js the-try-statement-1
809 (try (throw "i")
810 (:catch (error)
811 (alert (+ "an error happened: " error)))
812 (:finally
813 (alert "Leaving the try form")))
814 "try {
815 throw 'i';
816 } catch (error) {
817 alert('an error happened: ' + error);
818 } finally {
819 alert('Leaving the try form');
820 };")
822 (test-ps-js the-html-generator-1
823 (ps-html ((:a :href "foobar") "blorg"))
824 "'<A HREF=\"foobar\">blorg</A>';")
826 (test-ps-js the-html-generator-2
827 (ps-html ((:a :href (generate-a-link)) "blorg"))
828 "['<A HREF=\"', generateALink(), '\">blorg</A>']['join']('');")
830 (test-ps-js the-html-generator-3
831 (funcall (getprop document 'write)
832 (ps-html ((:a :href "#"
833 :onclick (ps-inline (transport))) "link")))
834 "document.write(['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">link</A>']['join'](''));")
836 (test-ps-js the-html-generator-4
837 (let ((disabled nil)
838 (authorized t))
839 (setf (getprop element 'inner-h-t-m-l)
840 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
841 "Edit me"))))
842 "(function () {
843 var disabled = null;
844 var authorized = true;
845 return element.innerHTML = ['<TEXTAREA', disabled || !authorized ? [' DISABLED=\"', 'disabled', '\"']['join']('') : '', '>Edit me</TEXTAREA>']['join']('');
846 })();")
848 (test-ps-js plus-is-not-commutative
849 (setf x (+ "before" x "after"))
850 "x = 'before' + x + 'after';")
852 (test-ps-js plus-works-if-first
853 (setf x (+ x "middle" "after"))
854 "x = x + 'middle' + 'after';")
856 (test-ps-js method-call-op-form
857 (funcall (getprop (+ "" x) 'to-string))
858 "('' + x).toString();")
860 (test-ps-js method-call-op-form-args
861 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
862 "('' + x).foo(1, 2, 'baz', 3);")
864 (test-ps-js method-call-string
865 ((getprop "hi" 'to-string))
866 "'hi'.toString();")
868 (test-ps-js method-call-conditional
869 ((if a x y) 1)
870 "(a ? x : y)(1);")
872 (test-ps-js method-call-variable
873 ((@ x to-string))
874 "x.toString();")
876 (test-ps-js method-call-array
877 ((@ (list 10 20) to-string))
878 "[ 10, 20 ].toString();")
880 (test-ps-js method-call-lambda-call
881 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
882 "(function (x) { return x; })(10).toString();")
884 (test no-whitespace-before-dot
885 (let* ((str (ps* '((@ ((lambda (x) x) 10) to-string))))
886 (dot-pos (position #\. str :test #'char=))
887 (char-before (elt str (1- dot-pos)))
888 (a-parenthesis #\)))
889 (is (char= char-before a-parenthesis))))
891 (test-ps-js simple-getprop
892 (let ((foo (create a 1)))
893 (alert (getprop foo 'a)))
894 "(function () {
895 var foo = { a : 1 };
896 return alert(foo.a);
897 })();")
899 (test-ps-js buggy-getprop
900 (getprop foo slot-name)
901 "foo[slotName];")
903 (test-ps-js buggy-getprop-two
904 (getprop foo (get-slot-name))
905 "foo[getSlotName()];")
907 (test-ps-js old-case-is-now-switch
908 ;; Switch was "case" before, but that was very non-lispish.
909 ;; For example, this code makes three messages and not one
910 ;; which may have been expected. This is because a switch
911 ;; statment must have a break statement for it to return
912 ;; after the alert. Otherwise it continues on the next
913 ;; clause.
914 (switch (aref blorg i)
915 (1 (alert "one"))
916 (2 (alert "two"))
917 (default (alert "default clause")))
918 "switch (blorg[i]) {
919 case 1: alert('one');
920 case 2: alert('two');
921 default: alert('default clause');
922 };")
924 (test-ps-js lisp-like-case
925 (case (aref blorg i)
926 (1 (alert "one"))
927 (2 (alert "two"))
928 (t (alert "default clause")))
929 "switch (blorg[i]) {
930 case 1:
931 alert('one');
932 break;
933 case 2:
934 alert('two');
935 break;
936 default: alert('default clause');
937 };")
940 (test-ps-js even-lispier-case
941 (case (aref blorg i)
942 ((1 2) (alert "Below three"))
943 (3 (alert "Three"))
944 (t (alert "Something else")))
945 "switch (blorg[i]) {
946 case 1:
947 case 2:
948 alert('Below three');
949 break;
950 case 3:
951 alert('Three');
952 break;
953 default: alert('Something else');
954 };")
956 (test-ps-js otherwise-case
957 (case (aref blorg i)
958 (1 (alert "one"))
959 (otherwise (alert "default clause")))
960 "switch (blorg[i]) {
961 case 1:
962 alert('one');
963 break;
964 default: alert('default clause');
965 };")
967 (test escape-sequences-in-string
968 (let ((escapes `((#\\ . #\\)
969 (#\b . #\Backspace)
970 (#\f . ,(code-char 12))
971 ("u000B" . ,(code-char #x000b));;Vertical tab, too uncommon to bother with
972 (#\n . #\Newline)
973 (#\r . #\Return)
974 (#\' . #\');;Double quote need not be quoted because parenscript strings are single quoted
975 (#\t . #\Tab)
976 ("u001F" . ,(code-char #x001f));; character below 32
977 ("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
978 ("uABCD" . ,(code-char #xabcd)))));; Really above ascii.
979 (loop for (js-escape . lisp-char) in escapes
980 for generated = (ps-doc* (format nil "hello~ahi" lisp-char))
981 for wanted = (format nil "'hello\\~ahi';" js-escape)
982 do (is (string= (normalize-js-code generated) wanted)))))
984 (test-ps-js getprop-setf
985 (setf (getprop x 'y) (+ (+ a 3) 4))
986 "x.y = (a + 3) + 4;")
988 (test-ps-js getprop-conditional1
989 (getprop (if zoo foo bar) 'x)
990 "(zoo ? foo : bar).x;")
992 (test-ps-js getprop-conditional2
993 (getprop (if (not zoo) foo bar) 'x)
994 "(!zoo ? foo : bar).x;")
996 (test script-star-eval1
997 (is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x 1) '(setf y 2))))))
999 (test script-star-eval2
1000 (is (string= "x = 1;" (normalize-js-code (ps* '(setf x 1))))))
1002 (test-ps-js list-with-single-nil
1003 (array nil)
1004 "[null];")
1006 (test-ps-js quoted-nil-is-array
1007 'nil
1008 "[];")
1010 (test-ps-js quoted-nil-is-array1
1012 "[];")
1014 (test-ps-js literal-nil
1015 (foo ())
1016 "foo(null);")
1018 (test-ps-js quoted-quoted-nil
1019 '(())
1020 "[null];")
1022 (test-ps-js quoted-quoted-nil1
1023 '(1 ())
1024 "[1, null];")
1026 (test-ps-js defsetf1
1027 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
1028 (setf (baz 1 2) 3))
1029 "(function () {
1030 var _js2 = 1;
1031 var _js3 = 2;
1032 var _js1 = 3;
1033 return setBaz(_js2, _js3, _js1);
1034 })();")
1036 (test-ps-js setf-macroexpands1
1037 (macrolet ((bar (x y)
1038 `(aref ,x ,y 1)))
1039 (setf (bar foo 2) 3))
1040 "foo[2][1] = 3;")
1042 (test-ps-js defsetf-short
1043 (progn (defsetf baz set-baz "docstring")
1044 (setf (baz 1 2 3) "foo"))
1045 "setBaz(1, 2, 3, 'foo');")
1047 (test-ps-js defun-setf1
1048 (progn (defun (setf some-thing) (new-val i1 i2)
1049 (setf (aref *some-thing* i1 i2) new-val))
1050 (setf (some-thing 1 2) "foo"))
1051 "function __setf_someThing(newVal, i1, i2) {
1052 return SOMETHING[i1][i2] = newVal;
1054 __setf_someThing('foo', 1, 2);")
1056 (test-ps-js defun-optional1
1057 (defun test-opt (&optional x)
1058 (if x "yes" "no"))
1059 "function testOpt(x) {
1060 return x ? 'yes' : 'no';
1061 };")
1063 (test-ps-js defun-optional2
1064 (defun foo (x &optional y)
1065 (+ x y))
1066 "function foo(x, y) {
1067 return x + y;
1068 };")
1070 (test-ps-js defun-optional3
1071 (defun blah (&optional (x 0))
1073 "function blah(x) {
1074 if (x === undefined) {
1075 x = 0;
1077 return x;
1078 };")
1080 (test-ps-js arglist-optional4
1081 (lambda (&optional (x 0 supplied?))
1083 "(function (x) {
1084 var suppliedwhat = x !== undefined;
1085 if (!suppliedwhat) {
1086 x = 0;
1088 return x;
1089 });")
1091 (test-ps-js return-nothing
1092 (defun foo () (return-from foo))
1093 "function foo() {
1094 return null;
1095 };")
1097 (test-ps-js return-values
1098 (defun foo () (return-from foo (values 1 2 3)))
1099 "function foo() {
1100 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [2, 3] };
1101 return 1;
1102 };")
1104 (test-ps-js set-timeout
1105 (set-timeout (lambda () (alert "foo")) 10)
1106 "setTimeout(function () { return alert('foo'); }, 10);")
1108 (test-ps-js operator-precedence
1109 (* 3 (+ 4 5) 6)
1110 "3 * (4 + 5) * 6;")
1112 (test-ps-js operators-1
1113 (in prop obj)
1114 "prop in obj;")
1116 (test-ps-js incf1
1117 (incf foo bar)
1118 "foo += bar;")
1120 (test-ps-js decf1
1121 (decf foo bar)
1122 "foo -= bar;")
1124 (test-ps-js incf2
1125 (incf x 5)
1126 "x += 5;")
1128 (test-ps-js decf2
1129 (decf y 10)
1130 "y -= 10;")
1132 (test-ps-js setf-conditional
1133 (setf foo (if x 1 2))
1134 "foo = x ? 1 : 2;")
1136 (test-ps-js obj-literal-numbers
1137 (create 1 "foo")
1138 "({ 1 : 'foo' });")
1140 (test-ps-js obj-literal-strings
1141 (create "foo" 2)
1142 "({ 'foo' : 2 });")
1144 (test-ps-js getprop-string
1145 (getprop foo "bar")
1146 "foo['bar'];")
1148 (test-ps-js getprop-string1
1149 (getprop "bar" 'length)
1150 "'bar'.length;")
1152 (test-ps-js getprop-progn
1153 (getprop (progn (some-fun "abc") "123") "length")
1154 "(someFun('abc'), '123')['length'];")
1156 (test-ps-js method-call-block
1157 ((@ (progn (some-fun "abc") "123") to-string))
1158 "(someFun('abc'), '123').toString();")
1160 (test-ps-js create-blank
1161 (create)
1162 "({ });")
1164 (test-ps-js blank-object-literal
1166 "({ });")
1168 (test-ps-js array-literal1
1170 "[];")
1172 (test-ps-js array-literal2
1173 ([])
1174 "[];")
1176 (test-ps-js array-literal3
1177 ([] 1 2 3)
1178 "[1, 2, 3];")
1180 (test-ps-js array-literal4
1181 ([] 1 (2 3))
1182 "[1, [2, 3]];")
1184 (test-ps-js array-literal5
1185 ([] (1 2) ("a" "b"))
1186 "[[1, 2], ['a', 'b']];")
1188 (test-ps-js defun-rest1
1189 (defun foo (&rest bar)
1190 (alert (aref bar 1)))
1191 "function foo() {
1192 var bar = [];
1193 for (var i1 = 0; i1 < arguments.length - 0; i1 += 1) {
1194 bar[i1] = arguments[i1 + 0];
1196 return alert(bar[1]);
1197 };")
1199 (test-ps-js defun-rest2
1200 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
1201 "function foo(baz) {
1202 var bar = [];
1203 for (var i1 = 0; i1 < arguments.length - 1; i1 += 1) {
1204 bar[i1] = arguments[i1 + 1];
1206 return baz + bar[1];
1207 };")
1209 (test-ps-js defun-keyword1
1210 (defun zoo (foo bar &key baz) (+ foo bar baz))
1211 "function zoo(foo, bar) {
1212 var _js2 = arguments.length;
1213 for (var n1 = 2; n1 < _js2; n1 += 2) {
1214 switch (arguments[n1]) {
1215 case 'baz':
1216 baz = arguments[n1 + 1];
1219 var baz;
1220 return foo + bar + baz;
1221 };")
1223 (test-ps-js defun-keyword2
1224 (defun zoo (&key baz) (* baz baz))
1225 "function zoo() {
1226 var _js2 = arguments.length;
1227 for (var n1 = 0; n1 < _js2; n1 += 2) {
1228 switch (arguments[n1]) {
1229 case 'baz':
1230 baz = arguments[n1 + 1];
1233 var baz;
1234 return baz * baz;
1235 };")
1237 (test-ps-js defun-keyword3
1238 (defun zoo (&key baz (bar 4)) (* baz bar))
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];
1245 break;
1246 case 'bar':
1247 bar = arguments[n1 + 1];
1250 var baz;
1251 var bar = 'undefined' === typeof bar ? 4 : bar;
1252 return baz * bar;
1253 };")
1255 (test-ps-js defun-keyword4
1256 (defun hello-world (&key ((:my-name-key my-name) 1))
1257 my-name)
1258 "function helloWorld() {
1259 var _js2 = arguments.length;
1260 for (var n1 = 0; n1 < _js2; n1 += 2) {
1261 switch (arguments[n1]) {
1262 case 'my-name-key':
1263 myName = arguments[n1 + 1];
1266 var myName = 'undefined' === typeof myName ? 1 : myName;
1267 return myName;
1268 };")
1270 (test-ps-js arglist-keyword-supplied
1271 (lambda (&key (foo 1 supplied?))
1272 foo)
1273 "(function () {
1274 var _js2 = arguments.length;
1275 for (var n1 = 0; n1 < _js2; n1 += 2) {
1276 switch (arguments[n1]) {
1277 case 'foo':
1278 foo = arguments[n1 + 1];
1279 suppliedwhat = true;
1282 var suppliedwhat;
1283 var foo = 'undefined' === typeof foo ? 1 : foo;
1284 return foo;
1285 });")
1287 (test-ps-js keyword-funcall1
1288 (func :baz 1)
1289 "func('baz', 1);")
1291 (test-ps-js keyword-funcall2
1292 (func :baz 1 :bar foo)
1293 "func('baz', 1, 'bar', foo);")
1295 (test-ps-js keyword-funcall3
1296 (fun a b :baz c)
1297 "fun(a, b, 'baz', c);")
1299 (test-ps-js cond1
1300 (cond ((= x 1) 1))
1301 "if (x === 1) {
1303 };")
1305 (test-ps-js cond2
1306 (cond ((= x 1) 2)
1307 ((= y (* x 4)) (foo "blah") (* x y)))
1308 "if (x === 1) {
1310 } else if (y === x * 4) {
1311 foo('blah');
1312 x * y;
1313 };")
1315 (test-ps-js if-exp-without-else-return
1316 (defun foo () (return-from foo (if x 1)))
1317 "function foo() {
1318 return x ? 1 : null;
1319 };")
1321 (test-ps-js progn-expression-single-statement
1322 (defun foo () (return-from foo (progn (* x y))))
1323 "function foo() {
1324 return x * y;
1325 };")
1327 (test-ps-js cond-expression1
1328 (defun foo ()
1329 (cond ((< 1 2) (bar "foo") (* 4 5))))
1330 "function foo() {
1331 if (1 < 2) {
1332 bar('foo');
1333 return 4 * 5;
1335 };")
1337 (test-ps-js cond-expression2
1338 (defun foo ()
1339 (cond ((< 2 1) "foo")
1340 ((= 7 7) "bar")))
1341 "function foo() {
1342 if (2 < 1) {
1343 return 'foo';
1344 } else if (7 === 7) {
1345 return 'bar';
1347 };")
1349 (test-ps-js cond-expression-final-t-clause
1350 (defun foo ()
1351 (cond ((< 1 2) (bar "foo") (* 4 5))
1352 ((= a b) (+ c d))
1353 ((< 1 2 3 4 5) x)
1354 (t "foo")))
1355 "function foo() {
1356 var _cmp1;
1357 var _cmp2;
1358 var _cmp3;
1359 if (1 < 2) {
1360 bar('foo');
1361 return 4 * 5;
1362 } else if (a === b) {
1363 return c + d;
1364 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1365 return x;
1366 } else {
1367 return 'foo';
1369 };")
1371 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1372 (defun foo ()
1373 (cond ((< 2 1) 5)
1374 (t "foo")
1375 ((< 1 2) "bar")))
1376 "function foo() {
1377 if (2 < 1) {
1378 return 5;
1379 } else {
1380 return 'foo';
1382 };")
1384 (test-ps-js funcall-if-expression
1385 (funcall (getprop document 'write)
1386 (if (= *linkornot* 1)
1387 (ps-html ((:a :href "#"
1388 :onclick (ps-inline (transport)))
1389 img))
1390 img))
1391 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>']['join']('') : img);")
1393 (test-ps-js negate-number-literal
1394 (- 1)
1395 "-1;")
1397 (test macro-environment1
1398 (is (string= (normalize-js-code (let* ((macroname (gensym)))
1399 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1400 `(defun test1 ()
1401 (macrolet ((,macroname (x) `(aref data ,x)))
1402 (when (,macroname x)
1403 (setf (,macroname x) 123)))))))
1404 (normalize-js-code
1405 "function test1() {
1406 return data[x] ? (data[x] = 123) : null;
1407 };"))))
1409 (test macro-environment2
1410 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
1411 (defpsmacro macro-environment2-macro (x)
1412 `(+ ,outer-lexical-variable ,x))
1413 (ps* '(macro-environment2-macro 2))))
1414 (normalize-js-code "1 + 2;"))))
1416 (test-ps-js ampersand-whole-1
1417 (macrolet ((foo (&whole foo bar baz)
1418 (declare (ignore bar baz))
1419 (with-standard-io-syntax (format nil "~a" foo))))
1420 (foo 1 2))
1421 "'(FOO 1 2)';")
1423 (test-ps-js keyword-consistent
1425 "'x';")
1427 (test-ps-js simple-symbol-macrolet
1428 (symbol-macrolet ((x 1)) x)
1429 "1;")
1431 (test-ps-js compound-symbol-macrolet
1432 (symbol-macrolet ((x 123)
1433 (y (* 2 x)))
1435 "2 * 123;")
1437 (test-ps-js define-symbol-macro
1438 (progn (define-symbol-macro tst-sym-macro 2)
1439 tst-sym-macro)
1440 "2;")
1442 (test-ps-js define-symbol-macro1
1443 (progn (define-symbol-macro tst-sym-macro1 2)
1444 (foo tst-sym-macro1))
1445 "foo(2);")
1447 (test-ps-js expression-progn
1448 (1+ (progn (foo) (if x 1 2)))
1449 "(foo(), x ? 1 : 2) + 1;")
1451 (test-ps-js let-decl-in-expression
1452 (defun f (x)
1453 (if x 1 (let* ((foo x)) foo)))
1454 "function f(x) {
1455 if (x) {
1456 return 1;
1457 } else {
1458 var foo = x;
1459 return foo;
1461 };")
1463 (test-ps-js special-var1
1464 (progn (defvar *foo*)
1465 (let* ((*foo* 2))
1466 (* *foo* 2)))
1467 "var FOO;
1468 (function () {
1469 var FOO_TMPSTACK1;
1470 try {
1471 FOO_TMPSTACK1 = FOO;
1472 FOO = 2;
1473 return FOO * 2;
1474 } finally {
1475 FOO = FOO_TMPSTACK1;
1477 })();")
1479 (test-ps-js special-var2
1480 (progn (defvar *foo*)
1481 (let* ((*baz* 3)
1482 (*foo* 2))
1483 (* *foo* 2 *baz*)))
1484 "var FOO;
1485 (function () {
1486 var BAZ = 3;
1487 var FOO_TMPSTACK1;
1488 try {
1489 FOO_TMPSTACK1 = FOO;
1490 FOO = 2;
1491 return FOO * 2 * BAZ;
1492 } finally {
1493 FOO = FOO_TMPSTACK1;
1495 })();")
1497 (test-ps-js literal1
1498 (setf x undefined)
1499 "x = undefined;")
1501 (test-ps-js literal2
1502 (aref this x)
1503 "this[x];")
1505 (test-ps-js setf-dec1
1506 (setf x (- 1 x 2))
1507 "x = 1 - x - 2;")
1509 (test-ps-js setf-dec2
1510 (setf x (- x 1 2))
1511 "x = x - 1 - 2;")
1513 (test-ps-js special-char-equals
1514 blah=
1515 "blahequals;")
1517 (test-ps-js setf-operator-priority
1518 (defun foo ()
1519 (or (getprop cache id)
1520 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1521 "function foo() {
1522 return cache[id] || (cache[id] = document.getElementById(id));
1523 };")
1525 (test-ps-js aref-operator-priority
1526 (aref (if (and x (> (length x) 0))
1527 (aref x 0)
1530 "(x && x.length > 0 ? x[0] : y)[z];")
1532 (test-ps-js aref-operator-priority1
1533 (aref (or (getprop x 'y)
1534 (getprop a 'b))
1536 "(x.y || a.b)[z];")
1538 (test-ps-js aref-operator-priority2
1539 (aref (if a b c) 0)
1540 "(a ? b : c)[0];")
1542 (test-ps-js negate-operator-priority
1543 (- (if x y z))
1544 "-(x ? y : z);")
1546 (test-ps-js op-p1
1547 (new (or a b))
1548 "new (a || b);")
1550 (test-ps-js op-p2
1551 (delete (if a (or b c) d))
1552 "delete (a ? b || c : d);")
1554 (test-ps-js op-p3
1555 (not (if (or x (not y)) z))
1556 "!(x || !y ? z : null);")
1558 (test-ps-js op-p4
1559 (- (- (* 1 2) 3))
1560 "-(1 * 2 - 3);")
1562 (test-ps-js op-p5
1563 (instanceof (or a b) (if x y z))
1564 "((a || b) instanceof (x ? y : z));")
1566 (test-ps-js op-p7
1567 (or x (if (= x 0) "zero" "empty"))
1568 "x || (x === 0 ? 'zero' : 'empty');")
1570 (test-ps-js named-op-expression
1571 (throw (if a b c))
1572 "throw a ? b : c;")
1574 (test-ps-js named-op-expression1
1575 (typeof (or x y))
1576 "typeof (x || y);")
1578 (test-ps-js aref-array-expression
1579 (aref (or a b c) 0)
1580 "(a || b || c)[0];")
1582 (test-ps-js getprop-operator
1583 (getprop (or a b c) 'd)
1584 "(a || b || c).d;")
1586 (test-ps-js getprop-parens
1587 (getprop (getprop foo 'bar) 'baz)
1588 "foo.bar.baz;")
1590 (test-ps-js funcall-funcall
1591 ((foo))
1592 "foo()();")
1594 (test-ps-js expression-funcall
1595 ((or (@ window eval) eval) foo nil)
1596 "(window.eval || eval)(foo, null);")
1598 (test-ps-js expression-funcall1
1599 (((or (@ window eval) eval) foo nil))
1600 "(window.eval || eval)(foo, null)();")
1602 (test-ps-js expression-funcall2
1603 (((or (@ window eval) eval)) foo nil)
1604 "(window.eval || eval)()(foo, null);")
1606 (test-ps-js who-html1
1607 (who-ps-html (:span :class "ticker-symbol"
1608 :ticker-symbol symbol
1609 (:a :href "http://foo.com"
1610 symbol)
1611 (:span :class "ticker-symbol-popup")))
1612 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>']['join']('');")
1614 (test-ps-js who-html2
1615 (who-ps-html (:p "t0" (:span "t1")))
1616 "'<P>t0<SPAN>t1</SPAN></P>';")
1618 (test-ps-js flet1
1619 ((lambda () (flet ((foo (x)
1620 (1+ x)))
1621 (foo 1))))
1622 "(function () {
1623 var foo = function (x) {
1624 return x + 1;
1626 return foo(1);
1627 })();")
1629 (test-ps-js flet2
1630 (flet ((foo (x) (1+ x))
1631 (bar (y) (+ 2 y)))
1632 (bar (foo 1)))
1633 "(function () {
1634 var foo = function (x) {
1635 return x + 1;
1637 var bar = function (y) {
1638 return 2 + y;
1640 return bar(foo(1));
1641 })();")
1643 (test-ps-js flet3
1644 (flet ((foo (x) (+ 2 x)))
1645 (flet ((foo (x) (1+ x))
1646 (bar (y) (+ 2 (foo y))))
1647 (bar (foo 1))))
1648 "(function () {
1649 var foo = function (x) {
1650 return 2 + x;
1652 var foo1 = function (x) {
1653 return x + 1;
1655 var bar = function (y) {
1656 return 2 + foo(y);
1658 return bar(foo1(1));
1659 })();")
1661 (test-ps-js labels1
1662 ((lambda () (labels ((foo (x)
1663 (if (= 0 x)
1665 (+ x (foo (1- x))))))
1666 (foo 3))))
1667 "(function () {
1668 var foo = function (x) {
1669 return 0 === x ? 0 : x + foo(x - 1);
1671 return foo(3);
1672 })();")
1674 (test-ps-js labels2
1675 (labels ((foo (x) (1+ (bar x)))
1676 (bar (y) (+ 2 (foo y))))
1677 (bar (foo 1)))
1678 "(function () {
1679 var foo = function (x) {
1680 return bar(x) + 1;
1682 var bar = function (y) {
1683 return 2 + foo(y);
1685 return bar(foo(1));
1686 })();")
1688 (test-ps-js labels3
1689 (labels ((foo (x) (1+ x))
1690 (bar (y) (+ 2 (foo y))))
1691 (bar (foo 1)))
1692 "(function () {
1693 var foo = function (x) {
1694 return x + 1;
1696 var bar = function (y) {
1697 return 2 + foo(y);
1699 return bar(foo(1));
1700 })();")
1702 (test-ps-js labels-lambda-list
1703 (labels ((foo (x &optional (y 0))
1704 (+ x y)))
1705 (foo 1))
1706 "(function () {
1707 var foo = function (x, y) {
1708 if (y === undefined) {
1709 y = 0;
1711 return x + y;
1713 return foo(1);
1714 })();")
1716 (test-ps-js for-loop-var-init-exp
1717 ((lambda (x)
1718 (do* ((y (if x 0 1) (1+ y))
1719 (z 0 (1+ z)))
1720 ((= y 3) z)))
1722 "(function (x) {
1723 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1725 return z;
1726 })(true);")
1728 (test-ps-js math-pi
1730 "Math.PI;")
1732 (test-ps-js literal-array
1733 '(1 2 3)
1734 "[1, 2, 3];")
1736 (test-ps-js literal-array-1
1737 '(1 foo 3)
1738 "[1, 'foo', 3];")
1740 (test-ps-js literal-array-literal
1742 "[];")
1744 (test-ps-js literal-array-literal1
1745 '(1 [])
1746 "[1, []];")
1748 (test ps-lisp-expands-in-lexical-environment
1749 (is (string= "5;" (let ((x 5))
1750 (ps (lisp x))))))
1752 (test ps-lisp-expands-in-lexical-environment1
1753 (is (string= "1 + 5;" (let ((x 5))
1754 (ps (+ 1 (lisp x)))))))
1756 (test ps-lisp-expands-in-lexical-environment2
1757 (is (string= "1 + 2 + 3;" (let ((x 2))
1758 (ps (+ 1 (lisp x) 3))))))
1760 (test ps*-lisp-expands-in-null-lexical-environment
1761 (signals unbound-variable (let ((x 5))
1762 (declare (ignore x))
1763 (ps* '(lisp x)))))
1765 (test ps*-lisp-expands-in-dynamic-environment
1766 (is (string= "1 + 2;"
1767 (let ((foo 2))
1768 (declare (special foo))
1769 (ps* '(+ 1 (lisp (locally (declare (special foo)) foo))))))))
1771 (test ps-lisp-dynamic-environment
1772 (is (string= "1 + 2;"
1773 (let ((foo 2))
1774 (declare (special foo))
1775 (ps (+ 1 (lisp foo)))))))
1777 (test-ps-js nested-if-expressions1
1778 (defun foo ()
1779 (return-from foo (if (if x y z) a b)))
1780 "function foo() {
1781 if (x ? y : z) {
1782 return a;
1783 } else {
1784 return b;
1786 };")
1788 (test-ps-js nested-if-expressions2
1789 (defun foo ()
1790 (if x y (if z a b)))
1791 "function foo() {
1792 if (x) {
1793 return y;
1794 } else {
1795 return z ? a : b;
1797 };")
1799 (test-ps-js let1
1800 (let (x)
1801 (+ x x))
1802 "(function () {
1803 var x = null;
1804 return x + x;
1805 })();")
1807 (test-ps-js let2
1808 (let ((x 1))
1809 (+ x x))
1810 "(function () {
1811 var x = 1;
1812 return x + x;
1813 })();")
1815 (test-ps-js let-x-x
1816 (let ((x (1+ x)))
1817 (+ x x))
1818 "(function () {
1819 var x1 = x + 1;
1820 return x1 + x1;
1821 })();")
1823 (test-ps-js let3
1824 (let ((x 1)
1825 (y 2))
1826 (+ x x))
1827 "(function () {
1828 var x = 1;
1829 var y = 2;
1830 return x + x;
1831 })();")
1833 (test-ps-js let4
1834 (let ((x 1)
1835 (y (1+ x)))
1836 (+ x y))
1837 "(function () {
1838 var x1 = 1;
1839 var y = x + 1;
1840 return x1 + y;
1841 })();")
1843 (test-ps-js let5
1844 (let ((x 1))
1845 (+ x 1)
1846 (let ((x (+ x 5)))
1847 (+ x 1))
1848 (+ x 1))
1849 "(function () {
1850 var x = 1;
1851 x + 1;
1852 var x1 = x + 5;
1853 x1 + 1;
1854 return x + 1;
1855 })();")
1857 (test-ps-js let6
1858 (let ((x 2))
1859 (let ((x 1)
1860 (y (1+ x)))
1861 (+ x y)))
1862 "(function () {
1863 var x = 2;
1864 var x1 = 1;
1865 var y = x + 1;
1866 return x1 + y;
1867 })();")
1869 (test-ps-js let-exp1
1870 (lambda ()
1871 (let (x)
1872 (+ x x)))
1873 "(function () {
1874 var x = null;
1875 return x + x;
1876 });")
1878 (test-ps-js let*1
1879 (let* ((x 1))
1880 (+ x x))
1881 "(function () {
1882 var x = 1;
1883 return x + x;
1884 })();")
1886 (test-ps-js let*2
1887 (let* ((x 1)
1888 (y (+ x 2)))
1889 (+ x y))
1890 "(function () {
1891 var x = 1;
1892 var y = x + 2;
1893 return x + y;
1894 })();")
1896 (test-ps-js let*3
1897 (let ((x 3))
1898 (let* ((x 1)
1899 (y (+ x 2)))
1900 (+ x y)))
1901 "(function () {
1902 var x = 3;
1903 var x1 = 1;
1904 var y = x1 + 2;
1905 return x1 + y;
1906 })();")
1908 (test-ps-js let*4
1909 (let ((x 3))
1910 (let* ((y (+ x 2))
1911 (x 1))
1912 (+ x y)))
1913 "(function () {
1914 var x = 3;
1915 var y = x + 2;
1916 var x1 = 1;
1917 return x1 + y;
1918 })();")
1920 (test-ps-js symbol-macrolet-var
1921 (symbol-macrolet ((x y))
1922 (var x))
1923 "var y;")
1925 (test-ps-js setf-conditional1
1926 (setf x (unless (null a) (1+ a)))
1927 "x = a != null ? a + 1 : null;")
1929 (test-ps-js setf-let1
1930 (setf x (let ((a 1)) a))
1931 "x = (function () {
1932 var a = 1;
1933 return a;
1934 })();")
1936 (test-ps-js setf-let2
1937 (setf x (let ((a (foo)))
1938 (unless (null a)
1939 (1+ a))))
1940 "x = (function () {
1941 var a = foo();
1942 return a != null ? a + 1 : null;
1943 })();")
1945 (test-ps-js symbol-macro-env1
1946 (symbol-macrolet ((bar 1))
1947 (macrolet ((bar (x y) `(+ ,x ,y)))
1948 (bar bar bar)))
1949 "1 + 1;")
1951 (test-ps-js symbol-macrolet-fun1
1952 (symbol-macrolet ((baz +))
1953 (baz 1 2))
1954 "baz(1, 2);")
1956 (test-ps-js lisp2-namespaces1
1957 (let ((list nil))
1958 (setf list (list 1 2 3)))
1959 "(function () {
1960 var list = null;
1961 return list = [1, 2, 3];
1962 })();")
1964 (test-ps-js let-shadows-symbol-macrolet
1965 (symbol-macrolet ((x y))
1966 (let ((x 1))
1967 (+ x x))
1968 (+ x x))
1969 "(function () {
1970 var x1 = 1;
1971 return x1 + x1;
1972 })();
1973 y + y;")
1975 (test-ps-js let-rename-optimization1
1976 (let ((x 1))
1977 (+ x x))
1978 "(function () {
1979 var x = 1;
1980 return x + x;
1981 })();")
1983 (test-ps-js let-rename-optimization2
1984 (lambda (x)
1985 (let ((x (+ 1 x)))
1987 "(function (x) {
1988 var x1 = 1 + x;
1989 return x1;
1990 });")
1992 (test-ps-js symbol-macro-array
1993 (symbol-macrolet ((x 1))
1994 (list x))
1995 "[1];")
1997 (test-ps-js symbol-macro-obj
1998 (symbol-macrolet ((x y))
1999 (create x 1))
2000 "({ x : 1 });")
2002 (test-ps-js symbol-macro-conditional1
2003 (symbol-macrolet ((x y))
2004 (if x x x))
2005 "if (y) {
2007 } else {
2009 };")
2011 (test-ps-js symbol-macro-conditional2
2012 (symbol-macrolet ((x y))
2013 (1+ (if x x x)))
2014 "(y ? y : y) + 1;")
2016 (test-ps-js flet-apply
2017 (flet ((foo () 'bar))
2018 (apply (function foo) nil))
2019 "(function () {
2020 var foo = function () {
2021 return 'bar';
2023 return foo.apply(this, null);
2024 })();")
2026 (test-ps-js let-apply
2027 (let ((foo (lambda () 1)))
2028 (let ((foo (lambda () 2)))
2029 (apply foo nil)))
2030 "(function () {
2031 var foo = function () {
2032 return 1;
2034 var foo1 = function () {
2035 return 2;
2037 return foo1.apply(this, null);
2038 })();")
2040 (test-ps-js flet-let
2041 (flet ((x (x) (1+ x)))
2042 (let ((x 2))
2043 (x x)))
2044 "(function () {
2045 var x = function (x) {
2046 return x + 1;
2048 var x1 = 2;
2049 return x(x1);
2050 })();")
2052 (test-ps-js let-flet
2053 (let ((x 2))
2054 (flet ((x (x) (1+ x)))
2055 (x x)))
2056 "(function () {
2057 var x = 2;
2058 var x1 = function (x) {
2059 return x + 1;
2061 return x1(x);
2062 })();")
2064 (test-ps-js labels-let
2065 (labels ((x (x) (1+ x)))
2066 (let ((x 2))
2067 (x x)))
2068 "(function () {
2069 var x = function (x) {
2070 return x + 1;
2072 var x1 = 2;
2073 return x(x1);
2074 })();")
2076 (test-ps-js let-labels
2077 (let ((x 2))
2078 (labels ((x (x) (1+ x)))
2079 (x x)))
2080 "(function () {
2081 var x = 2;
2082 var x1 = function (x) {
2083 return x + 1;
2085 return x1(x);
2086 })();")
2088 (test-ps-js macrolet-let-inteference
2089 (macrolet ((a (n) `(+ ,n 5)))
2090 (let ((a (a 1)))
2091 (let ((b (a (- a 4))))
2092 (+ a b))))
2093 "(function () {
2094 var a = 1 + 5;
2095 var b = (a - 4) + 5;
2096 return a + b;
2097 })();")
2099 (test-ps-js let-subtract-add
2100 (let ((x 1))
2101 (let ((x 2))
2102 (- x x)
2103 (- x)
2104 (decf x)
2105 (incf x)))
2106 "(function () {
2107 var x = 1;
2108 var x1 = 2;
2109 x1 - x1;
2110 -x1;
2111 --x1;
2112 return ++x1;
2113 })();")
2115 (test-ps-js create-reserved-word
2116 (create :default 1)
2117 "({ 'default' : 1 });")
2119 (test-ps-js getprop-reserved-word
2120 (getprop foo :default)
2121 "foo['default'];")
2123 (test-ps-js getprop-reserved-word1
2124 (getprop foo 'default)
2125 "foo['default'];")
2127 (test-ps-js eval-when-ps-side
2128 (eval-when (:execute)
2130 "5;")
2132 (defvar *lisp-output* nil)
2134 (test eval-when-lisp-side ()
2135 (setf *lisp-output* 'original-value)
2136 (let ((js-output (normalize-js-code
2137 (ps-doc* `(eval-when (:compile-toplevel)
2138 (setf *lisp-output* 'it-works))))))
2139 (is (eql 'it-works *lisp-output*))
2140 (is (string= "" js-output))))
2142 (defpsmacro my-in-package (package-name)
2143 `(eval-when (:compile-toplevel)
2144 (setf *lisp-output* ,package-name)))
2146 (test eval-when-macro-expansion ()
2147 (setf *lisp-output* 'original-value)
2148 (let ((js-output (normalize-js-code
2149 (ps-doc* `(progn
2150 (my-in-package :cl-user)
2151 3)))))
2152 (declare (ignore js-output))
2153 (is (eql :cl-user *lisp-output*))))
2155 (test eval-when-macrolet-expansion ()
2156 (setf *lisp-output* 'original-value)
2157 (let ((js-output (normalize-js-code
2158 (ps-doc* `(macrolet ((my-in-package2 (package-name)
2159 `(eval-when (:compile-toplevel)
2160 (setf *lisp-output* ,package-name))))
2161 (my-in-package2 :cl-user)
2162 3)))))
2163 (declare (ignore js-output))
2164 (is (eql :cl-user *lisp-output*))))
2166 (test-ps-js getprop-keyword
2167 (getprop foo :bar)
2168 "foo['bar'];")
2170 (test-ps-js nary-comparison1
2171 (lambda () (< 1 2 3))
2172 "(function () {
2173 var _cmp1;
2174 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2175 });")
2177 (test-ps-js chain-getprop1
2178 (chain ($ "foo") (bar x z) frob (baz 5))
2179 "$('foo').bar(x, z).frob.baz(5);")
2181 (test-ps-js chain-getprop2
2182 (chain ($ "foo") bar baz)
2183 "$('foo').bar.baz;")
2185 (test-ps-js chain-getprop3
2186 (chain ($ "foo") bar (x y) baz)
2187 "$('foo').bar.x(y).baz;")
2189 (test-ps-js flet-expression
2190 (1+ (flet ((foo (x) (1+ x)))
2191 (foo 1)))
2192 "(function () {
2193 var foo = function (x) {
2194 return x + 1;
2196 return foo(1);
2197 })() + 1;")
2199 (test-ps-js flet-lambda-list
2200 (flet ((foo (x &key (y 0))
2201 (+ x y)))
2202 (foo 1 :y 2))
2203 "(function () {
2204 var foo = function (x) {
2205 var _js2 = arguments.length;
2206 for (var n1 = 1; n1 < _js2; n1 += 2) {
2207 switch (arguments[n1]) {
2208 case 'y':
2209 y = arguments[n1 + 1];
2212 var y = 'undefined' === typeof y ? 0 : y;
2213 return x + y;
2215 return foo(1, 'y', 2);
2216 })();")
2218 (test-ps-js return-case-break-elimination
2219 (defun foo ()
2220 (return-from foo
2221 (case 1
2222 (0 1)
2223 (otherwise 2))))
2224 "function foo() {
2225 switch (1) {
2226 case 0:
2227 return 1;
2228 default:
2229 return 2;
2231 };")
2233 (test-ps-js aplusplus
2235 "aplusplus;")
2237 (test-ps-js astarstar
2239 "astarstar;")
2241 (test-ps-js switch-return-fallthrough
2242 (defun foo ()
2243 (return-from foo
2244 (switch x
2245 (1 (foo) break)
2246 (2 (bar))
2247 (default 4))))
2248 "function foo() {
2249 switch (x) {
2250 case 1:
2251 return foo();
2252 case 2:
2253 bar();
2254 default:
2255 return 4;
2257 };")
2259 (test-ps-js return-last-case
2260 (defun foo ()
2261 (return-from foo
2262 (case x
2263 (:a 'eh)
2264 (:b 'bee))))
2265 "function foo() {
2266 switch (x) {
2267 case 'a':
2268 return 'eh';
2269 case 'b':
2270 return 'bee';
2272 };")
2274 (test-ps-js return-macrolet
2275 (defun foo ()
2276 (return-from foo
2277 (macrolet ((x () 1))
2278 (case (x)
2279 (:a 'eh)
2280 (:b 'bee)))))
2281 "function foo() {
2282 switch (1) {
2283 case 'a':
2284 return 'eh';
2285 case 'b':
2286 return 'bee';
2288 };")
2290 (test-ps-js mv-bind1
2291 (multiple-value-bind (a b)
2292 (progn
2293 (returns-mv)
2294 (doesnt))
2295 (alert a)
2296 (alert b))
2297 "returnsMv();
2298 (function () {
2299 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2300 try {
2301 var a = doesnt();
2302 var _db3 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2303 var b = _db3[0];
2304 alert(a);
2305 return alert(b);
2306 } finally {
2307 __PS_MV_REG = prevMv1;
2309 })();")
2311 (test-ps-js mv-bind2
2312 (multiple-value-bind (a b)
2313 (let ((a 1))
2314 (returns-mv a)
2315 (doesnt b))
2316 (alert a)
2317 (alert b))
2318 "(function () {
2319 var a = 1;
2320 returnsMv(a);
2321 var prevMv3 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2322 try {
2323 var a5 = doesnt(b);
2324 var _db6 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2325 var b = _db6[0];
2326 alert(a5);
2327 return alert(b);
2328 } finally {
2329 __PS_MV_REG = prevMv3;
2331 })();")
2333 (test-ps-js multiple-value-bind-simple
2334 (multiple-value-bind (a b) (blah)
2335 (+ a b))
2336 "(function () {
2337 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2338 try {
2339 var a = blah();
2340 var _db3 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2341 var b = _db3[0];
2342 return a + b;
2343 } finally {
2344 __PS_MV_REG = prevMv1;
2346 })();")
2348 (test-ps-js values0
2349 (lambda () (values))
2350 "(function () {
2351 __PS_MV_REG = {};
2352 return null;
2353 });")
2355 (test-ps-js values1
2356 (values x)
2357 "x;")
2359 (test-ps-js values2
2360 (lambda () (values x y))
2361 "(function () {
2362 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2363 return x;
2364 });")
2366 (test-ps-js values3
2367 (lambda () (values x y z))
2368 "(function () {
2369 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2370 return x;
2371 });")
2373 (test-ps-js values-return
2374 (defun foo (x y)
2375 (return-from foo (values (* x x) y)))
2376 "function foo(x, y) {
2377 var val1_1 = x * x;
2378 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2379 return val1_1;
2380 };")
2382 (test-ps-js return-macrolet1
2383 (defun foo ()
2384 (return-from foo
2385 (symbol-macrolet ((x 2))
2386 (loop do (+ x x)))))
2387 "function foo() {
2388 while (true) {
2389 2 + 2;
2391 };")
2393 (test-ps-js return-cond
2394 (defun foo ()
2395 (return-from foo
2396 (cond ((foo? x) (loop for y in x do (foo y)))
2397 ((bar? x) x)
2398 (t 3))))
2399 "function foo() {
2400 if (foowhat(x)) {
2401 var _js2 = x.length;
2402 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2403 var y = x[_js1];
2404 foo(y);
2406 } else if (barwhat(x)) {
2407 return x;
2408 } else {
2409 return 3;
2411 };")
2413 (test-ps-js return-case
2414 (defun foo ()
2415 (return-from foo
2416 (case x
2417 (1 (loop for y in x do (foo y)))
2418 (2 x)
2419 ((t) 3))))
2420 "function foo() {
2421 switch (x) {
2422 case 1:
2423 var _js2 = x.length;
2424 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2425 var y = x[_js1];
2426 foo(y);
2428 return;
2429 case 2:
2430 return x;
2431 case true:
2432 return 3;
2434 };")
2436 (test-ps-js return-case1
2437 (defun foo ()
2438 (return-from foo
2439 (case x
2440 (1 (if a 1 2))
2441 (2 x)
2442 ((t) 3))))
2443 "function foo() {
2444 switch (x) {
2445 case 1:
2446 return a ? 1 : 2;
2447 case 2:
2448 return x;
2449 case true:
2450 return 3;
2452 };")
2454 (test-ps-js lambda-loop-if-return
2455 (lambda ()
2456 (if a
2457 (loop for y in x do (foo y))
2459 "(function () {
2460 if (a) {
2461 var _js4 = x.length;
2462 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2463 var y = x[_js3];
2464 foo(y);
2466 } else {
2467 return c;
2469 });")
2471 (test-ps-js lambda-loop-if-return1
2472 (defun baz ()
2473 (foo (lambda ()
2474 (if a
2475 (progn (loop for y in x do (foo y))
2476 (return-from baz))
2477 c))))
2478 "function baz() {
2479 try {
2480 return foo(function () {
2481 if (a) {
2482 var _js4 = x.length;
2483 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2484 var y = x[_js3];
2485 foo(y);
2487 throw { '__ps_block_tag' : 'baz',
2488 '__ps_value1' : null };
2489 } else {
2490 return c;
2493 } catch (_ps_err5) {
2494 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2495 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2496 return _ps_err5['__ps_value1'];
2497 } else {
2498 throw _ps_err5;
2501 };")
2503 (test-ps-js switch-loop
2504 (defun foo (x)
2505 (case x
2506 (1 (dolist (a b)))))
2507 "function foo(x) {
2508 switch (x) {
2509 case 1:
2510 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2511 a = b[_js_idx1];
2513 return;
2515 };")
2517 (test-ps-js switch-folds-blocks
2518 (defun foo ()
2519 (case x
2520 (1 (loop repeat 3 do (alert "foo")))
2521 (2 "bar")))
2522 "function foo() {
2523 switch (x) {
2524 case 1:
2525 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2526 alert('foo');
2528 return;
2529 case 2:
2530 return 'bar';
2532 };")
2534 (test-ps-js setf-places-before-macros
2535 (lambda ()
2536 (defsetf left (el) (offset)
2537 `(setf (@ ,el style left) ,offset))
2538 (macrolet ((left (el)
2539 `(@ ,el offset-left)))
2540 (setf (left x) 10)
2541 (left x)))
2542 "(function () {
2543 var _js2 = x;
2544 var _js1 = 10;
2545 _js2.style.left = _js1;
2546 return x.offsetLeft;
2547 });")
2549 (test-ps-js for-return
2550 (lambda () (dolist (arg args) (foo arg)))
2551 "(function () {
2552 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2553 arg = args[_js_idx1];
2554 foo(arg);
2556 });")
2558 (test-ps-js try-catch-return
2559 (defun foo ()
2560 (return-from foo
2561 (try (foo)
2562 (:catch (e)
2563 (bar))
2564 (:finally
2565 (cleanup)))))
2566 "function foo() {
2567 try {
2568 return foo();
2569 } catch (e) {
2570 return bar();
2571 } finally {
2572 cleanup();
2574 };")
2576 (test-ps-js defun-setf-optional
2577 (defun (setf foo) (new-value b &optional c)
2578 (setf (aref b (or c 0)) new-value))
2579 "function __setf_foo(newValue, b, c) {
2580 return b[c || 0] = newValue;
2581 };")
2583 (test-ps-js defun-setf-rest
2584 (progn (defun (setf foo) (new-value b &rest foo)
2585 (do-something b foo new-value))
2586 (setf (foo x 1 2 3 4) 5))
2587 "function __setf_foo(newValue, b) {
2588 var foo = [];
2589 for (var i1 = 0; i1 < arguments.length - 2; i1 += 1) {
2590 foo[i1] = arguments[i1 + 2];
2592 return doSomething(b, foo, newValue);
2594 __setf_foo(5, x, 1, 2, 3, 4);")
2596 (test-ps-js return-null
2597 (defun foo () (return-from foo nil))
2598 "function foo() {
2599 return null;
2600 };")
2602 (test-ps-js implicit-return-null
2603 (lambda ()
2605 "(function () {
2606 return null;
2607 });")
2609 (test-ps-js implicit-return-null
2610 (lambda ()
2611 nil)
2612 "(function () {
2613 return null;
2614 });")
2616 (test-ps-js return-conditional-nested
2617 (defun blep (ss x y)
2618 (when foo?
2619 (let ((pair (bar)))
2620 (unless (null pair)
2621 (destructuring-bind (a b) pair
2622 (unless (or (null a) (null b))
2623 (let ((val (baz a b)))
2624 (unless (null val)
2625 (when (blah val)
2626 (unless (blee)
2627 t))))))))))
2628 "function blep(ss, x, y) {
2629 if (foowhat) {
2630 var pair = bar();
2631 if (pair != null) {
2632 var a = pair[0];
2633 var b = pair[1];
2634 if (!(a == null || b == null)) {
2635 var val = baz(a, b);
2636 if (val != null) {
2637 if (blah(val)) {
2638 return !blee() ? true : null;
2644 };")
2646 ;; this test needs to be rewritten when named blocks are implemented!!!!
2647 (test-ps-js return-when-returns-broken-return
2648 (defun foo ()
2649 (return-from foo (when x 1))
2650 (+ 2 3))
2651 "function foo() {
2652 return x ? 1 : null;
2653 return 2 + 3;
2654 };")
2656 (test-ps-js return-case-conditional
2657 (defun foo ()
2658 (return-from foo
2659 (case foo
2660 (123 (when (bar) t))
2661 (345 (blah)))))
2662 "function foo() {
2663 switch (foo) {
2664 case 123:
2665 return bar() ? true : null;
2666 case 345:
2667 return blah();
2669 };")
2671 (test-ps-js return-try-conditional
2672 (defun foo ()
2673 (return-from foo
2674 (try (when x 1)
2675 (:catch (x) 2)
2676 (:finally (bar)))))
2677 "function foo() {
2678 try {
2679 return x ? 1 : null;
2680 } catch (x) {
2681 return 2;
2682 } finally {
2683 bar();
2685 };")
2687 (test-ps-js function-declare-special
2688 (lambda ()
2689 (declare (special *foo*))
2690 (let ((*foo* 1))
2691 (1+ *foo*)))
2692 "(function () {
2693 var FOO_TMPSTACK1;
2694 try {
2695 FOO_TMPSTACK1 = FOO;
2696 FOO = 1;
2697 return FOO + 1;
2698 } finally {
2699 FOO = FOO_TMPSTACK1;
2701 });")
2703 (test-ps-js declare-special-let
2704 (let ((*foo* 123))
2705 (declare (special *foo*))
2706 (blah))
2707 "(function () {
2708 var FOO_TMPSTACK1;
2709 try {
2710 FOO_TMPSTACK1 = FOO;
2711 FOO = 123;
2712 return blah();
2713 } finally {
2714 FOO = FOO_TMPSTACK1;
2716 })();")
2718 (test-ps-js macro-null-toplevel
2719 (progn
2720 (defmacro macro-null-toplevel ()
2721 nil)
2722 (macro-null-toplevel))
2725 (test-ps-js define-symbol-macro-let
2726 (progn
2727 (define-symbol-macro test-symbol-macro 1)
2728 (let ((test-symbol-macro 2))
2729 (1+ test-symbol-macro))
2730 (1+ test-symbol-macro))
2731 "(function () {
2732 var testSymbolMacro1 = 2;
2733 return testSymbolMacro1 + 1;
2734 })();
2735 1 + 1;")
2737 (test-ps-js define-symbol-macro-flet
2738 (progn
2739 (define-symbol-macro test-symbol-macro1 1)
2740 (flet ((test-symbol-macro1 () 2))
2741 (foo test-symbol-macro1)
2742 (test-symbol-macro1))
2743 (bar test-symbol-macro1))
2744 "(function () {
2745 var testSymbolMacro1_1 = function () {
2746 return 2;
2748 foo(1);
2749 return testSymbolMacro1_1();
2750 })();
2751 bar(1);")
2753 (test compile-stream-nulls
2754 (is (string=
2756 (with-input-from-string (s "
2757 (defmacro macro-null-toplevel ()
2758 nil)
2759 (macro-null-toplevel)")
2760 (ps-compile-stream s)))))
2762 (test compile-stream1
2763 (is (string=
2764 "(function () {
2765 var testSymbolMacro1_1 = function () {
2766 return 2;
2768 foo(1);
2769 return testSymbolMacro1_1();
2770 })();
2771 bar(1);
2773 (with-input-from-string (s "
2774 (define-symbol-macro test-symbol-macro1 1)
2775 (flet ((test-symbol-macro1 () 2))
2776 (foo test-symbol-macro1)
2777 (test-symbol-macro1))
2778 (bar test-symbol-macro1)")
2779 (ps::with-blank-compilation-environment (ps-compile-stream s))))))
2781 (test-ps-js equality-nary1
2782 (let ((x 10) (y 10) (z 10))
2783 (= x y z))
2784 "(function () {
2785 var _cmp1;
2786 var x = 10;
2787 var y = 10;
2788 var z = 10;
2789 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
2790 })();")
2792 (test-ps-js equality1
2793 (progn
2794 (equal a b)
2795 (eql a b)
2796 (eq a b)
2797 (= a b))
2798 "a == b;
2799 a === b;
2800 a === b;
2801 a === b;")
2803 (test-ps-js getprop-quote-reserved
2804 (getprop foo ':break)
2805 "foo['break'];")
2807 (test-ps-js defun-block-return-from
2808 (defun foo (x)
2809 (baz 4)
2810 (return-from foo x)
2811 (bar 5))
2812 "function foo(x) {
2813 baz(4);
2814 return x;
2815 return bar(5);
2816 }; ")
2818 (test-ps-js block-return-from
2819 (block scope
2820 (foo)
2821 (when (bar)
2822 (return-from scope))
2823 (blee))
2824 "(function () {
2825 foo();
2826 if (bar()) {
2827 return null;
2829 return blee();
2830 })();")
2832 (test-ps-js block-return-from0
2833 (defun baz ()
2834 (block scope
2835 (foo)
2836 (when (bar)
2837 (return-from scope))
2838 (blee)))
2839 "function baz() {
2840 foo();
2841 if (bar()) {
2842 return null;
2844 return blee();
2845 };")
2847 (test-ps-js block-return-from01
2848 (defun baz ()
2849 (block scope
2850 (foo)
2851 (when (bar)
2852 (return-from scope))
2853 (blee))
2855 "function baz() {
2856 scope: {
2857 foo();
2858 if (bar()) {
2859 break scope;
2861 blee();
2863 return 2;
2864 };")
2866 (test-ps-js block-return-from02
2867 (defun baz ()
2868 (block scope
2869 (foo)
2870 (when (bar)
2871 (return-from scope (foobar)))
2872 (blee))
2874 "function baz() {
2875 scope: {
2876 foo();
2877 if (bar()) {
2878 foobar();
2879 break scope;
2881 blee();
2883 return 2;
2884 };")
2886 (test-ps-js block-return-from1
2887 (lambda ()
2888 (block scope
2889 (foo)
2890 (when (bar)
2891 (return-from scope))
2892 (blee))
2893 (+ 1 2))
2894 "(function () {
2895 scope: {
2896 foo();
2897 if (bar()) {
2898 break scope;
2900 blee();
2902 return 1 + 2;
2903 });")
2905 (test-ps-js block-return-from2
2906 (lambda ()
2907 (bar 5)
2908 (block scope
2909 (foo)
2910 (when (bar)
2911 (return-from scope 6))
2912 (blee)))
2913 "(function () {
2914 bar(5);
2915 foo();
2916 if (bar()) {
2917 return 6;
2919 return blee();
2920 });")
2922 (test-ps-js let-funcall
2923 (let ((x foo))
2924 (funcall x)
2925 (let ((x bar))
2926 (funcall x))
2927 (funcall x))
2928 "(function () {
2929 var x = foo;
2930 x();
2931 var x1 = bar;
2932 x1();
2933 return x();
2934 })();")
2936 (test-ps-js symbol-macrolet-funcall
2937 (symbol-macrolet ((foo bar))
2938 (funcall foo 1 2 3))
2939 "bar(1, 2, 3);")
2941 (test-ps-js times-assign
2942 (setf x (* x 1000))
2943 "x *= 1000;")
2945 (test-ps-js vector-literal
2946 #(1 2 3)
2947 "[1, 2, 3];")
2949 (test-ps-js rem1
2950 (+ 1 (rem 2 (+ 3 4)))
2951 "1 + 2 % (3 + 4);")
2953 (test-ps-js non-associative
2954 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
2955 "1 / (2 / 3) + (1 - (2 - 3));")
2957 (test-ps-js lambda-apply
2958 (lambda (x)
2959 (apply (lambda (y) (bar (1+ y))) x))
2960 "(function (x) {
2961 return (function (y) {
2962 return bar(y + 1);
2963 }).apply(this, x);
2964 });")
2966 (test-ps-js operator-expressions-nested-let
2967 (let ((x (let ((y 1))
2968 y)))
2970 "(function () {
2971 var y;
2972 var x = (y = 1, y);
2973 return x;
2974 })();")
2976 (test-ps-js operator-expressions-array-nested-let
2977 (list (let ((y 1)) y) 2)
2978 "[(function () {
2979 var y = 1;
2980 return y;
2981 })(), 2];")
2983 (test-ps-js add-subtract-precedence
2984 (- x (+ y z))
2985 "x - (y + z);")
2987 (test-ps-js ps-inline-toplevel
2988 (ps-inline (foo))
2989 "'javascript:' + 'foo()';")
2991 (test-ps-js no-clause-progn-exp
2992 (setf x (progn))
2993 "x = null;")
2995 (test-ps-js no-clause-progn-return
2996 (defun foo ()
2997 (return-from foo (progn)))
2998 "function foo() {
2999 return null;
3000 };")
3002 (test-ps-js empty-cond-clause
3003 (setf x (cond ((foo))))
3004 "x = foo() ? null : null;")
3006 (test-ps-js empty-cond-clause1
3007 (setf x (cond ((foo) 123)
3008 ((bar))
3009 (t 456)))
3010 "x = foo() ? 123 : (bar() ? null : 456);")
3012 (test-ps-js let-no-body
3013 (defun foo ()
3014 (return-from foo (let ((foo bar)))))
3015 "function foo() {
3016 var foo1 = bar;
3017 return null;
3018 };")
3020 (test-ps-js rename-lexical-dupes
3021 (lambda ()
3022 (list (let ((foo 12)) (* foo 2))
3023 (let ((foo 13)) (* foo 3))))
3024 "(function () {
3025 var foo;
3026 var foo1;
3027 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3028 });")
3030 (test-ps-js defun-comment1
3031 (defun foo (x)
3032 "BARBAR is a revolutionary new foobar.
3033 X y and x."
3034 (1+ x))
3035 "/**
3036 * BARBAR is a revolutionary new foobar.
3037 * X y and x.
3039 function foo(x) {
3040 return x + 1;
3041 };")
3043 (test-ps-js var-comment
3044 (var x 1 "foo")
3045 "/** foo */
3046 var x = 1;")
3048 (test-ps-js case-return-break-broken-return
3049 (defun foo ()
3050 (case x
3051 ("bar" (if y (return-from foo t) nil))
3052 ("baz" nil)))
3053 "function foo() {
3054 switch (x) {
3055 case 'bar':
3056 if (y) {
3057 return true;
3058 } else {
3059 return null;
3061 case 'baz':
3062 return null;
3064 };")
3066 (test-ps-js case-return-break1-broken-return
3067 (defun foo ()
3068 (case x
3069 ("bar" (if y (return-from foo t)))
3070 ("baz" nil)))
3071 "function foo() {
3072 switch (x) {
3073 case 'bar':
3074 if (y) {
3075 return true;
3076 } else {
3077 return null;
3079 case 'baz':
3080 return null;
3082 };")
3084 (test-ps-js setf-progn
3085 (setf foo (progn (bar) (baz) 3))
3086 "bar();
3087 baz();
3088 foo = 3;")
3090 (test-ps-js var-progn
3091 (var x (progn (foo) (bar)))
3092 "foo();
3093 var x = bar();")
3095 (test-ps-js implicit-return-loop
3096 (lambda ()
3097 (if baz 7
3098 (progn
3099 (loop :repeat 100 :do (bar))
3100 42)))
3101 "(function () {
3102 if (baz) {
3103 return 7;
3104 } else {
3105 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3106 bar();
3108 return 42;
3110 });")
3112 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
3113 (test-ps-js loop-closures
3114 (dotimes (i 10) (lambda () (+ i 1)))
3115 "(function () {
3116 for (var i = 0; i < 10; i += 1) {
3117 with ({ i : i }) {
3118 function () {
3119 return i + 1;
3123 })();")
3125 (test-ps-js loop-closures-let
3126 (dotimes (i 10)
3127 (let ((x (+ i 1)))
3128 (lambda () (+ i x))))
3129 "(function () {
3130 for (var i = 0; i < 10; i += 1) {
3131 with ({ i : i, x : null }) {
3132 var x = i + 1;
3133 function () {
3134 return i + x;
3138 })();")
3140 (test-ps-js loop-closures-flet
3141 (dotimes (i 10) (flet ((foo (x) (+ i x))) (lambda () (foo i))))
3142 "(function () {
3143 for (var i = 0; i < 10; i += 1) {
3144 with ({ foo : null, i : i }) {
3145 var foo = function (x) {
3146 return i + x;
3148 function () {
3149 return foo(i);
3153 })();")
3155 (test-ps-js while-closures-let
3156 (while (foo)
3157 (let ((x (bar)))
3158 (lambda () (+ 1 x))))
3159 "while (foo()) {
3160 with ({ x : null }) {
3161 var x = bar();
3162 function () {
3163 return 1 + x;
3166 };")
3168 (test-ps-js dotted-list-form
3169 (defun foo (a)
3170 (when a
3171 (destructuring-bind (b . c)
3173 (list b c))))
3174 "function foo(a) {
3175 if (a) {
3176 var b = bar[0];
3177 var c = bar.length > 1 ? bar.slice(1) : [];
3178 return [b, c];
3180 };")
3182 (test-ps-js explicit-nil-block
3183 (defun bar ()
3184 (foo 1)
3185 (block nil (return (foo 2)) (+ 1 2))
3187 "function bar() {
3188 foo(1);
3189 nilBlock: {
3190 foo(2);
3191 break nilBlock;
3192 1 + 2;
3194 return 2;
3195 };")
3197 (test-ps-js dynamic-extent-function-return
3198 (defun foo ()
3199 ((lambda ()
3200 (return-from foo 6))))
3201 "function foo() {
3202 try {
3203 return (function () {
3204 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3205 })();
3206 } catch (_ps_err1) {
3207 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3208 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3209 return _ps_err1['__ps_value1'];
3210 } else {
3211 throw _ps_err1;
3214 };")
3216 (test-ps-js dynamic-extent-function-return-nothing
3217 (defun foo ()
3218 ((lambda ()
3219 (return-from foo))))
3220 "function foo() {
3221 try {
3222 return (function () {
3223 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3224 })();
3225 } catch (_ps_err1) {
3226 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3227 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3228 return _ps_err1['__ps_value1'];
3229 } else {
3230 throw _ps_err1;
3233 };")
3235 (test-ps-js dynamic-extent-function-return-values
3236 (defun foo ()
3237 ((lambda ()
3238 (return-from foo (values 1 2 3)))))
3239 "function foo() {
3240 try {
3241 __PS_MV_REG = {};
3242 return (function () {
3243 throw { '__ps_block_tag' : 'foo',
3244 '__ps_value1' : 1,
3245 '__ps_values' : [2, 3] };
3246 })();
3247 } catch (_ps_err1) {
3248 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3249 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3250 return _ps_err1['__ps_value1'];
3251 } else {
3252 throw _ps_err1;
3255 };")
3257 (test-ps-js dynamic-extent-function-return-funcall
3258 (defun foo ()
3259 ((lambda ()
3260 (return-from foo (if baz 6 5)))))
3261 "function foo() {
3262 try {
3263 return (function () {
3264 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3265 })();
3266 } catch (_ps_err1) {
3267 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3268 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3269 return _ps_err1['__ps_value1'];
3270 } else {
3271 throw _ps_err1;
3274 };")
3276 (test-ps-js block-dynamic-return
3277 (var foo ((lambda ()
3278 (block nil
3279 ((lambda () (return 6)))
3280 (+ 1 2)))))
3281 "var foo = (function () {
3282 try {
3283 (function () {
3284 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3285 })();
3286 return 1 + 2;
3287 } catch (_ps_err1) {
3288 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3289 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3290 return _ps_err1['__ps_value1'];
3291 } else {
3292 throw _ps_err1;
3295 })();")
3297 (test-ps-js block-dynamic-return1
3298 (var foo ((lambda ()
3299 (block nil
3300 ((lambda () (return 6)))
3301 (+ 1 2))
3302 (foobar 1 2))))
3303 "var foo = (function () {
3304 nilBlock: {
3305 (function () {
3306 break nilBlock;
3307 })();
3308 1 + 2;
3310 return foobar(1, 2);
3311 })();")
3313 (test-ps-js iteration-lambda-capture-no-need
3314 (dolist (x y) (lambda (x) (1+ x))) ;; there's really no need to create a 'with' scope in this case
3315 "(function () {
3316 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3317 with ({ x : x }) {
3318 x = y[_js_idx1];
3319 function (x) {
3320 return x + 1;
3324 })();")
3326 (test-ps-js case-invert1
3327 (encodeURIComponent fooBar)
3328 "encodeURIComponent(fooBar);")
3330 (test-ps-js simple-ash
3331 (+ (ash 4 1) (ash 4 -1))
3332 "(4 << 1) + (4 >> 1);")
3334 (test-ps-js progn-nil-expression
3335 (bar (progn (foo) nil))
3336 "bar((foo(), null));")
3338 (test-ps-js other-progn-nil-exp
3339 (defun blah ()
3340 (or (foo) (progn (bar) nil)))
3341 "function blah() {
3342 return foo() || (bar(), null);
3343 };")
3345 (test-ps-js lambda-nil-return
3346 (lambda (x)
3347 (block nil
3348 (when x
3349 (return 1))
3351 "(function (x) {
3352 if (x) {
3353 return 1;
3355 return 2;
3356 });")
3358 (test-ps-js lambda-nil-return-implicit-nested2
3359 (lambda (x)
3360 (block foo
3361 (if x
3362 (return-from foo 1)
3363 (dotimes (i 4)
3364 (return-from foo i)))
3366 "(function (x) {
3367 if (x) {
3368 return 1;
3369 } else {
3370 for (var i = 0; i < 4; i += 1) {
3371 return i;
3374 return 2;
3375 });")
3377 (test-ps-js throw-is-a-statement
3378 (defun blah ()
3379 (let ((result (foo)))
3380 (unless (null result)
3381 (throw result))))
3382 "function blah() {
3383 var result = foo();
3384 if (result != null) {
3385 throw result;
3387 };")
3389 (test-ps-js expressify1
3390 (defun blah ()
3391 (when (some-condition)
3392 (foo)
3393 (bar)
3394 (baz)))
3395 "function blah() {
3396 if (someCondition()) {
3397 foo();
3398 bar();
3399 return baz();
3401 };")
3403 (test-ps-js case-when-return
3404 (defun blah (a)
3405 (case a
3406 ("a" (when (foo) (return-from blah 111)))
3407 ("b" t)))
3408 "function blah(a) {
3409 switch (a) {
3410 case 'a':
3411 if (foo()) {
3412 return 111;
3413 } else {
3414 return null;
3416 case 'b':
3417 return true;
3419 };")
3421 (test-ps-js flet-return-from
3422 (defun abc ()
3423 (flet ((foo ()
3424 (return-from foo 123)))
3425 (foo)))
3426 "function abc() {
3427 var foo = function () {
3428 return 123;
3430 return foo();
3431 };")
3433 (test-ps-js flet-return-from1
3434 (flet ((foo ()
3435 (return-from foo 123)))
3436 (foo))
3437 "(function () {
3438 var foo = function () {
3439 return 123;
3441 return foo();
3442 })();")
3444 (test-ps-js lambda-docstring-declarations
3445 (lambda (x)
3446 "This is a docstring"
3447 (declare (ignore x))
3449 "(function (x) {
3450 return 2;
3451 });")
3453 (test-ps-js setf-let-exp
3454 (setf foo (let ((x (+ 1 2)))
3455 (if x 123 456)))
3456 "foo = (function () {
3457 var x = 1 + 2;
3458 return x ? 123 : 456;
3459 })();")
3461 (test-ps-js create-let-exp
3462 (create :abc (let ((x (+ 1 2)))
3463 (if x 123 456)))
3464 "({ 'abc' : (function () {
3465 var x = 1 + 2;
3466 return x ? 123 : 456;
3467 })() });")
3469 (test-ps-js eql-eql-eql-precedence
3470 (unless (equal (= 3 3) (= 3 4))
3471 (chain console (log 1)))
3472 "if ((3 === 3) != (3 === 4)) {
3473 console.log(1);
3474 };")
3476 (test-ps-js case-cond-breaks
3477 (defun blah (x)
3478 (case x
3479 (123 (cond ((foo1)
3480 (when (foo2)
3481 (when (foo3)
3482 (return-from blah nil))
3483 t))))
3484 (456 (foo7))))
3485 "function blah(x) {
3486 switch (x) {
3487 case 123:
3488 if (foo1()) {
3489 if (foo2()) {
3490 if (foo3()) {
3491 return null;
3493 return true;
3494 } else {
3495 return null;
3497 } else {
3498 return null;
3500 case 456:
3501 return foo7();
3503 };")
3505 (test-ps-js cond-double-t
3506 (lambda ()
3507 (cond (foo 1)
3508 (t 2)
3509 (t 3)))
3510 "(function () {
3511 if (foo) {
3512 return 1;
3513 } else {
3514 return 2;
3516 });")
3518 (test-ps-js let-let-funcall-lambda
3519 (let ((x 5))
3520 (let ((x 7))
3521 (funcall (lambda (x) (+ x 9)) x)))
3522 "(function () {
3523 var x = 5;
3524 var x1 = 7;
3525 return (function (x) {
3526 return x + 9;
3527 })(x1);
3528 })();")
3530 (test-ps-js let-let-lambda
3531 (let ((x 5))
3532 (let ((x 7))
3533 (lambda (x) (+ x 9))))
3534 "(function () {
3535 var x = 5;
3536 var x1 = 7;
3537 return function (x) {
3538 return x + 9;
3540 })();")
3542 (test-ps-js let-lambda
3543 (let ((x 5))
3544 (lambda (x) (+ x 9)))
3545 "(function () {
3546 var x = 5;
3547 return function (x) {
3548 return x + 9;
3550 })();")
3552 (test-ps-js symbol-macrolet-no-shadow-lambda
3553 (symbol-macrolet ((x y))
3554 (lambda (x) (+ x x)))
3555 "(function (x) {
3556 return x + x;
3557 });")
3559 (test-ps-js divide-one-arg-reciprocal
3560 (/ 2)
3561 "1 / 2;")
3563 (test-ps-js division-not-associative
3564 (/ a (* b c))
3565 "a / (b * c);")
3567 (test-ps-js divide-expressions
3568 (/ (foo) (bar))
3569 "foo() / bar();")
3571 (test-ps-js divide-expressions1
3572 (floor (1- x) y)
3573 "Math.floor((x - 1) / y);")
3575 (test-ps-js lexical-funargs-shadow1
3576 (lambda (x)
3577 (let ((x 1))
3578 (foo x))
3579 (incf x))
3580 "(function (x) {
3581 var x1 = 1;
3582 foo(x1);
3583 return ++x;
3584 });")
3586 (test-ps-js times-rem
3587 (* x (rem y z))
3588 "x * (y % z);")
3590 (test-ps-js rem-divide
3591 (/ x (rem y z))
3592 "x / (y % z);")
3594 (test-ps-js case-break-return
3595 (lambda () (case x (:foo) (:bar 1)))
3596 "(function () {
3597 switch (x) {
3598 case 'foo':
3599 return null;
3600 case 'bar':
3601 return 1;
3603 });")
3605 (test-ps-js trivial-expression-switch
3606 (foobar (case x (1 2)))
3607 "foobar((function () {
3608 switch (x) {
3609 case 1:
3610 return 2;
3612 })());")
3614 (test-ps-js trivial-expression-while
3615 (foobar (while (< 0 x) (decf x)))
3616 "foobar((function () {
3617 while (0 < x) {
3618 --x;
3620 })());")
3622 (test-ps-js funcall-block-expression-loop-lambda
3623 (foobar (loop for i from 0 to 10 do (1+ i)))
3624 "foobar((function () {
3625 for (var i = 0; i <= 10; i += 1) {
3626 i + 1;
3628 })());")
3630 (test-ps-js plus-block-expression-loop-lambda
3631 (1+ (loop for i from 0 to 10 do (1+ i)))
3632 "(function () {
3633 for (var i = 0; i <= 10; i += 1) {
3634 i + 1;
3636 })() + 1;")
3638 (test-ps-js let-closures-rename
3639 (lambda ()
3640 (let ((x 1)) (lambda () (1+ x)))
3641 (let ((x 2)) (lambda () (1+ x))))
3642 "(function () {
3643 var x = 1;
3644 function () {
3645 return x + 1;
3647 var x1 = 2;
3648 return function () {
3649 return x1 + 1;
3651 });")
3653 (test-ps-js let-closures-rename1
3654 (lambda ()
3655 (let ((x 1))
3656 (let ((y 2))
3657 (lambda () (+ x y))))
3658 (let ((x 2))
3659 (let ((y 3))
3660 (lambda () (+ x y)))))
3661 "(function () {
3662 var x = 1;
3663 var y = 2;
3664 function () {
3665 return x + y;
3667 var x1 = 2;
3668 var y2 = 3;
3669 return function () {
3670 return x1 + y2;
3672 });")
3674 (test-ps-js let-closures-rename2
3675 (defun make-closures ()
3676 (list
3677 (let ((x 1)) (lambda () (1+ x)))
3678 (let ((x 2)) (lambda () (1+ x)))))
3679 "function makeClosures() {
3680 var x;
3681 var x1;
3682 return [(x = 1, function () {
3683 return x + 1;
3684 }), (x1 = 2, function () {
3685 return x1 + 1;
3686 })];
3688 };")
3690 (test-ps-js conditional-not-used-up
3691 (lambda (bar)
3692 (when bar
3693 (let ((x 1))
3694 (1+ x))))
3695 "(function (bar) {
3696 if (bar) {
3697 var x = 1;
3698 return x + 1;
3700 });")
3702 (test-ps-js toplevel-local-scope
3703 (create "fn" (let ((x 5)) (lambda () x)))
3704 "({ 'fn' : (function () {
3705 var x = 5;
3706 return function () {
3707 return x;
3709 })() });")
3711 (test-ps-js toplevel-local-scope1
3712 (defvar foo (create "fn" (let ((x 5)) (lambda () x))))
3713 "var foo = { 'fn' : (function () {
3714 var x = 5;
3715 return function () {
3716 return x;
3718 })() };")
3720 (test-ps-js block-let
3721 (block foobar
3722 (let ((x 1))
3723 (return-from foobar x)
3725 "(function () {
3726 var x = 1;
3727 return x;
3728 return 2;
3729 })();")
3731 (test-ps-js expressionize-if-macroexpand-error
3732 (progn (defmacro xbaz () `(blah))
3734 (defun foo (xbaz)
3735 (unless (blah)
3736 (cond (xbaz (blah))
3737 (t (blahblah))))))
3738 "function foo(xbaz) {
3739 if (!blah()) {
3740 if (xbaz) {
3741 return blah();
3742 } else {
3743 return blahblah();
3746 };")
3748 (test-ps-js toplevel-defun-macroexpand
3749 (progn (defmacro defun-js (name lambda-list &body body)
3750 `(defun ,name ,lambda-list ,@body))
3752 (let ((foo 0))
3753 (defun-js bar () (1+ foo))
3754 (defvar baz 2)))
3755 "var foo = 0;
3756 function bar() {
3757 return foo + 1;
3759 var baz = 2;")
3761 (test-ps-js js-ir-package-unique-symbols
3762 (loop :for i :from 0 :below 5 :do
3763 (let ((block (elt blocks i)))
3764 (foo block)
3765 (lambda () nil)))
3766 "(function () {
3767 for (var i = 0; i < 5; i += 1) {
3768 var block = blocks[i];
3769 foo(block);
3770 function () {
3771 return null;
3774 })();")
3776 (test-ps-js broken-quote-expansion1
3777 (lambda (p)
3778 (with-slots (x y) p
3779 (if (< x 0) y x)))
3780 "(function (p) {
3781 return p.x < 0 ? p.y : p.x;
3782 });")
3784 (test-ps-js broken-quote-expansion2
3785 (progn
3786 (define-symbol-macro foo123 (ps:@ a foo123))
3787 (lambda () (when (> foo123 1) 2)))
3788 "(function () {
3789 return a.foo123 > 1 ? 2 : null;
3790 });")
3792 (test-ps-js unused-named-block-not-printed1
3793 (block foobar
3794 (+ 1 2 3))
3795 "(function () {
3796 return 1 + 2 + 3;
3797 })();")
3799 (test-ps-js unused-named-block-not-printed2
3800 (block nil
3801 (block nil
3802 (+ 1 2 3)))
3803 "(function () {
3804 return 1 + 2 + 3;
3805 })();")
3807 (test-ps-js unused-named-block-not-printed3
3808 (block foobar
3809 (block nil
3810 (+ 1 2 3)))
3811 "(function () {
3812 return 1 + 2 + 3;
3813 })();")
3815 (test-ps-js unused-named-block-not-printed4
3816 (block nil
3817 (block foobar
3818 (block nil
3819 (+ 1 2 3))))
3820 "(function () {
3821 return 1 + 2 + 3;
3822 })();")
3824 (test-ps-js trig-no-bind1
3825 (cosh 3.14)
3826 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
3828 (test-ps-js trig-bind1
3829 (acosh (blah 3.14))
3830 "(function () {
3831 var x1 = blah(3.14);
3832 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
3833 })();")
3835 ;;; broken
3837 ;; (test-ps-js let-defun-toplevel
3838 ;; (progn (let ((foo 0))
3839 ;; (defun bar () foo))
3840 ;; (bar))
3841 ;; "var bar_foo1 = 0;
3842 ;; function bar() {
3843 ;; return bar_foo1;
3844 ;; };
3845 ;; bar();")
3847 ;; (test-ps-js let-defvar-toplevel
3848 ;; (progn (let ((foo 0))
3849 ;; (defvar bar (1+ foo)))
3850 ;; bar)
3851 ;; "var bar_foo1 = 0;
3852 ;; var bar = bar_foo1 + 1;
3853 ;; bar;")
3855 ;; (test-ps-js setf-side-effects
3856 ;; (progn
3857 ;; (let ((x 10))
3858 ;; (defun side-effect()
3859 ;; (setf x 4)
3860 ;; 3)
3861 ;; (setf x (+ 2 (side-effect) x 5))))
3862 ;; "var sideEffect_x1 = 10;
3863 ;; function sideEffect() {
3864 ;; sideEffect_x1 = 4;
3865 ;; return 3;
3866 ;; };
3867 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")