1 ;; SPDX-License-Identifier: BSD-3-Clause
3 (in-package #:parenscript.tests
)
4 (named-readtables:in-readtable
:parenscript
)
6 (in-suite output-tests
)
8 (test-ps-js statements-and-expressions-1
12 (test-ps-js statements-and-expressions-2
20 (test-ps-js symbol-conversion-1
22 "bangwhathashatpercent;")
24 (test-ps-js symbol-conversion-2
28 (test-ps-js symbol-conversion-3
32 (test-ps-js symbol-conversion-4
36 (test-ps-js symbol-conversion-5
38 "encodeURIComponent;")
40 (test-ps-js symbol-conversion-6
44 (test-ps-js number-literals-1
48 (test-ps-js number-literals-2
52 (test-ps-js number-literals-3
56 (test-ps-js string-literals-1
60 (test-ps-js string-literals-2
64 (test-ps-js string-literals-3
68 (test-ps-js array-literals-1
72 (test-ps-js array-literals-2
76 (test-ps-js array-literals-3
78 (array "foobar" "bratzel bub"))
79 "[ [ 2, 3 ], [ 'foobar', 'bratzel bub' ] ];")
81 (test-ps-js array-literals-4
85 (test-ps-js array-literals-5
87 "new Array(1, 2, 3);")
89 (test-ps-js array-literals-6
92 (make-array "foobar" "bratzel bub"))
93 "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));")
95 (test-ps-js array-init-1
96 (make-array 2 :initial-contents
'(10 20))
98 var arr1 = new Array(2);
100 for (var i4 = 0; i4 < Math.min(arr1.length, init2.length); i4 += 1) {
101 arr1[i4] = init2[i4];
106 (test-ps-js array-init-2
107 (make-array 5 :initial-element
10)
109 var arr1 = new Array(5);
111 for (var i4 = 0; i4 < arr1.length; i4 += 1) {
117 (test-ps-js object-literals-1
118 (create foo
"bar" :blorg
1)
119 "({ foo : 'bar', 'blorg' : 1 });")
121 (test-ps-js object-literals-2
124 another-object
(create :schtrunz
1))
127 anotherObject : { 'schtrunz' : 1 } });")
129 (test-ps-js object-literals-3
130 (getprop an-object
'foo
)
133 (test-ps-js object-literals-4
134 (@ an-object foo bar
)
137 (test-ps-js object-literals-5
138 (with-slots (a b c
) this
140 "this.a + this.b + this.c;")
142 (test-ps-js with-slots-single-eval
143 (lambda () (with-slots (a b
) (foo) (+ a b
)))
146 return object1.a + object1.b;
149 (test-ps-js object-literal-quoted-symbols
150 (create 'test
"bang" 'symbol-saved-my-life
"parenscript")
151 "({ 'test' : 'bang', 'symbolSavedMyLife' : 'parenscript' });")
153 (test-ps-js object-literal-property-accessors
157 (set x v
) (setf x v
))))
166 :js-target-version
"1.8.5")
168 (test-ps-js object-method-apply-1
169 (apply (@ an-object foo
) nil
)
170 "anObject.foo.apply(anObject, null);")
172 (test-ps-js object-method-apply-2
173 (apply (getprop (make-an-object) foo
'bar
) nil
)
175 var _js1 = makeAnObject()[foo];
177 return _js2.apply(_js1, null);
180 (test-ps-js object-method-apply-3
181 (apply (@ (make-an-object) foo
) (bar))
183 var _js1 = makeAnObject();
185 return _js2.apply(_js1, bar());
188 (test-ps-js regular-expression-literals-1
192 (test-ps-js regular-expression-literals-2
196 (test-ps-js literal-symbols-1
200 (test-ps-js literal-symbols-2
204 (test-ps-js literal-symbols-3
208 (test-ps-js literal-symbols-4
214 (test-ps-js literal-symbols-5
218 (test-ps-js literal-symbols-6
222 (test-ps-js variables-1
226 (test-ps-js variables-2
230 (test-ps-js variables-3
234 (test-ps-js function-calls-and-method-calls-1
238 (test-ps-js function-calls-and-method-calls-2
239 (foobar (blorg 1 2) (blabla 3 4) (array 2 3 4))
240 "foobar(blorg(1, 2), blabla(3, 4), [ 2, 3, 4 ]);")
242 (test-ps-js function-calls-and-method-calls-3
243 ((getprop this
'blorg
) 1 2)
246 (test-ps-js function-calls-and-method-calls-4
250 (test-ps-js function-calls-and-method-calls-5
251 ((getprop (aref foobar
1) 'blorg
) nil t
)
252 "foobar[1].blorg(null, true);")
254 (test-ps-js operator-expressions-1
258 (test-ps-js operator-expressions-2
262 (test-ps-js operator-expressions-3
263 (* 1 (+ 2 3 4) 4 (/ 6 7))
264 "1 * (2 + 3 + 4) * 4 * (6 / 7);")
266 (test-ps-js operator-expressions-4
270 (test-ps-js operator-expressions-5
274 (test-ps-js operator-expressions-6
278 (test-ps-js operator-expressions-7
282 (test-ps-js operator-expressions-8
286 (test-ps-js body-forms-1
287 (progn (blorg i
) (blafoo i
))
291 (test-ps-js body-forms-2
292 (+ i
(progn (blorg i
) (blafoo i
)))
293 "i + (blorg(i), blafoo(i));")
295 (test-ps-js function-definition-1
296 (defun a-function (a b
)
298 "function aFunction(a, b) {
302 (test-ps-js lambda-definition-2
303 (lambda (a b
) (+ a b
))
308 (test-ps-js assignment-1
312 (test-ps-js assignment-2
313 (setf a
2 b
3 c
4 x
(+ a b c
))
319 (test-ps-js assignment-3
320 (setf a
(+ a
2 3 4 a
))
321 "a = a + 2 + 3 + 4 + a;")
323 (test-ps-js assignment-4
327 (test-ps-js assignment-5
339 (test-ps-js assignment-6
343 (test-ps-js assignment-8
345 (defun (setf color
) (new-color el
)
346 (setf (getprop (getprop el
'style
) 'color
) new-color
))
347 (setf (color some-div
) (+ 23 "em")))
348 "function __setf_color(newColor, el) {
349 return el.style.color = newColor;
351 __setf_color(23 + 'em', someDiv);")
353 (test-ps-js assignment-10
355 (defsetf left
(el) (offset)
356 `(setf (getprop (getprop ,el
'style
) 'left
) ,offset
))
357 (setf (left some-div
) (+ 123 "px")))
360 var _js1 = 123 + 'px';
361 return _js2.style.left = _js1;
364 (test-ps-js assignment-12
365 (macrolet ((left (el)
366 `(getprop ,el
'offset-left
)))
368 "someDiv.offsetLeft;")
370 (test-ps-js nil-block-return-1
371 (block nil
(return) 1)
377 (test-ps-js single-argument-statements-2
381 (test-ps-js single-argument-expression-1
382 (delete (new (*foobar
2 3 4)))
383 "delete new Foobar(2, 3, 4);")
385 (test-ps-js single-argument-expression-2
386 (if (= (typeof blorg
) *string
)
387 (alert (+ "blorg is a string: " blorg
))
388 (alert "blorg is not a string"))
389 "if (typeof blorg === String) {
390 alert('blorg is a string: ' + blorg);
392 alert('blorg is not a string');
395 (test-ps-js conditional-statements-1
397 (if ((@ blorg is-correct
))
398 (progn (carry-on) (return-from foo i
))
399 (alert "blorg is not correct!")))
401 if (blorg.isCorrect()) {
405 return alert('blorg is not correct!');
409 (test-ps-js conditional-statements-2
410 (+ i
(if ((@ blorg add-one
)) 1 2))
411 "i + (blorg.addOne() ? 1 : 2);")
413 (test-ps-js conditional-statements-3
415 (when ((@ blorg is-correct
))
417 (return-from foo i
)))
419 if (blorg.isCorrect()) {
425 (test-ps-js conditional-statements-4
426 (unless ((@ blorg is-correct
))
427 (alert "blorg is not correct!"))
428 "if (!blorg.isCorrect()) {
429 alert('blorg is not correct!');
432 (test-ps-js variable-declaration-1
433 (defvar *a
* (array 1 2 3))
434 "var A = [ 1, 2, 3 ];")
436 (test-ps-js variable-declaration-2
437 (progn (defvar *a
* 4)
458 (test-ps-js iteration-constructs-1
459 (do* ((a) b
(c (array "a" "b" "c" "d" "e"))
461 (e (aref c d
) (aref c d
)))
462 ((or (= d
(@ c length
)) (string= e
"x")))
464 (funcall (@ document write
) (+ "a: " a
" b: " b
"<br/>")))
466 for (var a = null, b = null, c = ['a', 'b', 'c', 'd', 'e'], d = 0, e = c[d];
467 !(d === c.length || e === 'x'); d += 1, e = c[d]) {
470 document.write('a: ' + a + ' b: ' + b + '<br/>');
474 (test-ps-js iteration-constructs-2
476 (s 0 (+ s i
(1+ i
))))
478 (funcall (@ document write
) (+ "i: " i
" s: " s
"<br/>")))
483 document.write('i: ' + i + ' s: ' + s + '<br/>');
485 var _js2 = s + i + (i + 1);
491 (test-ps-js iteration-constructs-3
493 (s 0 (+ s i
(1- i
))))
495 ((@ document write
) (+ "i: " i
" s: " s
"<br/>")))
497 for (var i = 0, s = 0; i <= 10; i += 1, s = s + i + (i - 1)) {
498 document.write('i: ' + i + ' s: ' + s + '<br/>');
502 (test-ps-js iteration-constructs-4
503 (let ((arr (array "a" "b" "c" "d" "e")))
504 (dotimes (i (@ arr length
))
505 ((@ document write
) (+ "i: " i
" arr[i]: " (aref arr i
) "<br/>"))))
507 var arr = ['a', 'b', 'c', 'd', 'e'];
508 for (var i = 0; i < arr.length; i += 1) {
509 document.write('i: ' + i + ' arr[i]: ' + arr[i] + '<br/>');
513 (test-ps-js iteration-constructs-5
515 (alert (+ "Summation to 10 is "
517 (incf res
(1+ i
))))))
520 return alert('Summation to 10 is ' + (function () {
521 for (var i = 0; i < 10; i += 1) {
528 (test-ps-js iteration-constructs-6
529 (let ((l (list 1 2 4 8 16 32)))
531 ((@ document write
) (+ "c: " c
"<br/>"))))
533 var l = [1, 2, 4, 8, 16, 32];
534 for (var c = null, _js_idx2 = 0; _js_idx2 < l.length; _js_idx2 += 1) {
536 document.write('c: ' + c + '<br/>');
540 (test-ps-js iteration-constructs-7
541 (let ((l '(1 2 4 8 16 32))
543 (alert (+ "Sum of " l
" is: "
547 var l = [1, 2, 4, 8, 16, 32];
549 return alert('Sum of ' + l + ' is: ' + (function () {
550 for (var c = null, _js_idx1 = 0; _js_idx1 < l.length; _js_idx1 += 1) {
558 (test-ps-js iteration-constructs-8
559 (let ((obj (create a
1 b
2 c
3)))
561 ((@ document write
) (+ i
": " (aref obj i
) "<br/>"))))
563 var obj = { a : 1, b : 2, c : 3 };
565 document.write(i + ': ' + obj[i] + '<br/>');
569 (test-ps-js iteration-constructs-9
570 (while ((@ film is-not-finished
))
571 ((@ this eat
) (new *popcorn
)))
572 "while (film.isNotFinished()) {
573 this.eat(new Popcorn);
576 (test-ps-js loop-for-bindings
577 (loop :for
((a b
) (:c
:d
)) :in arr
:do
(foo a b c d
))
579 var _js2 = arr.length;
580 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
581 var _db4 = arr[_js1];
592 (test-ps-js loop-for-on
593 (loop :for
(k v
) :on plist
:by
2 :do
(foo k v
))
595 for (var _js1 = plist; _js1.length > 0; _js1 = _js1['slice'](2)) {
602 (test-ps-js loop-for-keys-of
603 (loop :for k
:of obj
:do
(foo k
))
610 (test-ps-js loop-for-key-val-pairs-of
611 (loop :for
(k v
) :of obj
:do
(foo k v
))
619 (test-ps-js loop-for-key-val-pairs-of-with-bindings
620 (loop :for
(k (a b
)) :of obj
:do
(foo k a b
))
630 (test-ps-js loop-for-just-vals-of
631 (loop :for
(nil v
) :of obj
:do
(foo k v
))
633 for (var _js1 in obj) {
639 (test-ps-js loop-map-to
640 (loop :for str
:in strs
:map str
:to
(length str
))
642 var _js2 = strs.length;
644 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
645 var str = strs[_js1];
646 map3[str] = str.length;
651 (test-ps-js loop-for-of-map-to
652 (loop :for k
:of obj
:map k
:to
(foo k
))
661 (test-ps-js loop-for-of-when
662 (loop :for k
:of obj
:when
(foo k
) :map k
:to
(bar k
))
673 (test-ps-js loop-for-in-until-when
674 (loop :for a
:in b
:until
(> a
100) :when
(< a
50) :do
(foo a
))
677 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
688 (test-ps-js loop-with-for-when
689 (loop :with c
= c1
:for d
:from c1
:below c2
690 :when
(foo c d
) :do
(setf c d
)
694 for (var d = c1; d < c2; d += 1) {
702 (test-ps-js loop-for-then-for-in-while
704 (loop :for a
= (foo) :then
(bar) :for b
:in c
:while b
:do
(foo a b c
)))
708 for (var a = foo(); true; a = bar()) {
709 var _js1 = FIRST3 ? 0 : _js1 + 1;
722 (test-ps-js loop-while-when
723 (loop :for a
= (pop stack
) :while a
:for
(b c
) = (foo a
) :when b
:do
(bar c
))
725 for (var a = pop(stack); a; a = pop(stack)) {
735 (test-ps-js loop-for-of-for-in
737 (loop :for k
:of obj
:for a
:in b
:do
(foo k a
)))
738 "function blah(obj, b) {
742 var _js1 = FIRST3 ? 0 : _js1 + 1;
752 (test-ps-js loop-for-dot
753 (loop :for
(op . args
) :in expr
:do
(foo op args
))
755 var _js2 = expr.length;
756 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
757 var _db3 = expr[_js1];
759 var args = _db3.length > 1 ? _db3.slice(1) : [];
764 (test-ps-js loop-for-rest
765 (loop :for
(op &rest args
) :in expr
:do
(foo op args
))
767 var _js2 = expr.length;
768 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
769 var _db3 = expr[_js1];
771 var args = _db3.length > 1 ? _db3.slice(1) : [];
776 (test-ps-js loop-collect
777 (setf x
(loop :for a
:in b
:collect
(foo a
)))
781 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
783 collect3.push(foo(a));
788 (test-ps-js loop-append
789 (loop :for a
:in b
:append a
)
793 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
795 append3 = append3.concat(a);
800 (test-ps-js the-case-statement-1
802 ((1 "one") (alert "one"))
804 (t (alert "default clause")))
814 alert('default clause');
817 (test-ps-js the-case-statement-2
818 (switch (aref blorg i
)
819 (1 (alert "If I get here"))
820 (2 (alert "I also get here"))
821 (default (alert "I always get here")))
823 case 1: alert('If I get here');
824 case 2: alert('I also get here');
825 default: alert('I always get here');
828 (test-ps-js the-try-statement-1
831 (alert (+ "an error happened: " error
)))
833 (alert "Leaving the try form")))
837 alert('an error happened: ' + error);
839 alert('Leaving the try form');
842 (test-ps-js the-html-generator-1
843 (ps-html ((:a
:href
"foobar") "blorg"))
844 "'<A HREF=\"foobar\">blorg</A>';")
846 (test-ps-js the-html-generator-2
847 (ps-html ((:a
:href
(generate-a-link)) "blorg"))
848 "['<A HREF=\"', generateALink(), '\">blorg</A>'].join('');")
850 (test-ps-js the-html-generator-3
851 (funcall (getprop document
'write
)
852 (ps-html ((:a
:href
"#"
853 :onclick
(ps-inline (transport))) "link")))
854 "document.write(['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">link</A>'].join(''));")
856 (test-ps-js the-html-generator-4
859 (setf (getprop element
'inner-h-t-m-l
)
860 (ps-html ((:textarea
(or disabled
(not authorized
)) :disabled
"disabled")
864 var authorized = true;
865 return element.innerHTML = ['<TEXTAREA', disabled || !authorized ? [' DISABLED=\"', 'disabled', '\"'].join('') : '', '>Edit me</TEXTAREA>'].join('');
868 (test-ps-js plus-is-not-commutative
869 (setf x
(+ "before" x
"after"))
870 "x = 'before' + x + 'after';")
872 (test-ps-js plus-works-if-first
873 (setf x
(+ x
"middle" "after"))
874 "x = x + 'middle' + 'after';")
876 (test-ps-js method-call-op-form
877 (funcall (getprop (+ "" x
) 'to-string
))
878 "('' + x).toString();")
880 (test-ps-js method-call-op-form-args
881 (funcall (getprop (+ "" x
) 'foo
) 1 2 :baz
3)
882 "('' + x).foo(1, 2, 'baz', 3);")
884 (test-ps-js method-call-string
885 ((getprop "hi" 'to-string
))
888 (test-ps-js method-call-conditional
892 (test-ps-js method-call-variable
896 (test-ps-js method-call-array
897 ((@ (list 10 20) to-string
))
898 "[ 10, 20 ].toString();")
900 (test-ps-js method-call-lambda-call
901 (funcall (getprop (funcall (lambda (x) x
) 10) 'to-string
))
902 "(function (x) { return x; })(10).toString();")
904 (test no-whitespace-before-dot
905 (let* ((str (ps* '((@ ((lambda (x) x
) 10) to-string
))))
906 (dot-pos (position #\. str
:test
#'char
=))
907 (char-before (elt str
(1- dot-pos
)))
909 (is (char= char-before a-parenthesis
))))
911 (test-ps-js simple-getprop
912 (let ((foo (create a
1)))
913 (alert (getprop foo
'a
)))
919 (test-ps-js buggy-getprop
920 (getprop foo slot-name
)
923 (test-ps-js buggy-getprop-two
924 (getprop foo
(get-slot-name))
925 "foo[getSlotName()];")
927 (test-ps-js old-case-is-now-switch
928 ;; Switch was "case" before, but that was very non-lispish.
929 ;; For example, this code makes three messages and not one
930 ;; which may have been expected. This is because a switch
931 ;; statment must have a break statement for it to return
932 ;; after the alert. Otherwise it continues on the next
934 (switch (aref blorg i
)
937 (default (alert "default clause")))
939 case 1: alert('one');
940 case 2: alert('two');
941 default: alert('default clause');
944 (test-ps-js lisp-like-case
948 (t (alert "default clause")))
956 default: alert('default clause');
960 (test-ps-js even-lispier-case
962 ((1 2) (alert "Below three"))
964 (t (alert "Something else")))
968 alert('Below three');
973 default: alert('Something else');
976 (test-ps-js otherwise-case
979 (otherwise (alert "default clause")))
984 default: alert('default clause');
987 (test escape-sequences-in-string
988 (let ((escapes `((#\\ .
#\\)
990 (#\f .
,(code-char 12))
991 ("u000B" .
,(code-char #x000b
));;Vertical tab, too uncommon to bother with
994 (#\' .
#\');;Double quote need not be quoted because parenscript strings are single quoted
996 ("u001F" .
,(code-char #x001f
));; character below 32
997 ("u0080" .
,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
998 ("uABCD" .
,(code-char #xabcd
)))));; Really above ascii.
999 (loop for
(js-escape . lisp-char
) in escapes
1000 for generated
= (ps-doc* (format nil
"hello~ahi" lisp-char
))
1001 for wanted
= (format nil
"'hello\\~ahi';" js-escape
)
1002 do
(is (string= (normalize-js-code generated
) wanted
)))))
1004 (test-ps-js getprop-setf
1005 (setf (getprop x
'y
) (+ (+ a
3) 4))
1006 "x.y = (a + 3) + 4;")
1008 (test-ps-js getprop-conditional1
1009 (getprop (if zoo foo bar
) 'x
)
1010 "(zoo ? foo : bar).x;")
1012 (test-ps-js getprop-conditional2
1013 (getprop (if (not zoo
) foo bar
) 'x
)
1014 "(!zoo ? foo : bar).x;")
1016 (test script-star-eval1
1017 (is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x
1) '(setf y
2))))))
1019 (test script-star-eval2
1020 (is (string= "x = 1;" (normalize-js-code (ps* '(setf x
1))))))
1022 (test-ps-js list-with-single-nil
1026 (test-ps-js quoted-nil-is-array
1030 (test-ps-js quoted-nil-is-array1
1034 (test-ps-js literal-nil
1038 (test-ps-js quoted-quoted-nil
1042 (test-ps-js quoted-quoted-nil1
1046 (test-ps-js defsetf1
1047 (progn (defsetf baz
(x y
) (newval) `(set-baz ,x
,y
,newval
))
1053 return setBaz(_js2, _js3, _js1);
1056 (test-ps-js setf-macroexpands1
1057 (macrolet ((bar (x y
)
1059 (setf (bar foo
2) 3))
1062 (test-ps-js defsetf-short
1063 (progn (defsetf baz set-baz
"docstring")
1064 (setf (baz 1 2 3) "foo"))
1065 "setBaz(1, 2, 3, 'foo');")
1067 (test-ps-js defun-setf1
1068 (progn (defun (setf some-thing
) (new-val i1 i2
)
1069 (setf (aref *some-thing
* i1 i2
) new-val
))
1070 (setf (some-thing 1 2) "foo"))
1071 "function __setf_someThing(newVal, i1, i2) {
1072 return SOMETHING[i1][i2] = newVal;
1074 __setf_someThing('foo', 1, 2);")
1076 (test-ps-js defun-optional1
1077 (defun test-opt (&optional x
)
1079 "function testOpt(x) {
1080 return x ? 'yes' : 'no';
1083 (test-ps-js defun-optional2
1084 (defun foo (x &optional y
)
1086 "function foo(x, y) {
1090 (test-ps-js defun-optional3
1091 (defun blah (&optional
(x 0))
1094 if (x === undefined) {
1100 (test-ps-js arglist-optional4
1101 (lambda (&optional
(x 0 supplied?
))
1104 var suppliedwhat = x !== undefined;
1105 if (!suppliedwhat) {
1111 (test-ps-js return-nothing
1112 (defun foo () (return-from foo
))
1117 (test-ps-js return-values
1118 (defun foo () (return-from foo
(values 1 2 3)))
1120 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [2, 3] };
1124 (test-ps-js set-timeout
1125 (set-timeout (lambda () (alert "foo")) 10)
1126 "setTimeout(function () { return alert('foo'); }, 10);")
1128 (test-ps-js operator-precedence
1132 (test-ps-js operators-1
1152 (test-ps-js setf-conditional
1153 (setf foo
(if x
1 2))
1156 (test-ps-js obj-literal-numbers
1160 (test-ps-js obj-literal-strings
1164 (test-ps-js getprop-string
1168 (test-ps-js getprop-string1
1169 (getprop "bar" 'length
)
1172 (test-ps-js getprop-progn
1173 (getprop (progn (some-fun "abc") "123") "length")
1174 "(someFun('abc'), '123')['length'];")
1176 (test-ps-js getprop-multi1
1177 (getprop foo
1 "two" three
'bar
1 2)
1178 "foo[1]['two'][three].bar[1][2];")
1180 (test-ps-js method-call-block
1181 ((@ (progn (some-fun "abc") "123") to-string
))
1182 "(someFun('abc'), '123').toString();")
1184 (test-ps-js create-blank
1188 (test-ps-js blank-object-literal
1192 (test-ps-js array-literal1
1196 (test-ps-js array-literal2
1200 (test-ps-js array-literal3
1204 (test-ps-js array-literal4
1208 (test-ps-js array-literal5
1209 ([] (1 2) ("a" "b"))
1210 "[[1, 2], ['a', 'b']];")
1212 (test-ps-js defun-rest1
1213 (defun foo (&rest bar
)
1214 (alert (aref bar
1)))
1216 var bar = Array.prototype.slice.call(arguments, 0);
1217 return alert(bar[1]);
1220 (test-ps-js defun-rest2
1221 (defun foo (baz &rest bar
) (+ baz
(aref bar
1)))
1222 "function foo(baz) {
1223 var bar = Array.prototype.slice.call(arguments, 1);
1224 return baz + bar[1];
1227 (test-ps-js defun-keyword1
1228 (defun zoo (foo bar
&key baz
) (+ foo bar baz
))
1229 "function zoo(foo, bar) {
1230 var _js2 = arguments.length;
1231 for (var n1 = 2; n1 < _js2; n1 += 2) {
1232 switch (arguments[n1]) {
1234 baz = arguments[n1 + 1];
1238 return foo + bar + baz;
1241 (test-ps-js defun-keyword2
1242 (defun zoo (&key baz
) (* baz baz
))
1244 var _js2 = arguments.length;
1245 for (var n1 = 0; n1 < _js2; n1 += 2) {
1246 switch (arguments[n1]) {
1248 baz = arguments[n1 + 1];
1255 (test-ps-js defun-keyword3
1256 (defun zoo (&key baz
(bar 4)) (* baz bar
))
1258 var _js2 = arguments.length;
1259 for (var n1 = 0; n1 < _js2; n1 += 2) {
1260 switch (arguments[n1]) {
1262 baz = arguments[n1 + 1];
1265 bar = arguments[n1 + 1];
1269 var bar = 'undefined' === typeof bar ? 4 : bar;
1273 (test-ps-js defun-keyword4
1274 (defun hello-world (&key
((:my-name-key my-name
) 1))
1276 "function helloWorld() {
1277 var _js2 = arguments.length;
1278 for (var n1 = 0; n1 < _js2; n1 += 2) {
1279 switch (arguments[n1]) {
1281 myName = arguments[n1 + 1];
1284 var myName = 'undefined' === typeof myName ? 1 : myName;
1288 (test-ps-js arglist-keyword-supplied
1289 (lambda (&key
(foo 1 supplied?
))
1292 var _js2 = arguments.length;
1293 for (var n1 = 0; n1 < _js2; n1 += 2) {
1294 switch (arguments[n1]) {
1296 foo = arguments[n1 + 1];
1297 suppliedwhat = true;
1301 var foo = 'undefined' === typeof foo ? 1 : foo;
1305 (test-ps-js keyword-funcall1
1309 (test-ps-js keyword-funcall2
1310 (func :baz
1 :bar foo
)
1311 "func('baz', 1, 'bar', foo);")
1313 (test-ps-js keyword-funcall3
1315 "fun(a, b, 'baz', c);")
1325 ((= y
(* x
4)) (foo "blah") (* x y
)))
1328 } else if (y === x * 4) {
1333 (test-ps-js if-exp-without-else-return
1334 (defun foo () (return-from foo
(if x
1)))
1336 return x ? 1 : null;
1339 (test-ps-js progn-expression-single-statement
1340 (defun foo () (return-from foo
(progn (* x y
))))
1345 (test-ps-js cond-expression1
1347 (cond ((< 1 2) (bar "foo") (* 4 5))))
1355 (test-ps-js cond-expression2
1357 (cond ((< 2 1) "foo")
1362 } else if (7 === 7) {
1367 (test-ps-js cond-expression-final-t-clause
1369 (cond ((< 1 2) (bar "foo") (* 4 5))
1380 } else if (a === b) {
1382 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
1389 (test-ps-js cond-expression-middle-t-clause
;; should this signal a warning?
1402 (test-ps-js funcall-if-expression
1403 (funcall (getprop document
'write
)
1404 (if (= *linkornot
* 1)
1405 (ps-html ((:a
:href
"#"
1406 :onclick
(ps-inline (transport)))
1409 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>'].join('') : img);")
1411 (test-ps-js negate-number-literal
1415 (test macro-environment1
1416 (is (string= (normalize-js-code (let* ((macroname (gensym)))
1417 (ps* `(defmacro ,macroname
(x) `(+ ,x
123))
1419 (macrolet ((,macroname
(x) `(aref data
,x
)))
1420 (when (,macroname x
)
1421 (setf (,macroname x
) 123)))))))
1424 return data[x] ? (data[x] = 123) : null;
1427 (test macro-environment2
1428 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
1429 (defpsmacro macro-environment2-macro
(x)
1430 `(+ ,outer-lexical-variable
,x
))
1431 (ps* '(macro-environment2-macro 2))))
1432 (normalize-js-code "1 + 2;"))))
1434 (test-ps-js ampersand-whole-1
1435 (macrolet ((foo (&whole foo bar baz
)
1436 (declare (ignore bar baz
))
1437 (with-standard-io-syntax (format nil
"~a" foo
))))
1441 (test-ps-js ampersand-whole-2
1442 (macrolet ((foo (&whole foo bar baz
)
1447 (test-ps-js keyword-consistent
1451 (test-ps-js simple-symbol-macrolet
1452 (symbol-macrolet ((x 1)) x
)
1455 (test-ps-js compound-symbol-macrolet
1456 (symbol-macrolet ((x 123)
1461 (test-ps-js define-symbol-macro
1462 (progn (define-symbol-macro tst-sym-macro
2)
1466 (test-ps-js define-symbol-macro1
1467 (progn (define-symbol-macro tst-sym-macro1
2)
1468 (foo tst-sym-macro1
))
1471 (test-ps-js expression-progn
1472 (1+ (progn (foo) (if x
1 2)))
1473 "(foo(), x ? 1 : 2) + 1;")
1475 (test-ps-js let-decl-in-expression
1477 (if x
1 (let* ((foo x
)) foo
)))
1487 (test-ps-js special-var1
1488 (progn (defvar *foo
*)
1495 FOO_TMPSTACK1 = FOO;
1499 FOO = FOO_TMPSTACK1;
1503 (test-ps-js special-var2
1504 (progn (defvar *foo
*)
1513 FOO_TMPSTACK1 = FOO;
1515 return FOO * 2 * BAZ;
1517 FOO = FOO_TMPSTACK1;
1521 (test-ps-js literal1
1525 (test-ps-js literal2
1529 (test-ps-js setf-dec1
1533 (test-ps-js setf-dec2
1537 (test-ps-js special-char-equals
1541 (test-ps-js setf-operator-priority
1543 (or (getprop cache id
)
1544 (setf (getprop cache id
) ((@ document get-element-by-id
) id
))))
1546 return cache[id] || (cache[id] = document.getElementById(id));
1549 (test-ps-js aref-operator-priority
1550 (aref (if (and x
(> (length x
) 0))
1554 "(x && x.length > 0 ? x[0] : y)[z];")
1556 (test-ps-js aref-operator-priority1
1557 (aref (or (getprop x
'y
)
1562 (test-ps-js aref-operator-priority2
1566 (test-ps-js negate-operator-priority
1575 (delete (if a
(or b c
) d
))
1576 "delete (a ? b || c : d);")
1579 (not (if (or x
(not y
)) z
))
1580 "!(x || !y ? z : null);")
1587 (instanceof (or a b
) (if x y z
))
1588 "((a || b) instanceof (x ? y : z));")
1591 (or x
(if (= x
0) "zero" "empty"))
1592 "x || (x === 0 ? 'zero' : 'empty');")
1594 (test-ps-js named-op-expression
1598 (test-ps-js named-op-expression1
1602 (test-ps-js aref-array-expression
1604 "(a || b || c)[0];")
1606 (test-ps-js getprop-operator
1607 (getprop (or a b c
) 'd
)
1610 (test-ps-js getprop-parens
1611 (getprop (getprop foo
'bar
) 'baz
)
1614 (test-ps-js funcall-funcall
1618 (test-ps-js expression-funcall
1619 ((or (@ window eval
) eval
) foo nil
)
1620 "(window.eval || eval)(foo, null);")
1622 (test-ps-js expression-funcall1
1623 (((or (@ window eval
) eval
) foo nil
))
1624 "(window.eval || eval)(foo, null)();")
1626 (test-ps-js expression-funcall2
1627 (((or (@ window eval
) eval
)) foo nil
)
1628 "(window.eval || eval)()(foo, null);")
1630 (test-ps-js who-html1
1631 (who-ps-html (:span
:class
"ticker-symbol"
1632 :ticker-symbol symbol
1633 (:a
:href
"http://foo.com"
1635 (:span
:class
"ticker-symbol-popup")))
1636 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>'].join('');")
1638 (test-ps-js who-html2
1639 (who-ps-html (:p
"t0" (:span
"t1")))
1640 "'<P>t0<SPAN>t1</SPAN></P>';")
1643 ((lambda () (flet ((foo (x)
1647 var foo = function (x) {
1654 (flet ((foo (x) (1+ x
))
1658 var foo = function (x) {
1661 var bar = function (y) {
1668 (flet ((foo (x) (+ 2 x
)))
1669 (flet ((foo (x) (1+ x
))
1670 (bar (y) (+ 2 (foo y
))))
1673 var foo = function (x) {
1676 var foo1 = function (x) {
1679 var bar = function (y) {
1682 return bar(foo1(1));
1686 ((lambda () (labels ((foo (x)
1689 (+ x
(foo (1- x
))))))
1692 var foo = function (x) {
1693 return 0 === x ? 0 : x + foo(x - 1);
1699 (labels ((foo (x) (1+ (bar x
)))
1700 (bar (y) (+ 2 (foo y
))))
1703 var foo = function (x) {
1706 var bar = function (y) {
1713 (labels ((foo (x) (1+ x
))
1714 (bar (y) (+ 2 (foo y
))))
1717 var foo = function (x) {
1720 var bar = function (y) {
1726 (test-ps-js labels-lambda-list
1727 (labels ((foo (x &optional
(y 0))
1731 var foo = function (x, y) {
1732 if (y === undefined) {
1740 (test-ps-js for-loop-var-init-exp
1742 (do* ((y (if x
0 1) (1+ y
))
1747 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
1756 (test-ps-js literal-array
1760 (test-ps-js literal-array-1
1764 (test-ps-js literal-array-literal
1768 (test-ps-js literal-array-literal1
1772 (test ps-lisp-expands-in-lexical-environment
1773 (is (string= "5;" (let ((x 5))
1776 (test ps-lisp-expands-in-lexical-environment1
1777 (is (string= "1 + 5;" (let ((x 5))
1778 (ps (+ 1 (lisp x
)))))))
1780 (test ps-lisp-expands-in-lexical-environment2
1781 (is (string= "1 + 2 + 3;" (let ((x 2))
1782 (ps (+ 1 (lisp x
) 3))))))
1784 (test ps
*-lisp-expands-in-null-lexical-environment
1785 (signals unbound-variable
(let ((x 5))
1786 (declare (ignore x
))
1789 (test ps
*-lisp-expands-in-dynamic-environment
1790 (is (string= "1 + 2;"
1792 (declare (special foo
))
1793 (ps* '(+ 1 (lisp (locally (declare (special foo
)) foo
))))))))
1795 (test ps-lisp-dynamic-environment
1796 (is (string= "1 + 2;"
1798 (declare (special foo
))
1799 (ps (+ 1 (lisp foo
)))))))
1801 (test-ps-js nested-if-expressions1
1803 (return-from foo
(if (if x y z
) a b
)))
1812 (test-ps-js nested-if-expressions2
1814 (if x y
(if z a b
)))
1893 (test-ps-js let-exp1
1944 (test-ps-js symbol-macrolet-var
1945 (symbol-macrolet ((x y
))
1949 (test-ps-js setf-conditional1
1950 (setf x
(unless (null a
) (1+ a
)))
1951 "x = a != null ? a + 1 : null;")
1953 (test-ps-js setf-let1
1954 (setf x
(let ((a 1)) a
))
1960 (test-ps-js setf-let2
1961 (setf x
(let ((a (foo)))
1966 return a != null ? a + 1 : null;
1969 (test-ps-js symbol-macro-env1
1970 (symbol-macrolet ((bar 1))
1971 (macrolet ((bar (x y
) `(+ ,x
,y
)))
1975 (test-ps-js symbol-macrolet-fun1
1976 (symbol-macrolet ((baz +))
1980 (test-ps-js lisp2-namespaces1
1982 (setf list
(list 1 2 3)))
1985 return list = [1, 2, 3];
1988 (test-ps-js let-shadows-symbol-macrolet
1989 (symbol-macrolet ((x y
))
1999 (test-ps-js let-rename-optimization1
2007 (test-ps-js let-rename-optimization2
2016 (test-ps-js symbol-macro-array
2017 (symbol-macrolet ((x 1))
2021 (test-ps-js symbol-macro-obj
2022 (symbol-macrolet ((x (+ 1 2)))
2026 (test-ps-js symbol-macro-obj1
2027 (symbol-macrolet ((x (+ 1 2)))
2031 (test-ps-js symbol-macro-getprop1
2032 (symbol-macrolet ((x (+ 1 2)))
2036 (test-ps-js symbol-macro-getprop1
2037 (symbol-macrolet ((x (+ 1 2)))
2041 (test-ps-js let-let-create
2051 (test-ps-js symbol-macro-conditional1
2052 (symbol-macrolet ((x y
))
2060 (test-ps-js symbol-macro-conditional2
2061 (symbol-macrolet ((x y
))
2065 (test-ps-js preserve-this
2067 (let ((y (block nil
(bar this
))))
2070 var y = (function () {
2076 (test-ps-js flet-apply
2077 (flet ((foo () 'bar
))
2078 (apply (function foo
) nil
))
2080 var foo = function () {
2083 return foo.apply(this, null);
2086 (test-ps-js let-apply
2087 (let ((foo (lambda () 1)))
2088 (let ((foo (lambda () 2)))
2091 var foo = function () {
2094 var foo1 = function () {
2097 return foo1.apply(this, null);
2100 (test-ps-js flet-let
2101 (flet ((x (x) (1+ x
)))
2105 var x = function (x) {
2112 (test-ps-js let-flet
2114 (flet ((x (x) (1+ x
)))
2118 var x1 = function (x) {
2124 (test-ps-js labels-let
2125 (labels ((x (x) (1+ x
)))
2129 var x = function (x) {
2136 (test-ps-js let-labels
2138 (labels ((x (x) (1+ x
)))
2142 var x1 = function (x) {
2148 (test-ps-js macrolet-let-inteference
2149 (macrolet ((a (n) `(+ ,n
5)))
2151 (let ((b (a (- a
4))))
2155 var b = (a - 4) + 5;
2159 (test-ps-js let-subtract-add
2175 (test-ps-js create-reserved-word
2177 "({ 'default' : 1 });")
2179 (test-ps-js getprop-reserved-word
2180 (getprop foo
:default
)
2183 (test-ps-js getprop-reserved-word1
2184 (getprop foo
'default
)
2187 (test-ps-js eval-when-ps-side
2188 (eval-when (:execute
)
2192 (defvar *lisp-output
* nil
)
2194 (test eval-when-lisp-side
()
2195 (setf *lisp-output
* 'original-value
)
2196 (let ((js-output (normalize-js-code
2197 (ps-doc* `(eval-when (:compile-toplevel
)
2198 (setf *lisp-output
* 'it-works
))))))
2199 (is (eql 'it-works
*lisp-output
*))
2200 (is (string= "" js-output
))))
2202 (defpsmacro my-in-package
(package-name)
2203 `(eval-when (:compile-toplevel
)
2204 (setf *lisp-output
* ,package-name
)))
2206 (test eval-when-macro-expansion
()
2207 (setf *lisp-output
* 'original-value
)
2208 (let ((js-output (normalize-js-code
2210 (my-in-package :cl-user
)
2212 (declare (ignore js-output
))
2213 (is (eql :cl-user
*lisp-output
*))))
2215 (test eval-when-macrolet-expansion
()
2216 (setf *lisp-output
* 'original-value
)
2217 (let ((js-output (normalize-js-code
2218 (ps-doc* `(macrolet ((my-in-package2 (package-name)
2219 `(eval-when (:compile-toplevel
)
2220 (setf *lisp-output
* ,package-name
))))
2221 (my-in-package2 :cl-user
)
2223 (declare (ignore js-output
))
2224 (is (eql :cl-user
*lisp-output
*))))
2226 (test-ps-js getprop-keyword
2230 (test-ps-js nary-comparison1
2231 (lambda () (< 1 2 3))
2234 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
2237 (test-ps-js chain-getprop1
2238 (chain ($
"foo") (bar x z
) frob
(baz 5))
2239 "$('foo').bar(x, z).frob.baz(5);")
2241 (test-ps-js chain-getprop2
2242 (chain ($
"foo") bar baz
)
2243 "$('foo').bar.baz;")
2245 (test-ps-js chain-getprop3
2246 (chain ($
"foo") bar
(x y
) baz
)
2247 "$('foo').bar.x(y).baz;")
2249 (test-ps-js flet-expression
2250 (1+ (flet ((foo (x) (1+ x
)))
2253 var foo = function (x) {
2259 (test-ps-js flet-lambda-list
2260 (flet ((foo (x &key
(y 0))
2264 var foo = function (x) {
2265 var _js2 = arguments.length;
2266 for (var n1 = 1; n1 < _js2; n1 += 2) {
2267 switch (arguments[n1]) {
2269 y = arguments[n1 + 1];
2272 var y = 'undefined' === typeof y ? 0 : y;
2275 return foo(1, 'y', 2);
2278 (test-ps-js return-case-break-elimination
2293 (test-ps-js aplusplus
2297 (test-ps-js astarstar
2301 (test-ps-js switch-return-fallthrough
2319 (test-ps-js return-last-case
2334 (test-ps-js return-macrolet
2337 (macrolet ((x () 1))
2350 (test-ps-js mv-bind1
2351 (multiple-value-bind (a b
)
2359 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2362 var _db2 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2367 __PS_MV_REG = prevMv1;
2371 (test-ps-js mv-bind2
2372 (multiple-value-bind (a b
)
2381 var prevMv2 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2384 var _db4 = doesnt === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2389 __PS_MV_REG = prevMv2;
2393 (test-ps-js multiple-value-bind-simple
2394 (multiple-value-bind (a b
) (blah)
2397 var prevMv1 = 'undefined' === typeof __PS_MV_REG ? (__PS_MV_REG = undefined) : __PS_MV_REG;
2400 var _db2 = blah === __PS_MV_REG['tag'] ? __PS_MV_REG['values'] : [];
2404 __PS_MV_REG = prevMv1;
2409 (lambda () (values))
2420 (lambda () (values x y
))
2422 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2427 (lambda () (values x y z
))
2429 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y, z] };
2433 (test-ps-js values-return
2435 (return-from foo
(values (* x x
) y
)))
2436 "function foo(x, y) {
2438 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : [y] };
2442 (test-ps-js return-macrolet1
2445 (symbol-macrolet ((x 2))
2446 (loop do
(+ x x
)))))
2453 (test-ps-js return-cond
2456 (cond ((foo? x
) (loop for y in x do
(foo y
)))
2461 var _js2 = x.length;
2462 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2466 } else if (barwhat(x)) {
2473 (test-ps-js return-case
2477 (1 (loop for y in x do
(foo y
)))
2483 var _js2 = x.length;
2484 for (var _js1 = 0; _js1 < _js2; _js1 += 1) {
2496 (test-ps-js return-case1
2514 (test-ps-js lambda-loop-if-return
2517 (loop for y in x do
(foo y
))
2521 var _js4 = x.length;
2522 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2531 (test-ps-js lambda-loop-if-return1
2535 (progn (loop for y in x do
(foo y
))
2540 return foo(function () {
2542 var _js4 = x.length;
2543 for (var _js3 = 0; _js3 < _js4; _js3 += 1) {
2547 throw { '__ps_block_tag' : 'baz',
2548 '__ps_value1' : null };
2553 } catch (_ps_err5) {
2554 if (_ps_err5 && 'baz' === _ps_err5['__ps_block_tag']) {
2555 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err5['__ps_values'] };
2556 return _ps_err5['__ps_value1'];
2563 (test-ps-js switch-loop
2566 (1 (dolist (a b
)))))
2570 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
2577 (test-ps-js switch-folds-blocks
2580 (1 (loop repeat
3 do
(alert "foo")))
2585 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
2594 (test-ps-js setf-places-before-macros
2596 (defsetf left
(el) (offset)
2597 `(setf (@ ,el style left
) ,offset
))
2598 (macrolet ((left (el)
2599 `(@ ,el offset-left
)))
2605 _js2.style.left = _js1;
2606 return x.offsetLeft;
2609 (test-ps-js for-return
2610 (lambda () (dolist (arg args
) (foo arg
)))
2612 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
2613 arg = args[_js_idx1];
2618 (test-ps-js try-catch-return
2636 (test-ps-js defun-setf-optional
2637 (defun (setf foo
) (new-value b
&optional c
)
2638 (setf (aref b
(or c
0)) new-value
))
2639 "function __setf_foo(newValue, b, c) {
2640 return b[c || 0] = newValue;
2643 (test-ps-js defun-setf-rest
2644 (progn (defun (setf foo
) (new-value b
&rest foo
)
2645 (do-something b foo new-value
))
2646 (setf (foo x
1 2 3 4) 5))
2647 "function __setf_foo(newValue, b) {
2648 var foo = Array.prototype.slice.call(arguments, 2);
2649 return doSomething(b, foo, newValue);
2651 __setf_foo(5, x, 1, 2, 3, 4);")
2653 (test-ps-js return-null
2654 (defun foo () (return-from foo nil
))
2659 (test-ps-js implicit-return-null
2666 (test-ps-js implicit-return-null
2673 (test-ps-js return-conditional-nested
2674 (defun blep (ss x y
)
2678 (destructuring-bind (a b
) pair
2679 (unless (or (null a
) (null b
))
2680 (let ((val (baz a b
)))
2685 "function blep(ss, x, y) {
2691 if (!(a == null || b == null)) {
2692 var val = baz(a, b);
2695 return !blee() ? true : null;
2703 ;; this test needs to be rewritten when named blocks are implemented!!!!
2704 (test-ps-js return-when-returns-broken-return
2706 (return-from foo
(when x
1))
2709 return x ? 1 : null;
2713 (test-ps-js return-case-conditional
2717 (123 (when (bar) t
))
2722 return bar() ? true : null;
2728 (test-ps-js return-try-conditional
2736 return x ? 1 : null;
2744 (test-ps-js function-declare-special
2746 (declare (special *foo
*))
2752 FOO_TMPSTACK1 = FOO;
2756 FOO = FOO_TMPSTACK1;
2760 (test-ps-js declare-special-let
2762 (declare (special *foo
*))
2767 FOO_TMPSTACK1 = FOO;
2771 FOO = FOO_TMPSTACK1;
2775 (test-ps-js declare-special-let
*
2776 (let* ((*foo
* 123) (*bar
* (+ *foo
* *bar
*)))
2777 (declare (special *foo
* *bar
*))
2782 FOO_TMPSTACK1 = FOO;
2786 BAR_TMPSTACK2 = BAR;
2790 BAR = BAR_TMPSTACK2;
2793 FOO = FOO_TMPSTACK1;
2797 (test-ps-js defun-multiple-declarations-around-docstring
2799 (declare (ignorable x y
))
2800 (declare (integer x
) (float y
))
2801 "Fooes X while barring Y."
2802 (declare (special *foo
*) (special *bar
*))
2803 (let ((*bar
* (bar y
)))
2805 "/** Fooes X while barring Y. */
2806 function foo(x, y) {
2809 BAR_TMPSTACK1 = BAR;
2813 BAR = BAR_TMPSTACK1;
2817 (test-ps-js macro-null-toplevel
2819 (defmacro macro-null-toplevel
()
2821 (macro-null-toplevel))
2824 (test-ps-js define-symbol-macro-let
2826 (define-symbol-macro test-symbol-macro
1)
2827 (let ((test-symbol-macro 2))
2828 (1+ test-symbol-macro
))
2829 (1+ test-symbol-macro
))
2831 var testSymbolMacro1 = 2;
2832 return testSymbolMacro1 + 1;
2836 (test-ps-js define-symbol-macro-flet
2838 (define-symbol-macro test-symbol-macro1
1)
2839 (flet ((test-symbol-macro1 () 2))
2840 (foo test-symbol-macro1
)
2841 (test-symbol-macro1))
2842 (bar test-symbol-macro1
))
2844 var testSymbolMacro1_1 = function () {
2848 return testSymbolMacro1_1();
2852 (test compile-stream-nulls
2855 (with-input-from-string (s "
2856 (defmacro macro-null-toplevel ()
2858 (macro-null-toplevel)")
2859 (ps-compile-stream s
)))))
2861 (test compile-stream1
2864 var testSymbolMacro1_1 = function () {
2868 return testSymbolMacro1_1();
2872 (with-input-from-string (s "
2873 (define-symbol-macro test-symbol-macro1 1)
2874 (flet ((test-symbol-macro1 () 2))
2875 (foo test-symbol-macro1)
2876 (test-symbol-macro1))
2877 (bar test-symbol-macro1)")
2878 (ps::with-blank-compilation-environment
(ps-compile-stream s
))))))
2880 (test-ps-js equality-nary1
2881 (let ((x 10) (y 10) (z 10))
2888 return (_cmp1 = y, x === _cmp1 && _cmp1 === z);
2891 (test-ps-js equality1
2902 (test-ps-js getprop-quote-reserved
2903 (getprop foo
':break
)
2906 (test-ps-js defun-block-return-from
2917 (test-ps-js block-return-from
2921 (return-from scope
))
2931 (test-ps-js block-return-from0
2936 (return-from scope
))
2946 (test-ps-js block-return-from01
2951 (return-from scope
))
2965 (test-ps-js block-return-from02
2970 (return-from scope
(foobar)))
2985 (test-ps-js block-return-from1
2990 (return-from scope
))
3004 (test-ps-js block-return-from2
3010 (return-from scope
6))
3021 (test-ps-js let-funcall
3035 (test-ps-js symbol-macrolet-funcall
3036 (symbol-macrolet ((foo bar
))
3037 (funcall foo
1 2 3))
3040 (test-ps-js times-assign
3044 (test-ps-js vector-literal
3049 (+ 1 (rem 2 (+ 3 4)))
3052 (test-ps-js non-associative
3053 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
3054 "1 / (2 / 3) + (1 - (2 - 3));")
3056 (test-ps-js lambda-apply
3058 (apply (lambda (y) (bar (1+ y
))) x
))
3060 return (function (y) {
3065 (test-ps-js operator-expressions-nested-let
3066 (let ((x (let ((y 1))
3075 (test-ps-js operator-expressions-array-nested-let
3076 (list (let ((y 1)) y
) 2)
3082 (test-ps-js add-subtract-precedence
3086 (test-ps-js ps-inline-toplevel
3088 "'javascript:' + 'foo()';")
3090 (test-ps-js no-clause-progn-exp
3094 (test-ps-js no-clause-progn-return
3096 (return-from foo
(progn)))
3101 (test-ps-js empty-cond-clause
3102 (setf x
(cond ((foo))))
3103 "x = (function () { var testResult1 = foo(); return testResult1 ? testResult1 : null; })();")
3105 (test-ps-js empty-cond-clause1
3106 (setf x
(cond ((foo) 123)
3111 var testResult1 = bar();
3115 if (true) { return 456; };
3119 (test-ps-js let-no-body
3121 (return-from foo
(let ((foo bar
)))))
3127 (test-ps-js rename-lexical-dupes
3129 (list (let ((foo 12)) (* foo
2))
3130 (let ((foo 13)) (* foo
3))))
3134 return [(foo = 12, foo * 2), (foo1 = 13, foo1 * 3)];
3137 (test-ps-js defun-comment1
3139 "BARBAR is a revolutionary new foobar.
3143 * BARBAR is a revolutionary new foobar.
3150 (test-ps-js var-comment
3155 (test-ps-js case-return-break-broken-return
3158 ("bar" (if y
(return-from foo t
) nil
))
3173 (test-ps-js case-return-break1-broken-return
3176 ("bar" (if y
(return-from foo t
)))
3191 (test-ps-js setf-progn
3192 (setf foo
(progn (bar) (baz) 3))
3197 (test-ps-js var-progn
3198 (var x
(progn (foo) (bar)))
3202 (test-ps-js implicit-return-loop
3206 (loop :repeat
100 :do
(bar))
3212 for (var _js2 = 0; _js2 < 100; _js2 += 1) {
3219 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
3220 (test-ps-js loop-closures
3221 (dotimes (i 10) (lambda () (+ i
1)))
3223 for (var i = 0; i < 10; i += 1) {
3232 (test-ps-js loop-closures-let
3235 (lambda () (+ i x
))))
3237 for (var i = 0; i < 10; i += 1) {
3238 with ({ i : i, x : null }) {
3247 (test-ps-js loop-closures-flet
3248 (dotimes (i 10) (flet ((foo (x) (+ i x
))) (lambda () (foo i
))))
3250 for (var i = 0; i < 10; i += 1) {
3251 with ({ foo : null, i : i }) {
3252 var foo = function (x) {
3262 (test-ps-js while-closures-let
3265 (lambda () (+ 1 x
))))
3267 with ({ x : null }) {
3275 (test-ps-js dotted-list-form
3278 (destructuring-bind (b . c
)
3284 var c = bar.length > 1 ? bar.slice(1) : [];
3289 (test-ps-js explicit-nil-block
3292 (block nil
(return (foo 2)) (+ 1 2))
3304 (test-ps-js dynamic-extent-function-return
3307 (return-from foo
6))))
3310 return (function () {
3311 throw { '__ps_block_tag' : 'foo', '__ps_value1' : 6 };
3313 } catch (_ps_err1) {
3314 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3315 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3316 return _ps_err1['__ps_value1'];
3323 (test-ps-js dynamic-extent-function-return-nothing
3326 (return-from foo
))))
3329 return (function () {
3330 throw { '__ps_block_tag' : 'foo', '__ps_value1' : null };
3332 } catch (_ps_err1) {
3333 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3334 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3335 return _ps_err1['__ps_value1'];
3342 (test-ps-js dynamic-extent-function-return-values
3345 (return-from foo
(values 1 2 3)))))
3349 return (function () {
3350 throw { '__ps_block_tag' : 'foo',
3352 '__ps_values' : [2, 3] };
3354 } catch (_ps_err1) {
3355 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3356 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3357 return _ps_err1['__ps_value1'];
3364 (test-ps-js dynamic-extent-function-return-funcall
3367 (return-from foo
(if baz
6 5)))))
3370 return (function () {
3371 throw { '__ps_block_tag' : 'foo', '__ps_value1' : baz ? 6 : 5 };
3373 } catch (_ps_err1) {
3374 if (_ps_err1 && 'foo' === _ps_err1['__ps_block_tag']) {
3375 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3376 return _ps_err1['__ps_value1'];
3383 (test-ps-js block-dynamic-return
3384 (var foo
((lambda ()
3386 ((lambda () (return 6)))
3388 "var foo = (function () {
3391 throw { '__ps_block_tag' : 'nilBlock', '__ps_value1' : 6 };
3394 } catch (_ps_err1) {
3395 if (_ps_err1 && 'nilBlock' === _ps_err1['__ps_block_tag']) {
3396 __PS_MV_REG = { 'tag' : arguments.callee, 'values' : _ps_err1['__ps_values'] };
3397 return _ps_err1['__ps_value1'];
3404 (test-ps-js block-dynamic-return1
3405 (var foo
((lambda ()
3407 ((lambda () (return 6)))
3410 "var foo = (function () {
3417 return foobar(1, 2);
3420 (test-ps-js iteration-lambda-capture-no-need
3421 (dolist (x y
) (lambda (x) (1+ x
))) ;; there's really no need to create a 'with' scope in this case
3423 for (var x = null, _js_idx1 = 0; _js_idx1 < y.length; _js_idx1 += 1) {
3433 (test-ps-js case-invert1
3434 (encodeURIComponent fooBar
)
3435 "encodeURIComponent(fooBar);")
3437 (test-ps-js simple-ash
3438 (+ (ash 4 1) (ash 4 -
1))
3439 "(4 << 1) + (4 >> 1);")
3441 (test-ps-js progn-nil-expression
3442 (bar (progn (foo) nil
))
3443 "bar((foo(), null));")
3445 (test-ps-js other-progn-nil-exp
3447 (or (foo) (progn (bar) nil
)))
3449 return foo() || (bar(), null);
3452 (test-ps-js lambda-nil-return
3465 (test-ps-js lambda-nil-return-implicit-nested2
3471 (return-from foo i
)))
3477 for (var i = 0; i < 4; i += 1) {
3484 (test-ps-js throw-is-a-statement
3486 (let ((result (foo)))
3487 (unless (null result
)
3491 if (result != null) {
3496 (test-ps-js expressify1
3498 (when (some-condition)
3503 if (someCondition()) {
3510 (test-ps-js case-when-return
3513 ("a" (when (foo) (return-from blah
111)))
3528 (test-ps-js flet-return-from
3531 (return-from foo
123)))
3534 var foo = function () {
3540 (test-ps-js flet-return-from1
3542 (return-from foo
123)))
3545 var foo = function () {
3551 (test-ps-js lambda-docstring-declarations
3553 "This is a docstring"
3554 (declare (ignore x
))
3560 (test-ps-js setf-let-exp
3561 (setf foo
(let ((x (+ 1 2)))
3563 "foo = (function () {
3565 return x ? 123 : 456;
3568 (test-ps-js create-let-exp
3569 (create :abc
(let ((x (+ 1 2)))
3571 "({ 'abc' : (function () {
3573 return x ? 123 : 456;
3576 (test-ps-js eql-eql-eql-precedence
3577 (unless (equal (= 3 3) (= 3 4))
3578 (chain console
(log 1)))
3579 "if ((3 === 3) != (3 === 4)) {
3583 (test-ps-js case-cond-breaks
3589 (return-from blah nil
))
3612 (test-ps-js cond-double-t
3625 (test-ps-js let-let-funcall-lambda
3628 (funcall (lambda (x) (+ x
9)) x
)))
3632 return (function (x) {
3637 (test-ps-js let-let-lambda
3640 (lambda (x) (+ x
9))))
3644 return function (x) {
3649 (test-ps-js let-lambda
3651 (lambda (x) (+ x
9)))
3654 return function (x) {
3659 (test-ps-js symbol-macrolet-no-shadow-lambda
3660 (symbol-macrolet ((x y
))
3661 (lambda (x) (+ x x
)))
3666 (test-ps-js divide-one-arg-reciprocal
3670 (test-ps-js division-not-associative
3674 (test-ps-js divide-expressions
3678 (test-ps-js divide-expressions1
3680 "Math.floor((x - 1) / y);")
3682 (test-ps-js lexical-funargs-shadow1
3693 (test-ps-js times-rem
3697 (test-ps-js rem-divide
3701 (test-ps-js case-break-return
3702 (lambda () (case x
(:foo
) (:bar
1)))
3712 (test-ps-js trivial-expression-switch
3713 (foobar (case x
(1 2)))
3714 "foobar((function () {
3721 (test-ps-js trivial-expression-while
3722 (foobar (while (< 0 x
) (decf x
)))
3723 "foobar((function () {
3729 (test-ps-js funcall-block-expression-loop-lambda
3730 (foobar (loop for i from
0 to
10 do
(1+ i
)))
3731 "foobar((function () {
3732 for (var i = 0; i <= 10; i += 1) {
3737 (test-ps-js plus-block-expression-loop-lambda
3738 (1+ (loop for i from
0 to
10 do
(1+ i
)))
3740 for (var i = 0; i <= 10; i += 1) {
3745 (test-ps-js let-closures-rename
3747 (let ((x 1)) (lambda () (1+ x
)))
3748 (let ((x 2)) (lambda () (1+ x
))))
3755 return function () {
3760 (test-ps-js let-closures-rename1
3764 (lambda () (+ x y
))))
3767 (lambda () (+ x y
)))))
3776 return function () {
3781 (test-ps-js let-closures-rename2
3782 (defun make-closures ()
3784 (let ((x 1)) (lambda () (1+ x
)))
3785 (let ((x 2)) (lambda () (1+ x
)))))
3786 "function makeClosures() {
3789 return [(x = 1, function () {
3791 }), (x1 = 2, function () {
3797 (test-ps-js conditional-not-used-up
3809 (test-ps-js toplevel-local-scope
3810 (create "fn" (let ((x 5)) (lambda () x
)))
3811 "({ 'fn' : (function () {
3813 return function () {
3818 (test-ps-js toplevel-local-scope1
3819 (defvar foo
(create "fn" (let ((x 5)) (lambda () x
))))
3820 "var foo = { 'fn' : (function () {
3822 return function () {
3827 (test-ps-js block-let
3830 (return-from foobar x
)
3838 (test-ps-js expressionize-if-macroexpand-error
3839 (progn (defmacro xbaz
() `(blah))
3845 "function foo(xbaz) {
3855 (test-ps-js toplevel-defun-macroexpand
3856 (progn (defmacro defun-js
(name lambda-list
&body body
)
3857 `(defun ,name
,lambda-list
,@body
))
3860 (defun-js bar
() (1+ foo
))
3868 (test-ps-js js-ir-package-unique-symbols
3869 (loop :for i
:from
0 :below
5 :do
3870 (let ((block (elt blocks i
)))
3874 for (var i = 0; i < 5; i += 1) {
3875 var block = blocks[i];
3883 (test-ps-js broken-quote-expansion1
3888 return p.x < 0 ? p.y : p.x;
3891 (test-ps-js broken-quote-expansion2
3893 (define-symbol-macro foo123
(ps:@ a foo123
))
3894 (lambda () (when (> foo123
1) 2)))
3896 return a.foo123 > 1 ? 2 : null;
3899 (test-ps-js unused-named-block-not-printed1
3906 (test-ps-js unused-named-block-not-printed2
3914 (test-ps-js unused-named-block-not-printed3
3922 (test-ps-js unused-named-block-not-printed4
3931 (test-ps-js trig-no-bind1
3933 "(Math.exp(3.14) + Math.exp(-3.14)) / 2;")
3935 (test-ps-js trig-bind1
3938 var x1 = blah(3.14);
3939 return 2 * Math.log(Math.sqrt((x1 + 1) / 2) + Math.sqrt((x1 - 1) / 2));
3944 ;; (test-ps-js let-defun-toplevel
3945 ;; (progn (let ((foo 0))
3946 ;; (defun bar () foo))
3948 ;; "var bar_foo1 = 0;
3954 ;; (test-ps-js let-defvar-toplevel
3955 ;; (progn (let ((foo 0))
3956 ;; (defvar bar (1+ foo)))
3958 ;; "var bar_foo1 = 0;
3959 ;; var bar = bar_foo1 + 1;
3962 ;; (test-ps-js setf-side-effects
3965 ;; (defun side-effect()
3968 ;; (setf x (+ 2 (side-effect) x 5))))
3969 ;; "var sideEffect_x1 = 10;
3970 ;; function sideEffect() {
3971 ;; sideEffect_x1 = 4;
3974 ;; sideEffect_x1 = 2 + sideEffect() + x + 5;")