Replaced FiveAM with EOS (EOS is a drop-in replacement with better code and no depend...
[parenscript.git] / t / output-tests.lisp
blob28f28d4d1bca9529aad8035f1b023ac149005be3
1 ;; Copying and distribution of this file, with or without modification,
2 ;; are permitted in any medium without royalty provided the copyright
3 ;; notice and this notice are preserved. This file is offered as-is,
4 ;; without any warranty.
6 (in-package #:ps-test)
7 (named-readtables:in-readtable :parenscript)
9 (in-suite output-tests)
11 (test-ps-js statements-and-expressions-1
12 (+ i (if 1 2 3))
13 "i + (1 ? 2 : 3);")
15 (test-ps-js statements-and-expressions-2
16 (if 1 2 3)
17 "if (1) {
19 } else {
21 };")
23 (test-ps-js symbol-conversion-1
24 !?#@%
25 "bangwhathashatpercent;")
27 (test-ps-js symbol-conversion-2
28 bla-foo-bar
29 "blaFooBar;")
31 (test-ps-js symbol-conversion-3
32 *array
33 "Array;")
35 (test-ps-js symbol-conversion-4
36 *global-array*
37 "GLOBALARRAY;")
39 (test-ps-js number-literals-1
41 "1;")
43 (test-ps-js number-literals-2
44 123.123
45 "123.123;")
47 (test-ps-js number-literals-3
48 #x10
49 "16;")
51 (test-ps-js string-literals-1
52 "foobar"
53 "'foobar';")
55 (test-ps-js string-literals-2
56 "bratzel bub"
57 "'bratzel bub';")
59 (test-ps-js string-literals-3
60 " "
61 "'\\t';")
63 (test-ps-js array-literals-1
64 (array)
65 "[ ];")
67 (test-ps-js array-literals-2
68 (array 1 2 3)
69 "[ 1, 2, 3 ];")
71 (test-ps-js array-literals-3
72 (array (array 2 3)
73 (array "foobar" "bratzel bub"))
74 "[ [ 2, 3 ], [ 'foobar', 'bratzel bub' ] ];")
76 (test-ps-js array-literals-4
77 (make-array)
78 "new Array();")
80 (test-ps-js array-literals-5
81 (make-array 1 2 3)
82 "new Array(1, 2, 3);")
84 (test-ps-js array-literals-6
85 (make-array
86 (make-array 2 3)
87 (make-array "foobar" "bratzel bub"))
88 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
90 (test-ps-js object-literals-1
91 (create foo "bar" :blorg 1)
92 "{ foo : 'bar', 'blorg' : 1 };")
94 (test-ps-js object-literals-2
95 (create foo "hihi"
96 blorg (array 1 2 3)
97 another-object (create :schtrunz 1))
98 "{ foo : 'hihi',
99 blorg : [ 1, 2, 3 ],
100 anotherObject : { 'schtrunz' : 1 } };")
102 (test-ps-js object-literals-3
103 (getprop an-object 'foo)
104 "anObject.foo;")
106 (test-ps-js object-literals-4
107 (@ an-object foo bar)
108 "anObject.foo.bar;")
110 (test-ps-js object-literals-5
111 (with-slots (a b c) this
112 (+ a b c))
113 "this.a + this.b + this.c;")
115 (test-ps-js regular-expression-literals-1
116 (regex "foobar")
117 "/foobar/;")
119 (test-ps-js regular-expression-literals-2
120 (regex "/foobar/i")
121 "/foobar/i;")
123 (test-ps-js literal-symbols-1
125 "true;")
127 (test-ps-js literal-symbols-2
128 false
129 "false;")
131 (test-ps-js literal-symbols-3
133 "false;")
135 (test-ps-js literal-symbols-4
136 (lambda () nil)
137 "function () {
138 return null;
139 };")
141 (test-ps-js literal-symbols-5
142 undefined
143 "undefined;")
145 (test-ps-js literal-symbols-6
146 this
147 "this;")
149 (test-ps-js variables-1
150 variable
151 "variable;")
153 (test-ps-js variables-2
154 a-variable
155 "aVariable;")
157 (test-ps-js variables-3
158 *math
159 "Math;")
161 (test-ps-js function-calls-and-method-calls-1
162 (blorg 1 2)
163 "blorg(1, 2);")
165 (test-ps-js function-calls-and-method-calls-2
166 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
167 "foobar(blorg(1, 2), blabla(3, 4), [ 2, 3, 4 ]);")
169 (test-ps-js function-calls-and-method-calls-3
170 ((getprop this 'blorg) 1 2)
171 "this.blorg(1, 2);")
173 (test-ps-js function-calls-and-method-calls-4
174 ((aref foo i) 1 2)
175 "foo[i](1, 2);")
177 (test-ps-js function-calls-and-method-calls-5
178 ((getprop (aref foobar 1) 'blorg) nil t)
179 "foobar[1].blorg(null, true);")
181 (test-ps-js operator-expressions-1
182 (* 1 2)
183 "1 * 2;")
185 (test-ps-js operator-expressions-2
186 (= 1 2)
187 "1 === 2;")
189 (test-ps-js operator-expressions-3
190 (* 1 (+ 2 3 4) 4 (/ 6 7))
191 "1 * (2 + 3 + 4) * 4 * 6 / 7;")
193 (test-ps-js operator-expressions-4
194 (incf i)
195 "++i;")
197 (test-ps-js operator-expressions-5
198 (decf i)
199 "--i;")
201 (test-ps-js operator-expressions-6
202 (1- i)
203 "i - 1;")
205 (test-ps-js operator-expressions-7
206 (1+ i)
207 "i + 1;")
209 (test-ps-js operator-expressions-8
210 (not (< i 2))
211 "i >= 2;")
213 (test-ps-js body-forms-1
214 (progn (blorg i) (blafoo i))
215 "blorg(i);
216 blafoo(i);")
218 (test-ps-js body-forms-2
219 (+ i (progn (blorg i) (blafoo i)))
220 "i + (blorg(i), blafoo(i));")
222 (test-ps-js function-definition-1
223 (defun a-function (a b)
224 (+ a b))
225 "function aFunction(a, b) {
226 return a + b;
227 };")
229 (test-ps-js function-definition-2
230 (lambda (a b) (+ a b))
231 "function (a, b) {
232 return a + b;
233 };")
235 (test-ps-js assignment-1
236 (setf a 1)
237 "a = 1;")
239 (test-ps-js assignment-2
240 (setf a 2 b 3 c 4 x (+ a b c))
241 "a = 2;
242 b = 3;
243 c = 4;
244 x = a + b + c;")
246 (test-ps-js assignment-3
247 (setf a (+ a 2 3 4 a))
248 "a = a + 2 + 3 + 4 + a;")
250 (test-ps-js assignment-4
251 (setf a (- 1 a))
252 "a = 1 - a;")
254 (test-ps-js assignment-5
255 (let ((a 1) (b 2))
256 (psetf a b b a))
257 "var a = 1;
258 var b = 2;
259 var _js1 = b;
260 var _js2 = a;
261 a = _js1;
262 b = _js2;")
264 (test-ps-js assignment-6
265 (setq a 1)
266 "a = 1;")
268 (test-ps-js assignment-8
269 (progn
270 (defun (setf color) (new-color el)
271 (setf (getprop (getprop el 'style) 'color) new-color))
272 (setf (color some-div) (+ 23 "em")))
273 "function __setf_color(newColor, el) {
274 return el.style.color = newColor;
276 __setf_color(23 + 'em', someDiv);")
278 (test-ps-js assignment-10
279 (progn
280 (defsetf left (el) (offset)
281 `(setf (getprop (getprop ,el 'style) 'left) ,offset))
282 (setf (left some-div) (+ 123 "px")))
283 "var _js2 = someDiv;
284 var _js1 = 123 + 'px';
285 _js2.style.left = _js1;")
287 (test-ps-js assignment-12
288 (macrolet ((left (el)
289 `(getprop ,el 'offset-left)))
290 (left some-div))
291 "someDiv.offsetLeft;")
293 (test-ps-js nil-block-return-1
294 (block nil (return))
295 "nilBlock: {
296 break nilBlock;
297 };")
299 (test-ps-js single-argument-statements-2
300 (throw "foobar")
301 "throw 'foobar';")
303 (test-ps-js single-argument-expression-1
304 (delete (new (*foobar 2 3 4)))
305 "delete new Foobar(2, 3, 4);")
307 (test-ps-js single-argument-expression-2
308 (if (= (typeof blorg) *string)
309 (alert (+ "blorg is a string: " blorg))
310 (alert "blorg is not a string"))
311 "if (typeof blorg === String) {
312 alert('blorg is a string: ' + blorg);
313 } else {
314 alert('blorg is not a string');
315 };")
317 (test-ps-js conditional-statements-1
318 (defun foo ()
319 (if ((@ blorg is-correct))
320 (progn (carry-on) (return-from foo i))
321 (alert "blorg is not correct!")))
322 "function foo() {
323 if (blorg.isCorrect()) {
324 carryOn();
325 return i;
326 } else {
327 return alert('blorg is not correct!');
329 };")
331 (test-ps-js conditional-statements-2
332 (+ i (if ((@ blorg add-one)) 1 2))
333 "i + (blorg.addOne() ? 1 : 2);")
335 (test-ps-js conditional-statements-3
336 (defun foo ()
337 (when ((@ blorg is-correct))
338 (carry-on)
339 (return-from foo i)))
340 "function foo() {
341 if (blorg.isCorrect()) {
342 carryOn();
343 return i;
345 };")
347 (test-ps-js conditional-statements-4
348 (unless ((@ blorg is-correct))
349 (alert "blorg is not correct!"))
350 "if (!blorg.isCorrect()) {
351 alert('blorg is not correct!');
352 };")
354 (test-ps-js variable-declaration-1
355 (defvar *a* (array 1 2 3))
356 "var A = [ 1, 2, 3 ];")
358 (test-ps-js variable-declaration-2
359 (progn
360 (defvar *a* 4)
361 (let ((x 1)
362 (*a* 2))
363 (let* ((y (+ x 1))
364 (x (+ x y)))
365 (+ *a* x y))))
366 "var A = 4;
367 var x = 1;
368 var A_TMPSTACK1;
369 try {
370 A_TMPSTACK1 = A;
371 A = 2;
372 var y = x + 1;
373 var x2 = x + y;
374 A + x2 + y;
375 } finally {
376 A = A_TMPSTACK1;
377 };")
379 (test-ps-js iteration-constructs-1
380 (do* ((a) b (c (array "a" "b" "c" "d" "e"))
381 (d 0 (1+ d))
382 (e (aref c d) (aref c d)))
383 ((or (= d (@ c length)) (string= e "x")))
384 (setf a d b e)
385 (funcall (@ document write) (+ "a: " a " b: " b "<br/>")))
386 "for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d]; !(d === c.length || e === 'x'); d += 1, e = c[d]) {
387 a = d;
388 b = e;
389 document.write('a: ' + a + ' b: ' + b + '<br/>');
390 };")
392 (test-ps-js iteration-constructs-2
393 (do ((i 0 (1+ i))
394 (s 0 (+ s i (1+ i))))
395 ((> i 10))
396 (funcall (@ document write) (+ "i: " i " s: " s "<br/>")))
397 "var i = 0;
398 var s = 0;
399 for (; i <= 10; ) {
400 document.write('i: ' + i + ' s: ' + s + '<br/>');
401 var _js1 = i + 1;
402 var _js2 = s + i + i + 1;
403 i = _js1;
404 s = _js2;
405 };")
407 (test-ps-js iteration-constructs-3
408 (do* ((i 0 (1+ i))
409 (s 0 (+ s i (1- i))))
410 ((> i 10))
411 ((@ document write) (+ "i: " i " s: " s "<br/>")))
412 "for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + i - 1) {
413 document.write('i: ' + i + ' s: ' + s + '<br/>');
414 };")
416 (test-ps-js iteration-constructs-4
417 (let ((arr (array "a" "b" "c" "d" "e")))
418 (dotimes (i (@ arr length))
419 ((@ document write) (+ "i: " i " arr[i]: " (aref arr i) "<br/>"))))
420 "var arr = ['a', 'b', 'c', 'd', 'e'];
421 for (var i = 0; i < arr.length; i += 1) {
422 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
423 };")
425 (test-ps-js iteration-constructs-5
426 (let ((res 0))
427 (alert (+ "Summation to 10 is "
428 (dotimes (i 10 res)
429 (incf res (1+ i))))))
430 "var res = 0;
431 alert('Summation to 10 is ' + (function () {
432 for (var i = 0; i < 10; i += 1) {
433 res += i + 1;
435 return res;
436 })());")
438 (test-ps-js iteration-constructs-6
439 (let ((l (list 1 2 4 8 16 32)))
440 (dolist (c l)
441 ((@ document write) (+ "c: " c "<br/>"))))
442 "var l = [1, 2, 4, 8, 16, 32];
443 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
444 c = l[_js_idx1];
445 document.write('c: ' + c + '<br/>');
446 };")
448 (test-ps-js iteration-constructs-7
449 (let ((l '(1 2 4 8 16 32))
450 (s 0))
451 (alert (+ "Sum of " l " is: "
452 (dolist (c l s)
453 (incf s c)))))
454 "var l = [1, 2, 4, 8, 16, 32];
455 var s = 0;
456 alert('Sum of ' + l + ' is: ' + (function () {
457 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
458 c = l[_js_idx1];
459 s += c;
461 return s;
462 })());")
464 (test-ps-js iteration-constructs-8
465 (let ((obj (create a 1 b 2 c 3)))
466 (for-in (i obj)
467 ((@ document write) (+ i ": " (aref obj i) "<br/>"))))
468 "var obj = { a : 1, b : 2, c : 3 };
469 for (var i in obj) {
470 document.write(i + ': ' + obj[i] + '<br/>');
471 };")
473 (test-ps-js iteration-constructs-9
474 (while ((@ film is-not-finished))
475 ((@ this eat) (new *popcorn)))
476 "while (film.isNotFinished()) {
477 this.eat(new Popcorn);
478 };")
480 (test-ps-js the-case-statement-1
481 (case (aref blorg i)
482 ((1 "one") (alert "one"))
483 (2 (alert "two"))
484 (t (alert "default clause")))
485 "switch (blorg[i]) {
486 case 1:
487 case 'one':
488 alert('one');
489 break;
490 case 2:
491 alert('two');
492 break;
493 default:
494 alert('default clause');
495 };")
497 (test-ps-js the-case-statement-2
498 (switch (aref blorg i)
499 (1 (alert "If I get here"))
500 (2 (alert "I also get here"))
501 (default (alert "I always get here")))
502 "switch (blorg[i]) {
503 case 1: alert('If I get here');
504 case 2: alert('I also get here');
505 default: alert('I always get here');
506 };")
508 (test-ps-js the-try-statement-1
509 (try (throw "i")
510 (:catch (error)
511 (alert (+ "an error happened: " error)))
512 (:finally
513 (alert "Leaving the try form")))
514 "try {
515 throw 'i';
516 } catch (error) {
517 alert('an error happened: ' + error);
518 } finally {
519 alert('Leaving the try form');
520 };")
522 (test-ps-js the-html-generator-1
523 (ps-html ((:a :href "foobar") "blorg"))
524 "'<A HREF=\"foobar\">blorg</A>';")
526 (test-ps-js the-html-generator-2
527 (ps-html ((:a :href (generate-a-link)) "blorg"))
528 "['<A HREF=\"', generateALink(), '\">blorg</A>']['join']('');")
530 (test-ps-js the-html-generator-3
531 (funcall (getprop document 'write)
532 (ps-html ((:a :href "#"
533 :onclick (ps-inline (transport))) "link")))
534 "document.write(['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">link</A>']['join'](''));")
536 (test-ps-js the-html-generator-4
537 (let ((disabled nil)
538 (authorized t))
539 (setf (getprop element 'inner-h-t-m-l)
540 (ps-html ((:textarea (or disabled (not authorized)) :disabled "disabled")
541 "Edit me"))))
542 "var disabled = null;
543 var authorized = true;
544 element.innerHTML = ['<TEXTAREA', disabled || !authorized ? [' DISABLED=\"', 'disabled', '\"']['join']('') : '', '>Edit me</TEXTAREA>']['join']('');")
546 (test-ps-js plus-is-not-commutative
547 (setf x (+ "before" x "after"))
548 "x = 'before' + x + 'after';")
550 (test-ps-js plus-works-if-first
551 (setf x (+ x "middle" "after"))
552 "x = x + 'middle' + 'after';")
554 (test-ps-js setf-side-effects
555 (progn
556 (let ((x 10))
557 (defun side-effect()
558 (setf x 4)
560 (setf x (+ 2 (side-effect) x 5))))
561 "var x = 10;
562 function sideEffect() {
563 x = 4;
564 return 3;
566 x = 2 + sideEffect() + x + 5;")
568 (test-ps-js method-call-op-form
569 (funcall (getprop (+ "" x) 'to-string))
570 "('' + x).toString();")
572 (test-ps-js method-call-op-form-args
573 (funcall (getprop (+ "" x) 'foo) 1 2 :baz 3)
574 "('' + x).foo(1, 2, 'baz', 3);")
576 (test-ps-js method-call-string
577 ((getprop "hi" 'to-string))
578 "'hi'.toString();")
580 (test-ps-js method-call-conditional
581 ((if a x y) 1)
582 "(a ? x : y)(1);")
584 (test-ps-js method-call-variable
585 ((@ x to-string))
586 "x.toString();")
588 (test-ps-js method-call-array
589 ((@ (list 10 20) to-string))
590 "[ 10, 20 ].toString();")
592 (test-ps-js method-call-lambda-call
593 (funcall (getprop (funcall (lambda (x) x) 10) 'to-string))
594 "(function (x) { return x; })(10).toString();")
596 (test no-whitespace-before-dot
597 (let* ((str (ps* '((@ ((lambda (x) x) 10) to-string))))
598 (dot-pos (position #\. str :test #'char=))
599 (char-before (elt str (1- dot-pos)))
600 (a-parenthesis #\)))
601 (is (char= char-before a-parenthesis))))
603 (test-ps-js simple-getprop
604 (let ((foo (create a 1)))
605 (alert (getprop foo 'a)))
606 "var foo = { a : 1 };
607 alert(foo.a);")
609 (test-ps-js buggy-getprop
610 (getprop foo slot-name)
611 "foo[slotName];")
613 (test-ps-js buggy-getprop-two
614 (getprop foo (get-slot-name))
615 "foo[getSlotName()];")
617 (test-ps-js old-case-is-now-switch
618 ;; Switch was "case" before, but that was very non-lispish.
619 ;; For example, this code makes three messages and not one
620 ;; which may have been expected. This is because a switch
621 ;; statment must have a break statement for it to return
622 ;; after the alert. Otherwise it continues on the next
623 ;; clause.
624 (switch (aref blorg i)
625 (1 (alert "one"))
626 (2 (alert "two"))
627 (default (alert "default clause")))
628 "switch (blorg[i]) {
629 case 1: alert('one');
630 case 2: alert('two');
631 default: alert('default clause');
632 };")
634 (test-ps-js lisp-like-case
635 (case (aref blorg i)
636 (1 (alert "one"))
637 (2 (alert "two"))
638 (default (alert "default clause")))
639 "switch (blorg[i]) {
640 case 1:
641 alert('one');
642 break;
643 case 2:
644 alert('two');
645 break;
646 default: alert('default clause');
647 };")
650 (test-ps-js even-lispier-case
651 (case (aref blorg i)
652 ((1 2) (alert "Below three"))
653 (3 (alert "Three"))
654 (t (alert "Something else")))
655 "switch (blorg[i]) {
656 case 1:
657 case 2:
658 alert('Below three');
659 break;
660 case 3:
661 alert('Three');
662 break;
663 default: alert('Something else');
664 };")
666 (test-ps-js otherwise-case
667 (case (aref blorg i)
668 (1 (alert "one"))
669 (otherwise (alert "default clause")))
670 "switch (blorg[i]) {
671 case 1:
672 alert('one');
673 break;
674 default: alert('default clause');
675 };")
677 (test escape-sequences-in-string
678 (let ((escapes `((#\\ . #\\)
679 (#\b . #\Backspace)
680 (#\f . ,(code-char 12))
681 ("u000B" . ,(code-char #x000b));;Vertical tab, too uncommon to bother with
682 (#\n . #\Newline)
683 (#\r . #\Return)
684 (#\' . #\');;Double quote need not be quoted because parenscript strings are single quoted
685 (#\t . #\Tab)
686 ("u001F" . ,(code-char #x001f));; character below 32
687 ("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
688 ("uABCD" . ,(code-char #xabcd)))));; Really above ascii.
689 (loop for (js-escape . lisp-char) in escapes
690 for generated = (ps-doc* `(let ((x ,(format nil "hello~ahi" lisp-char)))))
691 for wanted = (format nil "var x = 'hello\\~ahi';" js-escape)
692 do (is (string= (normalize-js-code generated) wanted)))))
694 (test-ps-js getprop-setf
695 (setf (getprop x 'y) (+ (+ a 3) 4))
696 "x.y = a + 3 + 4;")
698 (test-ps-js getprop-conditional1
699 (getprop (if zoo foo bar) 'x)
700 "(zoo ? foo : bar).x;")
702 (test-ps-js getprop-conditional2
703 (getprop (if (not zoo) foo bar) 'x)
704 "(!zoo ? foo : bar).x;")
706 (test script-star-eval1
707 (is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x 1) '(setf y 2))))))
709 (test script-star-eval2
710 (is (string= "x = 1;" (normalize-js-code (ps* '(setf x 1))))))
712 (test-ps-js list-with-single-nil
713 (array nil)
714 "[null];")
716 (test-ps-js quoted-nil-is-array
717 'nil
718 "[];")
720 (test-ps-js defsetf1
721 (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
722 (setf (baz 1 2) 3))
723 "var _js2 = 1;
724 var _js3 = 2;
725 var _js1 = 3;
726 setBaz(_js2, _js3, _js1);")
728 (test-ps-js setf-macroexpands1
729 (macrolet ((bar (x y)
730 `(aref ,x ,y 1)))
731 (setf (bar foo 2) 3))
732 "foo[2][1] = 3;")
734 (test-ps-js defsetf-short
735 (progn (defsetf baz set-baz "docstring")
736 (setf (baz 1 2 3) "foo"))
737 "setBaz(1, 2, 3, 'foo');")
739 (test-ps-js defun-setf1
740 (progn (defun (setf some-thing) (new-val i1 i2)
741 (setf (aref *some-thing* i1 i2) new-val))
742 (setf (some-thing 1 2) "foo"))
743 "function __setf_someThing(newVal, i1, i2) {
744 return SOMETHING[i1][i2] = newVal;
746 __setf_someThing('foo', 1, 2);")
748 (test-ps-js defun-optional1
749 (defun test-opt (&optional x)
750 (if x "yes" "no"))
751 "function testOpt(x) {
752 return x ? 'yes' : 'no';
753 };")
755 (test-ps-js defun-optional2
756 (defun foo (x &optional y)
757 (+ x y))
758 "function foo(x, y) {
759 return x + y;
760 };")
762 (test-ps-js defun-optional3
763 (defun blah (&optional (x 0))
765 "function blah(x) {
766 if (x === undefined) {
767 x = 0;
769 return x;
770 };")
772 (test-ps-js defun-optional4
773 (lambda (&optional (x 0 supplied?))
775 "function (x) {
776 var suppliedwhat = x !== undefined;
777 if (!suppliedwhat) {
778 x = 0;
780 return x;
781 };")
783 (test-ps-js return-nothing
784 (defun foo () (return-from foo))
785 "function foo() {
786 return null;
787 };")
789 (test-ps-js set-timeout
790 (set-timeout (lambda () (alert "foo")) 10)
791 "setTimeout(function () { return alert('foo'); }, 10);")
793 (test-ps-js operator-precedence
794 (* 3 (+ 4 5) 6)
795 "3 * (4 + 5) * 6;")
797 (test-ps-js operators-1
798 (in prop obj)
799 "prop in obj;")
801 (test-ps-js incf1
802 (incf foo bar)
803 "foo += bar;")
805 (test-ps-js decf1
806 (decf foo bar)
807 "foo -= bar;")
809 (test-ps-js incf2
810 (incf x 5)
811 "x += 5;")
813 (test-ps-js decf2
814 (decf y 10)
815 "y -= 10;")
817 (test-ps-js setf-conditional
818 (setf foo (if x 1 2))
819 "foo = x ? 1 : 2;")
821 (test-ps-js obj-literal-numbers
822 (create 1 "foo")
823 "{ 1 : 'foo' };")
825 (test-ps-js obj-literal-strings
826 (create "foo" 2)
827 "{ 'foo' : 2 };")
829 (test-ps-js getprop-string
830 (getprop foo "bar")
831 "foo['bar'];")
833 (test-ps-js getprop-string1
834 (getprop "bar" 'length)
835 "'bar'.length;")
837 (test-ps-js getprop-progn
838 (getprop (progn (some-fun "abc") "123") "length")
839 "(someFun('abc'), '123')['length'];")
841 (test-ps-js method-call-block
842 ((@ (progn (some-fun "abc") "123") to-string))
843 "(someFun('abc'), '123').toString();")
845 (test-ps-js create-blank
846 (create)
847 "{ };")
849 (test-ps-js blank-object-literal
851 "{ };")
853 (test-ps-js array-literal1
855 "[];")
857 (test-ps-js array-literal2
858 ([])
859 "[];")
861 (test-ps-js array-literal3
862 ([] 1 2 3)
863 "[1, 2, 3];")
865 (test-ps-js array-literal4
866 ([] 1 (2 3))
867 "[1, [2, 3]];")
869 (test-ps-js array-literal5
870 ([] (1 2) ("a" "b"))
871 "[[1, 2], ['a', 'b']];")
873 (test-ps-js defun-rest1
874 (defun foo (&rest bar)
875 (alert (aref bar 1)))
876 "function foo() {
877 var bar = [];
878 for (var i1 = 0; i1 < arguments.length - 0; i1 += 1) {
879 bar[i1] = arguments[i1 + 0];
881 return alert(bar[1]);
882 };")
884 (test-ps-js defun-rest2
885 (defun foo (baz &rest bar) (+ baz (aref bar 1)))
886 "function foo(baz) {
887 var bar = [];
888 for (var i1 = 0; i1 < arguments.length - 1; i1 += 1) {
889 bar[i1] = arguments[i1 + 1];
891 return baz + bar[1];
892 };")
894 (test-ps-js defun-keyword1
895 (defun zoo (foo bar &key baz) (+ foo bar baz))
896 "function zoo(foo, bar) {
897 var _js2 = arguments.length;
898 for (var n1 = 2; n1 < _js2; n1 += 2) {
899 switch (arguments[n1]) {
900 case 'baz':
901 baz = arguments[n1 + 1];
904 var baz;
905 return foo + bar + baz;
906 };")
908 (test-ps-js defun-keyword2
909 (defun zoo (&key baz) (* baz baz))
910 "function zoo() {
911 var _js2 = arguments.length;
912 for (var n1 = 0; n1 < _js2; n1 += 2) {
913 switch (arguments[n1]) {
914 case 'baz':
915 baz = arguments[n1 + 1];
918 var baz;
919 return baz * baz;
920 };")
922 (test-ps-js defun-keyword3
923 (defun zoo (&key baz (bar 4)) (* baz bar))
924 "function zoo() {
925 var _js2 = arguments.length;
926 for (var n1 = 0; n1 < _js2; n1 += 2) {
927 switch (arguments[n1]) {
928 case 'baz':
929 baz = arguments[n1 + 1];
930 break;
931 case 'bar':
932 bar = arguments[n1 + 1];
935 var baz;
936 var bar = undefined === bar ? 4 : bar;
937 return baz * bar;
938 };")
940 (test-ps-js defun-keyword4
941 (defun hello-world (&key ((:my-name-key my-name) 1))
942 my-name)
943 "function helloWorld() {
944 var _js2 = arguments.length;
945 for (var n1 = 0; n1 < _js2; n1 += 2) {
946 switch (arguments[n1]) {
947 case 'my-name-key':
948 myName = arguments[n1 + 1];
951 var myName = undefined === myName ? 1 : myName;
952 return myName;
953 };")
955 (test-ps-js defun-keyword-supplied
956 (lambda (&key (foo 1 supplied?))
957 foo)
958 "function () {
959 var _js2 = arguments.length;
960 for (var n1 = 0; n1 < _js2; n1 += 2) {
961 switch (arguments[n1]) {
962 case 'foo':
963 foo = arguments[n1 + 1];
964 suppliedwhat = true;
967 var suppliedwhat;
968 var foo = undefined === foo ? 1 : foo;
969 return foo;
970 };")
972 (test-ps-js keyword-funcall1
973 (func :baz 1)
974 "func('baz', 1);")
976 (test-ps-js keyword-funcall2
977 (func :baz 1 :bar foo)
978 "func('baz', 1, 'bar', foo);")
980 (test-ps-js keyword-funcall3
981 (fun a b :baz c)
982 "fun(a, b, 'baz', c);")
984 (test-ps-js cond1
985 (cond ((= x 1) 1))
986 "if (x === 1) {
988 };")
990 (test-ps-js cond2
991 (cond ((= x 1) 2)
992 ((= y (* x 4)) (foo "blah") (* x y)))
993 "if (x === 1) {
995 } else if (y === x * 4) {
996 foo('blah');
997 x * y;
998 };")
1000 (test-ps-js if-exp-without-else-return
1001 (defun foo () (return-from foo (if x 1)))
1002 "function foo() {
1003 return x ? 1 : null;
1004 };")
1006 (test-ps-js progn-expression-single-statement
1007 (defun foo () (return-from foo (progn (* x y))))
1008 "function foo() {
1009 return x * y;
1010 };")
1012 (test-ps-js cond-expression1
1013 (defun foo ()
1014 (cond ((< 1 2) (bar "foo") (* 4 5))))
1015 "function foo() {
1016 if (1 < 2) {
1017 bar('foo');
1018 return 4 * 5;
1020 };")
1022 (test-ps-js cond-expression2
1023 (defun foo ()
1024 (cond ((< 2 1) "foo")
1025 ((= 7 7) "bar")))
1026 "function foo() {
1027 if (2 < 1) {
1028 return 'foo';
1029 } else if (7 === 7) {
1030 return 'bar';
1032 };")
1034 (test-ps-js cond-expression-final-t-clause
1035 (defun foo ()
1036 (cond ((< 1 2) (bar "foo") (* 4 5))
1037 ((= a b) (+ c d))
1038 ((< 1 2 3 4 5) x)
1039 (t "foo")))
1040 "function foo() {
1041 var _cmp3;
1042 var _cmp2;
1043 var _cmp1;
1044 if (1 < 2) {
1045 bar('foo');
1046 return 4 * 5;
1047 } else if (a === b) {
1048 return c + d;
1049 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1050 return x;
1051 } else {
1052 return 'foo';
1054 };")
1056 (test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
1057 (defun foo ()
1058 (cond ((< 2 1) 5)
1059 (t "foo")
1060 ((< 1 2) "bar")))
1061 "function foo() {
1062 if (2 < 1) {
1063 return 5;
1064 } else {
1065 return 'foo';
1067 };")
1069 (test-ps-js funcall-if-expression
1070 (funcall (getprop document 'write)
1071 (if (= *linkornot* 1)
1072 (ps-html ((:a :href "#"
1073 :onclick (ps-inline (transport)))
1074 img))
1075 img))
1076 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>']['join']('') : img);")
1078 (test-ps-js negate-number-literal
1079 (- 1)
1080 "-1;")
1082 (test macro-environment1
1083 (is (string= (normalize-js-code (let* ((macroname (gensym)))
1084 (ps* `(defmacro ,macroname (x) `(+ ,x 123))
1085 `(defun test1 ()
1086 (macrolet ((,macroname (x) `(aref data ,x)))
1087 (when (,macroname x)
1088 (setf (,macroname x) 123)))))))
1089 (normalize-js-code
1090 "function test1() {
1091 return data[x] ? (data[x] = 123) : null;
1092 };"))))
1094 (test macro-environment2
1095 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
1096 (defpsmacro macro-environment2-macro (x)
1097 `(+ ,outer-lexical-variable ,x))
1098 (ps* '(macro-environment2-macro 2))))
1099 (normalize-js-code "1 + 2;"))))
1101 (test-ps-js ampersand-whole-1
1102 (macrolet ((foo (&whole foo bar baz)
1103 (declare (ignore bar baz))
1104 (with-standard-io-syntax (format nil "~a" foo))))
1105 (foo 1 2))
1106 "'(FOO 1 2)';")
1108 (test-ps-js keyword-consistent
1110 "'x';")
1112 (test-ps-js simple-symbol-macrolet
1113 (symbol-macrolet ((x 1)) x)
1114 "1;")
1116 (test-ps-js compound-symbol-macrolet
1117 (symbol-macrolet ((x 123)
1118 (y (* 2 x)))
1120 "2 * 123;")
1122 (test-ps-js define-symbol-macro
1123 (progn (define-symbol-macro tst-sym-macro 2)
1124 tst-sym-macro)
1125 "2;")
1127 (test-ps-js define-symbol-macro1
1128 (progn (define-symbol-macro tst-sym-macro1 2)
1129 (foo tst-sym-macro1))
1130 "foo(2);")
1132 (test-ps-js expression-progn
1133 (1+ (progn (foo) (if x 1 2)))
1134 "(foo(), x ? 1 : 2) + 1;")
1136 (test-ps-js let-decl-in-expression
1137 (defun f (x)
1138 (if x 1 (let* ((foo x)) foo)))
1139 "function f(x) {
1140 if (x) {
1141 return 1;
1142 } else {
1143 var foo = x;
1144 return foo;
1146 };")
1148 (test-ps-js special-var1
1149 (progn (defvar *foo*)
1150 (let* ((*foo* 2))
1151 (* *foo* 2)))
1152 "var FOO;
1153 var FOO_TMPSTACK1;
1154 try {
1155 FOO_TMPSTACK1 = FOO;
1156 FOO = 2;
1157 FOO * 2;
1158 } finally {
1159 FOO = FOO_TMPSTACK1;
1160 };")
1162 (test-ps-js special-var2
1163 (progn (defvar *foo*)
1164 (let* ((*baz* 3)
1165 (*foo* 2))
1166 (* *foo* 2 *baz*)))
1167 "var FOO;
1168 var BAZ = 3;
1169 var FOO_TMPSTACK1;
1170 try {
1171 FOO_TMPSTACK1 = FOO;
1172 FOO = 2;
1173 FOO * 2 * BAZ;
1174 } finally {
1175 FOO = FOO_TMPSTACK1;
1176 };")
1178 (test-ps-js literal1
1179 (setf x undefined)
1180 "x = undefined;")
1182 (test-ps-js literal2
1183 (aref this x)
1184 "this[x];")
1186 (test-ps-js setf-dec1
1187 (setf x (- 1 x 2))
1188 "x = 1 - x - 2;")
1190 (test-ps-js setf-dec2
1191 (setf x (- x 1 2))
1192 "x = x - 1 - 2;")
1194 (test-ps-js special-char-equals
1195 blah=
1196 "blahequals;")
1198 (test-ps-js setf-operator-priority
1199 (defun foo ()
1200 (or (getprop cache id)
1201 (setf (getprop cache id) ((@ document get-element-by-id) id))))
1202 "function foo() {
1203 return cache[id] || (cache[id] = document.getElementById(id));
1204 };")
1206 (test-ps-js aref-operator-priority
1207 (aref (if (and x (> (length x) 0))
1208 (aref x 0)
1211 "(x && x.length > 0 ? x[0] : y)[z];")
1213 (test-ps-js aref-operator-priority1
1214 (aref (or (getprop x 'y)
1215 (getprop a 'b))
1217 "(x.y || a.b)[z];")
1219 (test-ps-js aref-operator-priority2
1220 (aref (if a b c) 0)
1221 "(a ? b : c)[0];")
1223 (test-ps-js negate-operator-priority
1224 (- (if x y z))
1225 "-(x ? y : z);")
1227 (test-ps-js op-p1
1228 (new (or a b))
1229 "new (a || b);")
1231 (test-ps-js op-p2
1232 (delete (if a (or b c) d))
1233 "delete (a ? b || c : d);")
1235 (test-ps-js op-p3
1236 (not (if (or x (not y)) z))
1237 "!(x || !y ? z : null);")
1239 (test-ps-js op-p4
1240 (- (- (* 1 2) 3))
1241 "-(1 * 2 - 3);")
1243 (test-ps-js op-p5
1244 (instanceof (or a b) (if x y z))
1245 "((a || b) instanceof (x ? y : z));")
1247 (test-ps-js op-p7
1248 (or x (if (= x 0) "zero" "empty"))
1249 "x || (x === 0 ? 'zero' : 'empty');")
1251 (test-ps-js named-op-expression
1252 (throw (if a b c))
1253 "throw a ? b : c;")
1255 (test-ps-js named-op-expression1
1256 (typeof (or x y))
1257 "typeof (x || y);")
1259 (test-ps-js aref-array-expression
1260 (aref (or a b c) 0)
1261 "(a || b || c)[0];")
1263 (test-ps-js getprop-operator
1264 (getprop (or a b c) 'd)
1265 "(a || b || c).d;")
1267 (test-ps-js getprop-parens
1268 (getprop (getprop foo 'bar) 'baz)
1269 "foo.bar.baz;")
1271 (test-ps-js funcall-funcall
1272 ((foo))
1273 "foo()();")
1275 (test-ps-js expression-funcall
1276 ((or (@ window eval) eval) foo nil)
1277 "(window.eval || eval)(foo, null);")
1279 (test-ps-js expression-funcall1
1280 (((or (@ window eval) eval) foo nil))
1281 "(window.eval || eval)(foo, null)();")
1283 (test-ps-js expression-funcall2
1284 (((or (@ window eval) eval)) foo nil)
1285 "(window.eval || eval)()(foo, null);")
1287 (test-ps-js who-html1
1288 (who-ps-html (:span :class "ticker-symbol"
1289 :ticker-symbol symbol
1290 (:a :href "http://foo.com"
1291 symbol)
1292 (:span :class "ticker-symbol-popup")))
1293 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>']['join']('');")
1295 (test-ps-js flet1
1296 ((lambda () (flet ((foo (x)
1297 (1+ x)))
1298 (foo 1))))
1299 "(function () {
1300 var foo = function (x) {
1301 return x + 1;
1303 return foo(1);
1304 })();")
1306 (test-ps-js flet2
1307 (flet ((foo (x) (1+ x))
1308 (bar (y) (+ 2 y)))
1309 (bar (foo 1)))
1310 "var foo = function (x) {
1311 return x + 1;
1313 var bar = function (y) {
1314 return 2 + y;
1316 bar(foo(1));")
1318 (test-ps-js flet3
1319 (flet ((foo (x) (+ 2 x)))
1320 (flet ((foo (x) (1+ x))
1321 (bar (y) (+ 2 (foo y))))
1322 (bar (foo 1))))
1323 "var foo = function (x) {
1324 return 2 + x;
1326 var foo1 = function (x) {
1327 return x + 1;
1329 var bar = function (y) {
1330 return 2 + foo(y);
1332 bar(foo1(1));")
1334 (test-ps-js labels1
1335 ((lambda () (labels ((foo (x)
1336 (if (= 0 x)
1338 (+ x (foo (1- x))))))
1339 (foo 3))))
1340 "(function () {
1341 var foo = function (x) {
1342 return 0 === x ? 0 : x + foo(x - 1);
1344 return foo(3);
1345 })();")
1347 (test-ps-js labels2
1348 (labels ((foo (x) (1+ (bar x)))
1349 (bar (y) (+ 2 (foo y))))
1350 (bar (foo 1)))
1351 "var foo = function (x) {
1352 return bar(x) + 1;
1354 var bar = function (y) {
1355 return 2 + foo(y);
1357 bar(foo(1));")
1359 (test-ps-js labels3
1360 (labels ((foo (x) (1+ x))
1361 (bar (y) (+ 2 (foo y))))
1362 (bar (foo 1)))
1363 "var foo = function (x) {
1364 return x + 1;
1366 var bar = function (y) {
1367 return 2 + foo(y);
1369 bar(foo(1));")
1371 (test-ps-js labels-lambda-list
1372 (labels ((foo (x &optional (y 0))
1373 (+ x y)))
1374 (foo 1))
1375 "var foo = function (x, y) {
1376 if (y === undefined) {
1377 y = 0;
1379 return x + y;
1381 foo(1);")
1383 (test-ps-js for-loop-var-init-exp
1384 ((lambda (x)
1385 (do* ((y (if x 0 1) (1+ y))
1386 (z 0 (1+ z)))
1387 ((= y 3) z)))
1388 true)
1389 "(function (x) {
1390 return (function () {
1391 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1393 return z;
1394 })();
1395 })(true);")
1397 (test-ps-js math-pi
1399 "Math.PI;")
1401 (test-ps-js literal-array
1402 '(1 2 3)
1403 "[1, 2, 3];")
1405 (test-ps-js literal-array-1
1406 '(1 foo 3)
1407 "[1, 'foo', 3];")
1409 (test ps-lisp-expands-in-lexical-environment
1410 (is (string= "5;" (let ((x 5)) (ps (lisp x))))))
1412 (test ps*-lisp-expands-in-null-lexical-environment
1413 (signals error (let ((x 5)) (declare (ignore x)) (ps* '(lisp x)))))
1415 (test ps*-lisp-expands-in-dynamic-environment
1416 (is (string= "1 + 2;" (let ((foo 2)) (declare (special foo)) (ps* '(+ 1 (lisp (locally (declare (special foo)) foo))))))))
1418 (test ps-lisp-dynamic-environment
1419 (is (string= "1 + 2;" (let ((foo 2)) (declare (special foo)) (ps (+ 1 (lisp foo)))))))
1421 (test-ps-js nested-if-expressions1
1422 (defun foo ()
1423 (return-from foo (if (if x y z) a b)))
1424 "function foo() {
1425 return (x ? y : z) ? a : b;
1426 };")
1428 (test-ps-js nested-if-expressions2
1429 (defun foo ()
1430 (if x y (if z a b)))
1431 "function foo() {
1432 if (x) {
1433 return y;
1434 } else {
1435 return z ? a : b;
1437 };")
1439 (test-ps-js let1
1440 (let (x)
1441 (+ x x))
1442 "var x = null;
1443 x + x;")
1445 (test-ps-js let2
1446 (let ((x 1))
1447 (+ x x))
1448 "var x = 1;
1449 x + x;")
1451 (test-ps-js let-x-x
1452 (let ((x (1+ x)))
1453 (+ x x))
1454 "var x1 = x + 1;
1455 x1 + x1;")
1457 (test-ps-js let3
1458 (let ((x 1)
1459 (y 2))
1460 (+ x x))
1461 "var x = 1;
1462 var y = 2;
1463 x + x;")
1465 (test-ps-js let4
1466 (let ((x 1)
1467 (y (1+ x)))
1468 (+ x y))
1469 "var x1 = 1;
1470 var y = x + 1;
1471 x1 + y;")
1473 (test-ps-js let5
1474 (let ((x 1))
1475 (+ x 1)
1476 (let ((x (+ x 5)))
1477 (+ x 1))
1478 (+ x 1))
1479 "var x = 1;
1480 x + 1;
1481 var x1 = x + 5;
1482 x1 + 1;
1483 x + 1;")
1485 (test-ps-js let6
1486 (let ((x 2))
1487 (let ((x 1)
1488 (y (1+ x)))
1489 (+ x y)))
1490 "var x = 2;
1491 var x1 = 1;
1492 var y = x + 1;
1493 x1 + y;")
1495 (test-ps-js let-exp1
1496 (lambda ()
1497 (let (x)
1498 (+ x x)))
1499 "function () {
1500 var x = null;
1501 return x + x;
1502 };")
1504 (test-ps-js let*1
1505 (let* ((x 1))
1506 (+ x x))
1507 "var x = 1;
1508 x + x;")
1510 (test-ps-js let*2
1511 (let* ((x 1)
1512 (y (+ x 2)))
1513 (+ x y))
1514 "var x = 1;
1515 var y = x + 2;
1516 x + y;")
1518 (test-ps-js let*3
1519 (let ((x 3))
1520 (let* ((x 1)
1521 (y (+ x 2)))
1522 (+ x y)))
1523 "var x = 3;
1524 var x1 = 1;
1525 var y = x1 + 2;
1526 x1 + y;")
1528 (test-ps-js let*4
1529 (let ((x 3))
1530 (let* ((y (+ x 2))
1531 (x 1))
1532 (+ x y)))
1533 "var x = 3;
1534 var y = x + 2;
1535 var x1 = 1;
1536 x1 + y;")
1538 (test-ps-js symbol-macrolet-var
1539 (symbol-macrolet ((x y))
1540 (var x))
1541 "var y;")
1543 (test-ps-js setf-conditional1
1544 (setf x (unless (null a) (1+ a)))
1545 "x = a != null ? a + 1 : null;")
1547 (test-ps-js setf-let1
1548 (setf x (let ((a 1)) a))
1549 "x = (a = 1, a);")
1551 (test-ps-js setf-let2
1552 (setf x (let ((a (foo)))
1553 (unless (null a)
1554 (1+ a))))
1555 "x = (a = foo(), a != null ? a + 1 : null);")
1557 (test-ps-js symbol-macro-env1
1558 (symbol-macrolet ((bar 1))
1559 (macrolet ((bar (x y) `(+ ,x ,y)))
1560 (bar bar bar)))
1561 "1 + 1;")
1563 (test-ps-js symbol-macrolet-fun1
1564 (symbol-macrolet ((baz +))
1565 (baz 1 2))
1566 "baz(1, 2);")
1568 (test-ps-js lisp2-namespaces1
1569 (let ((list nil))
1570 (setf list (list 1 2 3)))
1571 "var list = null;
1572 list = [1, 2, 3];")
1574 (test-ps-js let-shadows-symbol-macrolet
1575 (symbol-macrolet ((x y))
1576 (let ((x 1))
1577 (+ x x))
1578 (+ x x))
1579 "var x1 = 1;
1580 x1 + x1;
1581 y + y;")
1583 (test-ps-js let-rename-optimization1
1584 (let ((x 1))
1585 (+ x x))
1586 "var x = 1;
1587 x + x;")
1589 (test-ps-js let-rename-optimization2
1590 (lambda (x)
1591 (let ((x (+ 1 x)))
1593 "function (x) {
1594 var x1 = 1 + x;
1595 return x1;
1596 };")
1598 (test-ps-js symbol-macro-array
1599 (symbol-macrolet ((x 1))
1600 (list x))
1601 "[1];")
1603 (test-ps-js symbol-macro-obj
1604 (symbol-macrolet ((x y))
1605 (create x 1))
1606 "{ x : 1 };")
1608 (test-ps-js symbol-macro-conditional1
1609 (symbol-macrolet ((x y))
1610 (if x x x))
1611 "if (y) {
1613 } else {
1615 };")
1617 (test-ps-js symbol-macro-conditional2
1618 (symbol-macrolet ((x y))
1619 (1+ (if x x x)))
1620 "(y ? y : y) + 1;")
1622 (test-ps-js flet-apply
1623 (flet ((foo () 'bar))
1624 (apply (function foo) nil))
1625 "var foo = function () {
1626 return 'bar';
1628 foo.apply(this, null);")
1630 (test-ps-js let-apply
1631 (let ((foo (lambda () 1)))
1632 (let ((foo (lambda () 2)))
1633 (apply foo nil)))
1634 "var foo = function () {
1635 return 1;
1637 var foo1 = function () {
1638 return 2;
1640 foo1.apply(this, null);")
1642 (test-ps-js flet-let
1643 (flet ((x (x) (1+ x)))
1644 (let ((x 2))
1645 (x x)))
1646 "var x = function (x) {
1647 return x + 1;
1649 var x1 = 2;
1650 x(x1);")
1652 (test-ps-js let-flet
1653 (let ((x 2))
1654 (flet ((x (x) (1+ x)))
1655 (x x)))
1656 "var x = 2;
1657 var x1 = function (x) {
1658 return x + 1;
1660 x1(x);")
1662 (test-ps-js labels-let
1663 (labels ((x (x) (1+ x)))
1664 (let ((x 2))
1665 (x x)))
1666 "var x = function (x) {
1667 return x + 1;
1669 var x1 = 2;
1670 x(x1);")
1672 (test-ps-js let-labels
1673 (let ((x 2))
1674 (labels ((x (x) (1+ x)))
1675 (x x)))
1676 "var x = 2;
1677 var x1 = function (x) {
1678 return x + 1;
1680 x1(x);")
1682 (test-ps-js macrolet-let-inteference
1683 (macrolet ((a (n) `(+ ,n 5)))
1684 (let ((a (a 1)))
1685 (let ((b (a (- a 4))))
1686 (+ a b))))
1687 "var a = 1 + 5;
1688 var b = a - 4 + 5;
1689 a + b;")
1691 (test-ps-js let-subtract-add
1692 (let ((x 1))
1693 (let ((x 2))
1694 (- x x)
1695 (- x)
1696 (decf x)
1697 (incf x)))
1698 "var x = 1;
1699 var x1 = 2;
1700 x1 - x1;
1701 -x1;
1702 --x1;
1703 ++x1;")
1705 (test-ps-js create-reserved-word
1706 (create :default 1)
1707 "{ 'default' : 1 };")
1709 (test-ps-js getprop-reserved-word
1710 (getprop foo :default)
1711 "foo['default'];")
1713 (test-ps-js getprop-reserved-word1
1714 (getprop foo 'default)
1715 "foo['default'];")
1717 (test-ps-js eval-when-ps-side
1718 (eval-when (:execute)
1720 "5;")
1722 (defvar *lisp-output* nil)
1724 (test eval-when-lisp-side ()
1725 (setf *lisp-output* 'original-value)
1726 (let ((js-output (normalize-js-code
1727 (ps-doc* `(eval-when (:compile-toplevel)
1728 (setf *lisp-output* 'it-works))))))
1729 (is (eql 'it-works *lisp-output*))
1730 (is (string= "" js-output))))
1732 (defpsmacro my-in-package (package-name)
1733 `(eval-when (:compile-toplevel)
1734 (setf *lisp-output* ,package-name)))
1736 (test eval-when-macro-expansion ()
1737 (setf *lisp-output* 'original-value)
1738 (let ((js-output (normalize-js-code
1739 (ps-doc* `(progn
1740 (my-in-package :cl-user)
1741 3)))))
1742 (declare (ignore js-output))
1743 (is (eql :cl-user *lisp-output*))))
1745 (test eval-when-macrolet-expansion ()
1746 (setf *lisp-output* 'original-value)
1747 (let ((js-output (normalize-js-code
1748 (ps-doc* `(macrolet ((my-in-package2 (package-name)
1749 `(eval-when (:compile-toplevel)
1750 (setf *lisp-output* ,package-name))))
1751 (my-in-package2 :cl-user)
1752 3)))))
1753 (declare (ignore js-output))
1754 (is (eql :cl-user *lisp-output*))))
1756 (test-ps-js getprop-keyword
1757 (getprop foo :bar)
1758 "foo['bar'];")
1760 (test-ps-js nary-comparison1
1761 (lambda () (< 1 2 3))
1762 "function () {
1763 var _cmp1;
1764 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
1765 };")
1767 (test-ps-js chain-getprop1
1768 (chain ($ "foo") (bar x z) frob (baz 5))
1769 "$('foo').bar(x, z).frob.baz(5);")
1771 (test-ps-js chain-getprop2
1772 (chain ($ "foo") bar baz)
1773 "$('foo').bar.baz;")
1775 (test-ps-js chain-getprop3
1776 (chain ($ "foo") bar (x y) baz)
1777 "$('foo').bar.x(y).baz;")
1779 (test-ps-js flet-expression
1780 (1+ (flet ((foo (x) (1+ x)))
1781 (foo 1)))
1782 "(foo = function (x) {
1783 return x + 1;
1784 }, foo(1)) + 1;")
1786 (test-ps-js flet-lambda-list
1787 (labels ((foo (x &key (y 0))
1788 (+ x y)))
1789 (foo 1 :y 2))
1790 "var foo = function (x) {
1791 var _js2 = arguments.length;
1792 for (var n1 = 1; n1 < _js2; n1 += 2) {
1793 switch (arguments[n1]) {
1794 case 'y':
1795 y = arguments[n1 + 1];
1798 var y = undefined === y ? 0 : y;
1799 return x + y;
1801 foo(1, 'y', 2);")
1803 (test-ps-js return-case-break-elimination
1804 (defun foo ()
1805 (return-from foo
1806 (case 1
1807 (0 1)
1808 (otherwise 2))))
1809 "function foo() {
1810 switch (1) {
1811 case 0:
1812 return 1;
1813 default:
1814 return 2;
1816 };")
1818 (test-ps-js aplusplus
1820 "aplusplus;")
1822 (test-ps-js astarstar
1824 "astarstar;")
1826 (test-ps-js switch-return-fallthrough
1827 (defun foo ()
1828 (return-from foo
1829 (switch x
1830 (1 (foo) break)
1831 (2 (bar))
1832 (default 4))))
1833 "function foo() {
1834 switch (x) {
1835 case 1:
1836 return foo();
1837 case 2:
1838 bar();
1839 default:
1840 return 4;
1842 };")
1844 (test-ps-js return-last-case
1845 (defun foo ()
1846 (return-from foo
1847 (case x
1848 (a 'eh)
1849 (b 'bee))))
1850 "function foo() {
1851 switch (x) {
1852 case a:
1853 return 'eh';
1854 case b:
1855 return 'bee';
1857 };")
1859 (test-ps-js return-macrolet
1860 (defun foo ()
1861 (return-from foo
1862 (macrolet ((x () 1))
1863 (case (x)
1864 (a 'eh)
1865 (b 'bee)))))
1866 "function foo() {
1867 switch (1) {
1868 case a:
1869 return 'eh';
1870 case b:
1871 return 'bee';
1873 };")
1875 (test-ps-js mv-bind1
1876 (multiple-value-bind (a b)
1877 (progn
1878 (returns-mv)
1879 (doesnt))
1880 (alert a)
1881 (alert b))
1882 "var prevMv2 = null;
1883 returnsMv();
1884 prevMv2 = arguments['callee']['mv'];
1885 try {
1886 arguments['callee']['mv'] = true;
1887 var a = doesnt();
1888 var mv1 = typeof arguments['callee']['mv'] === 'object' ? arguments['callee']['mv'] : new Array(1);
1889 var b = mv1[0];
1890 alert(a);
1891 alert(b);
1892 } finally {
1893 if (undefined === prevMv2) {
1894 delete arguments['callee']['mv'];
1895 } else {
1896 arguments['callee']['mv'] = prevMv2;
1898 };")
1900 (test-ps-js mv-bind2
1901 (multiple-value-bind (a b)
1902 (let ((a 1))
1903 (returns-mv a)
1904 (doesnt b))
1905 (alert a)
1906 (alert b))
1907 "var prevMv2 = null;
1908 var a = 1;
1909 returnsMv(a);
1910 prevMv2 = arguments['callee']['mv'];
1911 try {
1912 arguments['callee']['mv'] = true;
1913 var a3 = doesnt(b);
1914 var mv1 = typeof arguments['callee']['mv'] === 'object' ? arguments['callee']['mv'] : new Array(1);
1915 var b = mv1[0];
1916 alert(a3);
1917 alert(b);
1918 } finally {
1919 if (undefined === prevMv2) {
1920 delete arguments['callee']['mv'];
1921 } else {
1922 arguments['callee']['mv'] = prevMv2;
1924 };")
1926 (test-ps-js multiple-value-bind-simple
1927 (multiple-value-bind (a b) (blah)
1928 (+ a b))
1929 "var prevMv2 = null;
1930 prevMv2 = arguments['callee']['mv'];
1931 try {
1932 arguments['callee']['mv'] = true;
1933 var a = blah();
1934 var mv1 = typeof arguments['callee']['mv'] === 'object' ? arguments['callee']['mv'] : new Array(1);
1935 var b = mv1[0];
1936 a + b;
1937 } finally {
1938 if (undefined === prevMv2) {
1939 delete arguments['callee']['mv'];
1940 } else {
1941 arguments['callee']['mv'] = prevMv2;
1943 };")
1945 (test-ps-js values0
1946 (lambda () (values))
1947 "function () {
1948 return null;
1949 };")
1951 (test-ps-js values1
1952 (values x)
1953 "x;")
1955 (test-ps-js values2
1956 (values x y)
1957 "var val1_1 = x;
1958 var valrest2 = [y];
1959 if (undefined !== arguments['callee']['caller']['mv']) {
1960 arguments['callee']['caller']['mv'] = valrest2;
1962 val1_1;")
1964 (test-ps-js values3
1965 (values x y z)
1966 "var val1_1 = x;
1967 var valrest2 = [y, z];
1968 if (undefined !== arguments['callee']['caller']['mv']) {
1969 arguments['callee']['caller']['mv'] = valrest2;
1971 val1_1;")
1973 (test-ps-js values-return
1974 (defun foo ()
1975 (return-from foo (values x y)))
1976 "function foo() {
1977 var val1_1 = x;
1978 var valrest2 = [y];
1979 if (undefined !== arguments['callee']['caller']['mv']) {
1980 arguments['callee']['caller']['mv'] = valrest2;
1982 return val1_1;
1983 };")
1985 (test-ps-js return-macrolet
1986 (defun foo ()
1987 (return-from foo
1988 (symbol-macrolet ((x 2))
1989 (loop do (+ x x)))))
1990 "function foo() {
1991 for (; true; ) {
1992 2 + 2;
1994 return null;
1995 };")
1997 (test-ps-js return-cond
1998 (defun foo ()
1999 (return-from foo
2000 (cond ((foo? x) (loop for y in x do (foo y)))
2001 ((bar? x) x)
2002 (t 3))))
2003 "function foo() {
2004 if (foowhat(x)) {
2005 var _js2 = x.length;
2006 var _js1 = 0;
2007 if (_js1 < _js2) {
2008 var y = x[_js1];
2009 while (true) {
2010 foo(y);
2011 _js1 += 1;
2012 if (_js1 >= _js2) {
2013 break;
2015 y = x[_js1];
2018 return null;
2019 } else if (barwhat(x)) {
2020 return x;
2021 } else {
2022 return 3;
2024 };")
2026 (test-ps-js switch-loop
2027 (case x
2028 (1 (dolist (a b))))
2029 "switch (x) {
2030 case 1:
2031 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2032 a = b[_js_idx1];
2034 };")
2036 (test-ps-js switch-folds-blocks
2037 (case x
2038 (1 (loop repeat 3 do (alert "foo"))))
2039 "switch (x) {
2040 case 1:
2041 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2042 alert('foo');
2044 };")
2046 (test-ps-js setf-places-before-macros
2047 (progn
2048 (defsetf left (el) (offset)
2049 `(setf (@ ,el style left) ,offset))
2050 (macrolet ((left (el)
2051 `(@ ,el offset-left)))
2052 (setf (left x) 10)
2053 (left x)))
2054 "var _js2 = x;
2055 var _js1 = 10;
2056 _js2.style.left = _js1;
2057 x.offsetLeft;")
2059 (test-ps-js for-return
2060 (lambda () (dolist (arg args) (foo arg)))
2061 "function () {
2062 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2063 arg = args[_js_idx1];
2064 foo(arg);
2066 };")
2068 (test-ps-js try-catch-return
2069 (defun foo ()
2070 (return-from foo
2071 (try (foo)
2072 (:catch (e)
2073 (bar))
2074 (:finally
2075 (cleanup)))))
2076 "function foo() {
2077 try {
2078 return foo();
2079 } catch (e) {
2080 return bar();
2081 } finally {
2082 cleanup();
2084 };")
2086 (test-ps-js defun-setf-optional
2087 (defun (setf foo) (new-value b &optional c)
2088 (setf (aref b (or c 0)) new-value))
2089 "function __setf_foo(newValue, b, c) {
2090 return b[c || 0] = newValue;
2091 };")
2093 (test-ps-js defun-setf-rest
2094 (progn (defun (setf foo) (new-value b &rest foo)
2095 (do-something b foo new-value))
2096 (setf (foo x 1 2 3 4) 5))
2097 "function __setf_foo(newValue, b) {
2098 var foo = [];
2099 for (var i1 = 0; i1 < arguments.length - 2; i1 += 1) {
2100 foo[i1] = arguments[i1 + 2];
2102 return doSomething(b, foo, newValue);
2104 __setf_foo(5, x, 1, 2, 3, 4);")
2106 (test-ps-js return-null
2107 (defun foo () (return-from foo nil))
2108 "function foo() {
2109 return null;
2110 };")
2112 (test-ps-js implicit-return-null
2113 (lambda ()
2115 "function () {
2116 return null;
2117 };")
2119 (test-ps-js implicit-return-null
2120 (lambda ()
2121 nil)
2122 "function () {
2123 return null;
2124 };")
2126 (test-ps-js return-conditional-nested
2127 (defun blep (ss x y)
2128 (when foo?
2129 (let ((pair (bar)))
2130 (unless (null pair)
2131 (destructuring-bind (a b) pair
2132 (unless (or (null a) (null b))
2133 (let ((val (baz a b)))
2134 (unless (null val)
2135 (when (blah val)
2136 (unless (blee)
2137 t))))))))))
2138 "function blep(ss, x, y) {
2139 if (foowhat) {
2140 var pair = bar();
2141 if (pair != null) {
2142 var a = pair[0];
2143 var b = pair[1];
2144 if (!(a == null || b == null)) {
2145 var val = baz(a, b);
2146 if (val != null) {
2147 if (blah(val)) {
2148 return !blee() ? true : null;
2154 };")
2156 ;; this test needs to be rewritten when named blocks are implemented!!!!
2157 (test-ps-js return-when-returns-broken-return
2158 (defun foo ()
2159 (return-from foo (when x 1))
2160 (+ 2 3))
2161 "function foo() {
2162 return x ? 1 : null;
2163 return 2 + 3;
2164 };")
2166 (test-ps-js return-case-conditional
2167 (defun foo ()
2168 (return-from foo
2169 (case foo
2170 (123 (when (bar) t))
2171 (345 (blah)))))
2172 "function foo() {
2173 switch (foo) {
2174 case 123:
2175 return bar() ? true : null;
2176 break;
2177 case 345:
2178 return blah();
2180 };")
2182 (test-ps-js return-try-conditional
2183 (defun foo ()
2184 (return-from foo
2185 (try (when x 1)
2186 (:catch (x) 2)
2187 (:finally (bar)))))
2188 "function foo() {
2189 try {
2190 return x ? 1 : null;
2191 } catch (x) {
2192 return 2;
2193 } finally {
2194 bar();
2196 };")
2198 (test-ps-js function-declare-special
2199 (lambda ()
2200 (declare (special *foo*))
2201 (let ((*foo* 1))
2202 (1+ *foo*)))
2203 "function () {
2204 var FOO_TMPSTACK1;
2205 try {
2206 FOO_TMPSTACK1 = FOO;
2207 FOO = 1;
2208 return FOO + 1;
2209 } finally {
2210 FOO = FOO_TMPSTACK1;
2212 };")
2214 (test-ps-js declare-special-let
2215 (let ((*foo* 123))
2216 (declare (special *foo*))
2217 (blah))
2218 "var FOO_TMPSTACK1;
2219 try {
2220 FOO_TMPSTACK1 = FOO;
2221 FOO = 123;
2222 blah();
2223 } finally {
2224 FOO = FOO_TMPSTACK1;
2225 };")
2227 (test-ps-js macro-null-toplevel
2228 (progn
2229 (defmacro macro-null-toplevel ()
2230 nil)
2231 (macro-null-toplevel))
2234 (test-ps-js define-symbol-macro-let
2235 (progn
2236 (define-symbol-macro test-symbol-macro 1)
2237 (let ((test-symbol-macro 2))
2238 (1+ test-symbol-macro))
2239 (1+ test-symbol-macro))
2240 "var testSymbolMacro1 = 2;
2241 testSymbolMacro1 + 1;
2242 1 + 1;")
2244 (test-ps-js define-symbol-macro-flet
2245 (progn
2246 (define-symbol-macro test-symbol-macro1 1)
2247 (flet ((test-symbol-macro1 () 2))
2248 (foo test-symbol-macro1)
2249 (test-symbol-macro1))
2250 (bar test-symbol-macro1))
2251 "var testSymbolMacro1_1 = function () {
2252 return 2;
2254 foo(1);
2255 testSymbolMacro1_1();
2256 bar(1);")
2258 (test compile-stream-nulls
2259 (is (string=
2261 (with-input-from-string (s "
2262 (defmacro macro-null-toplevel ()
2263 nil)
2264 (macro-null-toplevel)")
2265 (ps-compile-stream s)))))
2267 (test compile-stream1
2268 (is (string=
2269 "var testSymbolMacro1_1 = function () {
2270 return 2;
2272 foo(1);
2273 testSymbolMacro1_1();
2274 bar(1);
2276 (with-input-from-string (s "
2277 (define-symbol-macro test-symbol-macro1 1)
2278 (flet ((test-symbol-macro1 () 2))
2279 (foo test-symbol-macro1)
2280 (test-symbol-macro1))
2281 (bar test-symbol-macro1)")
2282 (ps::with-blank-compilation-environment (ps-compile-stream s))))))
2284 (test-ps-js equality-nary1
2285 (let ((x 10) (y 10) (z 10))
2286 (= x y z))
2287 "var x = 10;
2288 var y = 10;
2289 var z = 10;
2290 var _cmp1 = y;
2291 x === _cmp1 && _cmp1 === z;")
2293 (test-ps-js equality1
2294 (progn
2295 (equal a b)
2296 (eql a b)
2297 (eq a b)
2298 (= a b))
2299 "a == b;
2300 a === b;
2301 a === b;
2302 a === b;")
2304 (test-ps-js getprop-quote-reserved
2305 (getprop foo ':break)
2306 "foo['break'];")
2308 (test-ps-js defun-block-return-from
2309 (defun foo (x)
2310 (baz 4)
2311 (return-from foo x)
2312 (bar 5))
2313 "function foo(x) {
2314 baz(4);
2315 return x;
2316 return bar(5);
2317 }; ")
2319 (test-ps-js block-return-from
2320 (block scope
2321 (foo)
2322 (when (bar)
2323 (return-from scope))
2324 (blee))
2325 "scope: {
2326 foo();
2327 if (bar()) {
2328 break scope;
2330 blee();
2331 };")
2333 (test-ps-js let-funcall
2334 (let ((x foo))
2335 (funcall x)
2336 (let ((x bar))
2337 (funcall x))
2338 (funcall x))
2339 "var x = foo;
2340 x();
2341 var x1 = bar;
2342 x1();
2343 x();")
2345 (test-ps-js symbol-macrolet-funcall
2346 (symbol-macrolet ((foo bar))
2347 (funcall foo 1 2 3))
2348 "bar(1, 2, 3);")
2350 (test-ps-js times-assign
2351 (setf x (* x 1000))
2352 "x *= 1000;")
2354 (test-ps-js vector-literal
2355 #(1 2 3)
2356 "[1, 2, 3];")
2358 (test-ps-js rem1
2359 (+ 1 (rem 2 (+ 3 4)))
2360 "1 + 2 % (3 + 4);")
2362 (test-ps-js non-associative
2363 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
2364 "1 / (2 / 3) + 1 - (2 - 3);")
2366 (test-ps-js lambda-apply
2367 (lambda (x)
2368 (apply (lambda (y) (bar (1+ y))) x))
2369 "function (x) {
2370 return (function (y) {
2371 return bar(y + 1);
2372 }).apply(this, x);
2373 };")
2375 (test-ps-js operator-expressions-nested-let
2376 (let ((x (let ((y 1))
2377 y)))
2379 "var x = (y = 1, y); x;")
2381 (test-ps-js operator-expressions-array-nested-let
2382 (list (let ((y 1)) y) 2)
2383 "[(y = 1, y), 2];")
2385 (test-ps-js add-subtract-precedence
2386 (- x (+ y z))
2387 "x - (y + z);")
2389 (test-ps-js ps-inline-toplevel
2390 (ps-inline (foo))
2391 "'javascript:' + 'foo()';")
2393 (test-ps-js no-clause-progn-exp
2394 (setf x (progn))
2395 "x = null;")
2397 (test-ps-js no-clause-progn-return
2398 (defun foo ()
2399 (return-from foo (progn)))
2400 "function foo() {
2401 return null;
2402 };")
2404 (test-ps-js empty-cond-clause
2405 (setf x (cond ((foo))))
2406 "x = foo() ? null : null;")
2408 (test-ps-js empty-cond-clause1
2409 (setf x (cond ((foo) 123)
2410 ((bar))
2411 (t 456)))
2412 "x = foo() ? 123 : (bar() ? null : 456);")
2414 (test-ps-js let-no-body
2415 (defun foo ()
2416 (return-from foo (let ((foo bar)))))
2417 "function foo() {
2418 var foo1 = bar;
2419 return null;
2420 };")
2422 (test-ps-js dont-hoist-lexical-dupes
2423 (lambda ()
2424 (list (let ((foo 12)) (* foo 2))
2425 (let ((foo 13)) (* foo 3))))
2426 "function () {
2427 var foo;
2428 return [(foo = 12, foo * 2), (foo = 13, foo * 3)];
2429 };")
2431 (test-ps-js defun-comment1
2432 (defun foo (x)
2433 "BARBAR is a revolutionary new foobar.
2434 X y and x."
2435 (1+ x))
2436 "/**
2437 * BARBAR is a revolutionary new foobar.
2438 * X y and x.
2440 function foo(x) {
2441 return x + 1;
2442 };")
2444 (test-ps-js var-comment
2445 (var x 1 "foo")
2446 "/** foo */
2447 var x = 1;")
2449 (test-ps-js case-return-break-broken-return
2450 (defun foo ()
2451 (case x
2452 ("bar" (if y (return-from foo t) nil))
2453 ("baz" nil)))
2454 "function foo() {
2455 switch (x) {
2456 case 'bar':
2457 if (y) {
2458 return true;
2460 break;
2461 case 'baz':
2462 return null;
2464 };")
2466 (test-ps-js case-return-break1-broken-return
2467 (defun foo ()
2468 (case x
2469 ("bar" (if y (return-from foo t)))
2470 ("baz" nil)))
2471 "function foo() {
2472 switch (x) {
2473 case 'bar':
2474 if (y) {
2475 return true;
2477 break;
2478 case 'baz':
2479 return null;
2481 };")
2483 (test-ps-js setf-progn
2484 (setf foo (progn (bar) (baz) 3))
2485 "bar();
2486 baz();
2487 foo = 3;")
2489 ;; (test-ps-js var-progn
2490 ;; (var x (progn (foo) (bar)))
2491 ;; "foo();
2492 ;; var x = bar();")
2494 (test-ps-js implicit-return-loop
2495 (lambda ()
2496 (if baz 7
2497 (progn
2498 (loop :repeat 100 :do (bar))
2499 42)))
2500 "function () {
2501 if (baz) {
2502 return 7;
2503 } else {
2504 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
2505 bar();
2507 return 42;
2509 };")
2511 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
2512 (test-ps-js loop-closures
2513 (dotimes (i 10) (lambda () (+ i 1)))
2514 "for (var i = 0; i < 10; i += 1) {
2515 with ({ i : i }) {
2516 function () {
2517 return i + 1;
2520 };")
2522 (test-ps-js loop-closures-let
2523 (dotimes (i 10) (let ((x (+ i 1))) (lambda () (+ i x))))
2524 "for (var i = 0; i < 10; i += 1) {
2525 with ({ x : null, i : i }) {
2526 var x = i + 1;
2527 function () {
2528 return i + x;
2531 };")
2533 (test-ps-js loop-closures-flet
2534 (dotimes (i 10) (flet ((foo (x) (+ i x))) (lambda () (foo i))))
2535 "for (var i = 0; i < 10; i += 1) {
2536 with ({ foo : null, i : i }) {
2537 var foo = function (x) {
2538 return i + x;
2540 function () {
2541 return foo(i);
2544 };")
2546 (test-ps-js while-closures-let
2547 (while (foo)
2548 (let ((x (bar)))
2549 (lambda () (+ 1 x))))
2550 "while (foo()) {
2551 with ({ x : null }) {
2552 var x = bar();
2553 function () {
2554 return 1 + x;
2557 };")
2559 (test-ps-js dotted-list-form
2560 (defun foo (a)
2561 (when a
2562 (destructuring-bind (b . c)
2564 (list b c))))
2565 "function foo(a) {
2566 if (a) {
2567 var b = bar[0];
2568 var c = bar.length > 1 ? bar.slice(1) : [];
2569 return [b, c];
2571 };")
2573 (test-ps-js return-from-loop
2574 (dolist (x '(2 1 3))
2575 (when (= x 1)
2576 (return))
2577 (chain console (log x)))
2578 "for (var x = null, _js_arrvar2 = [2, 1, 3], _js_idx1 = 0; _js_idx1 < _js_arrvar2.length; _js_idx1 += 1) {
2579 x = _js_arrvar2[_js_idx1];
2580 if (x === 1) {
2581 break;
2583 console.log(x);
2584 };")
2586 (test-ps-js explicit-nil-block
2587 (block nil (return) (+ 1 2))
2588 "nilBlock: {
2589 break nilBlock;
2590 1 + 2;
2591 };")
2593 (test-ps-js dynamic-extent-function-return
2594 (defun foo () ((lambda () (return-from foo))))
2595 "function foo() {
2596 try {
2597 return (function () {
2598 throw { 'ps-block-tag' : 'foo', 'ps-return-value' : null };
2599 })();
2600 } catch (err) {
2601 if (err && 'foo' === err['ps-block-tag']) {
2602 err['ps-return-value'];
2603 } else {
2604 throw err;
2607 };")
2609 (test-ps-js block-dynamic-return
2610 (block nil ((lambda () (return))) (+ 1 2))
2611 "nilBlock: {
2612 try {
2613 (function () {
2614 throw { 'ps-block-tag' : 'nilBlock', 'ps-return-value' : null };
2615 })();
2616 1 + 2;
2617 } catch (err) {
2618 if (err && 'nilBlock' === err['ps-block-tag']) {
2619 err['ps-return-value'];
2620 } else {
2621 throw err;
2624 };")
2626 (test-ps-js iteration-lambda-capture-no-need
2627 (dolist (x y) (lambda (x) (1+ x))) ;; there's really no need to create a 'with' scope in this case
2628 "for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
2629 with ({ x : x }) {
2630 x = y[_js_idx1];
2631 function (x) {
2632 return x + 1;
2635 };")
2637 (test-ps-js case-invert1
2638 (encodeURIComponent fooBar)
2639 "encodeURIComponent(fooBar);")
2641 (test-ps-js simple-ash
2642 (+ (ash 4 1) (ash 4 -1))
2643 "(4 << 1) + (4 >> 1);")
2645 (test-ps-js progn-nil-expression
2646 (bar (progn (foo) nil))
2647 "bar((foo(), null));")
2649 (test-ps-js other-progn-nil-exp
2650 (defun blah ()
2651 (or (foo) (progn (bar) nil)))
2652 "function blah() {
2653 return foo() || (bar(), null);
2654 };")
2656 (test-ps-js lambda-nil-return
2657 (lambda (x)
2658 (block nil
2659 (when x
2660 (return 1))
2662 "function (x) {
2663 if (x) {
2664 return 1;
2666 return 2;
2667 };")
2669 (test-ps-js lambda-nil-return-implicit-nested
2670 (lambda (x)
2671 (block nil
2672 (if x
2673 (return 1)
2674 (dotimes (i 4)
2675 (return 1)))
2677 "function (x) {
2678 if (x) {
2679 return 1;
2680 } else {
2681 for (var i = 0; i < 4; i += 1) {
2682 break;
2685 return 2;
2686 };")
2688 (test-ps-js throw-is-a-statement
2689 (defun blah ()
2690 (let ((result (foo)))
2691 (unless (null result)
2692 (throw result))))
2693 "function blah() {
2694 var result = foo();
2695 if (result != null) {
2696 throw result;
2698 };")
2700 (test-ps-js expressify1
2701 (defun blah ()
2702 (when (some-condition)
2703 (foo)
2704 (bar)
2705 (baz)))
2706 "function blah() {
2707 if (someCondition()) {
2708 foo();
2709 bar();
2710 return baz();
2712 };")
2714 (test-ps-js case-when-return
2715 (defun blah (a)
2716 (case a
2717 ("a" (when (foo) (return-from blah 111)))
2718 ("b" t)))
2719 "function blah(a) {
2720 switch (a) {
2721 case 'a':
2722 if (foo()) {
2723 return 111;
2725 break;
2726 case 'b':
2727 return true;
2729 };")
2731 (test-ps-js flet-return-from
2732 (defun abc ()
2733 (flet ((foo ()
2734 (return-from foo 123)))
2735 (foo)))
2736 "function abc() {
2737 var foo = function () {
2738 return 123;
2740 return foo();
2741 };")
2743 (test-ps-js flet-return-from1
2744 (flet ((foo ()
2745 (return-from foo 123)))
2746 (foo))
2747 "var foo = function () {
2748 return 123;
2750 foo();")
2752 (test-ps-js lambda-docstring-declarations
2753 (lambda (x)
2754 "This is a docstring"
2755 (declare (ignore x))
2757 "function (x) {
2758 return 2;
2759 };")
2761 (test-ps-js setf-let-exp
2762 (setf foo (let ((x (+ 1 2)))
2763 (if x 123 456)))
2764 "foo = (x = 1 + 2, x ? 123 : 456);")
2766 (test-ps-js create-let-exp
2767 (create :abc (let ((x (+ 1 2)))
2768 (if x 123 456)))
2769 "{ 'abc' : (x = 1 + 2, x ? 123 : 456) };")
2771 (test-ps-js eql-eql-eql-precedence
2772 (unless (equal (= 3 3) (= 3 4))
2773 (chain console (log 1)))
2774 "if ((3 === 3) != (3 === 4)) {
2775 console.log(1);
2776 };")