1 (in-package #:parenscript-test
)
5 (test-ps-js plus-is-not-commutative
6 (setf x
(+ "before" x
"after"))
7 "x = 'before' + x + 'after';")
9 (test-ps-js plus-works-if-first
10 (setf x
(+ x
"middle" "after"))
11 "x = x + 'middle' + 'after';")
13 (test-ps-js setf-side-effects
19 (setf x
(+ 2 (side-effect) x
5))))
21 function sideEffect() {
25 x = 2 + sideEffect() + x + 5;")
27 (test-ps-js method-call-op-form
28 (funcall (getprop (+ "" x
) 'to-string
))
29 "('' + x).toString();")
31 (test-ps-js method-call-op-form-args
32 (funcall (getprop (+ "" x
) 'foo
) 1 2 :baz
3)
33 "('' + x).foo(1, 2, 'baz', 3);")
35 (test-ps-js method-call-string
36 ((getprop "hi" 'to-string
))
39 (test-ps-js method-call-conditional
43 (test-ps-js method-call-variable
47 (test-ps-js method-call-array
48 ((@ (list 10 20) to-string
))
49 "[ 10, 20 ].toString();")
51 (test-ps-js method-call-lambda-call
52 (funcall (getprop (funcall (lambda (x) x
) 10) 'to-string
))
53 "(function (x) { return x; })(10).toString();")
55 (test no-whitespace-before-dot
56 (let* ((str (ps* '((@ ((lambda (x) x
) 10) to-string
))))
57 (dot-pos (position #\. str
:test
#'char
=))
58 (char-before (elt str
(1- dot-pos
)))
60 (is (char= char-before a-parenthesis
))))
62 (test-ps-js simple-getprop
63 (let ((foo (create a
1)))
64 (alert (getprop foo
'a
)))
68 (test-ps-js buggy-getprop
69 (getprop foo slot-name
)
72 (test-ps-js buggy-getprop-two
73 (getprop foo
(get-slot-name))
74 "foo[getSlotName()];")
76 (test-ps-js old-case-is-now-switch
77 ;; Switch was "case" before, but that was very non-lispish.
78 ;; For example, this code makes three messages and not one
79 ;; which may have been expected. This is because a switch
80 ;; statment must have a break statement for it to return
81 ;; after the alert. Otherwise it continues on the next
83 (switch (aref blorg i
)
86 (default (alert "default clause")))
90 default: alert('default clause');
93 (test-ps-js lisp-like-case
97 (default (alert "default clause")))
105 default: alert('default clause');
109 (test-ps-js even-lispier-case
111 ((1 2) (alert "Below three"))
113 (t (alert "Something else")))
117 alert('Below three');
122 default: alert('Something else');
125 (test-ps-js otherwise-case
128 (otherwise (alert "default clause")))
133 default: alert('default clause');
136 (test escape-sequences-in-string
137 (let ((escapes `((#\\ .
#\\)
139 (#\f .
,(code-char 12))
140 ("u000B" .
,(code-char #x000b
));;Vertical tab, too uncommon to bother with
143 (#\' .
#\');;Double quote need not be quoted because parenscript strings are single quoted
145 ("u001F" .
,(code-char #x001f
));; character below 32
146 ("u0080" .
,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
147 ("uABCD" .
,(code-char #xabcd
)))));; Really above ascii.
148 (loop for
(js-escape . lisp-char
) in escapes
149 for generated
= (ps-doc* `(let ((x ,(format nil
"hello~ahi" lisp-char
)))))
150 for wanted
= (format nil
"var x = 'hello\\~ahi';" js-escape
)
151 do
(is (string= (normalize-js-code generated
) wanted
)))))
153 (test-ps-js getprop-setf
154 (setf (getprop x
'y
) (+ (+ a
3) 4))
157 (test-ps-js getprop-conditional1
158 (getprop (if zoo foo bar
) 'x
)
159 "(zoo ? foo : bar).x;")
161 (test-ps-js getprop-conditional2
162 (getprop (if (not zoo
) foo bar
) 'x
)
163 "(!zoo ? foo : bar).x;")
165 (test script-star-eval1
166 (is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x
1) '(setf y
2))))))
168 (test script-star-eval2
169 (is (string= "x = 1;" (normalize-js-code (ps* '(setf x
1))))))
171 (test-ps-js list-with-single-nil
175 (test-ps-js quoted-nil-is-array
180 (progn (defsetf baz
(x y
) (newval) `(set-baz ,x
,y
,newval
))
185 setBaz(_js2, _js3, _js1);")
187 (test-ps-js setf-macroexpands1
188 (macrolet ((bar (x y
)
190 (setf (bar foo
2) 3))
193 (test-ps-js defsetf-short
194 (progn (defsetf baz set-baz
"docstring")
195 (setf (baz 1 2 3) "foo"))
196 "setBaz(1, 2, 3, 'foo');")
198 (test-ps-js defun-setf1
199 (progn (defun (setf some-thing
) (new-val i1 i2
)
200 (setf (aref *some-thing
* i1 i2
) new-val
))
201 (setf (some-thing 1 2) "foo"))
202 "function __setf_someThing(newVal, i1, i2) {
203 return SOMETHING[i1][i2] = newVal;
205 __setf_someThing('foo', 1, 2);")
207 (test-ps-js defun-optional1
208 (defun test-opt (&optional x
)
210 "function testOpt(x) {
211 return x ? 'yes' : 'no';
214 (test-ps-js defun-optional2
215 (defun foo (x &optional y
)
217 "function foo(x, y) {
221 (test-ps-js defun-optional3
222 (defun blah (&optional
(x 0))
225 if (x === undefined) {
231 (test-ps-js defun-optional4
232 (lambda (&optional
(x 0 supplied?
))
235 var suppliedwhat = x !== undefined;
242 (test-ps-js return-nothing
246 (test-ps-js set-timeout
247 (set-timeout (lambda () (alert "foo")) 10)
248 "setTimeout(function () { return alert('foo'); }, 10);")
250 (test-ps-js operator-precedence
254 (test-ps-js operators-1
274 (test-ps-js setf-conditional
275 (setf foo
(if x
1 2))
278 (test-ps-js obj-literal-numbers
282 (test-ps-js obj-literal-strings
286 (test-ps-js getprop-string
290 (test-ps-js getprop-string1
291 (getprop "bar" 'length
)
294 (test-ps-js getprop-progn
295 (getprop (progn (some-fun "abc") "123") "length")
296 "(someFun('abc'), '123')['length'];")
298 (test-ps-js method-call-block
299 ((@ (progn (some-fun "abc") "123") to-string
))
300 "(someFun('abc'), '123').toString();")
302 (test-ps-js create-blank
306 (test-ps-js blank-object-literal
310 (test-ps-js array-literal1
314 (test-ps-js array-literal2
318 (test-ps-js array-literal3
322 (test-ps-js array-literal4
326 (test-ps-js array-literal5
328 "[[1, 2], ['a', 'b']];")
330 (test-ps-js defun-rest1
331 (defun foo (&rest bar
)
332 (alert (aref bar
1)))
335 for (var i1 = 0; i1 < arguments.length - 0; i1 += 1) {
336 bar[i1] = arguments[i1 + 0];
338 return alert(bar[1]);
341 (test-ps-js defun-rest2
342 (defun foo (baz &rest bar
) (+ baz
(aref bar
1)))
345 for (var i1 = 0; i1 < arguments.length - 1; i1 += 1) {
346 bar[i1] = arguments[i1 + 1];
351 (test-ps-js defun-keyword1
352 (defun zoo (foo bar
&key baz
) (+ foo bar baz
))
353 "function zoo(foo, bar) {
355 var _js2 = arguments.length;
356 for (var n1 = 2; n1 < _js2; n1 += 2) {
357 switch (arguments[n1]) {
359 baz = arguments[n1 + 1];
362 return foo + bar + baz;
365 (test-ps-js defun-keyword2
366 (defun zoo (&key baz
) (* baz baz
))
369 var _js2 = arguments.length;
370 for (var n1 = 0; n1 < _js2; n1 += 2) {
371 switch (arguments[n1]) {
373 baz = arguments[n1 + 1];
379 (test-ps-js defun-keyword3
380 (defun zoo (&key baz
(bar 4)) (* baz bar
))
384 var _js2 = arguments.length;
385 for (var n1 = 0; n1 < _js2; n1 += 2) {
386 switch (arguments[n1]) {
388 baz = arguments[n1 + 1];
391 bar = arguments[n1 + 1];
397 (test-ps-js defun-keyword4
398 (defun hello-world (&key
((:my-name-key my-name
) 1))
400 "function helloWorld() {
402 var _js2 = arguments.length;
403 for (var n1 = 0; n1 < _js2; n1 += 2) {
404 switch (arguments[n1]) {
406 myName = arguments[n1 + 1];
412 (test-ps-js defun-keyword-supplied
413 (lambda (&key
(foo 1 supplied?
))
416 var suppliedwhat = null;
418 var _js2 = arguments.length;
419 for (var n1 = 0; n1 < _js2; n1 += 2) {
420 switch (arguments[n1]) {
422 foo = arguments[n1 + 1];
429 (test-ps-js keyword-funcall1
433 (test-ps-js keyword-funcall2
434 (func :baz
1 :bar foo
)
435 "func('baz', 1, 'bar', foo);")
437 (test-ps-js keyword-funcall3
439 "fun(a, b, 'baz', c);")
449 ((= y
(* x
4)) (foo "blah") (* x y
)))
452 } else if (y === x * 4) {
457 (test-ps-js if-exp-without-else-return
459 "return x ? 1 : null;")
461 (test-ps-js progn-expression-single-statement
462 (return (progn (* x y
)))
465 (test-ps-js cond-expression1
467 (cond ((< 1 2) (bar "foo") (* 4 5))))
475 (test-ps-js cond-expression2
477 (cond ((< 2 1) "foo")
482 } else if (7 === 7) {
487 (test-ps-js cond-expression-final-t-clause
489 (cond ((< 1 2) (bar "foo") (* 4 5))
500 } else if (a === b) {
502 } else if (_cmp1 = 2, _cmp2 = 3, _cmp3 = 4, 1 < _cmp1 && _cmp1 < _cmp2 && _cmp2 < _cmp3 && _cmp3 < 5) {
509 (test-ps-js cond-expression-middle-t-clause
;; should this signal a warning?
522 (test-ps-js funcall-if-expression
523 (funcall (getprop document
'write
)
524 (if (= *linkornot
* 1)
525 (ps-html ((:a
:href
"#"
526 :onclick
(ps-inline (transport)))
529 "document.write(LINKORNOT === 1 ? ['<A HREF=\"#\" ONCLICK=\"', 'javascript:' + 'transport()', '\">', img, '</A>']['join']('') : img);")
531 (test-ps-js negate-number-literal
535 (test macro-environment1
536 (is (string= (normalize-js-code (let* ((macroname (gensym)))
537 (ps* `(defmacro ,macroname
(x) `(+ ,x
123))
539 (macrolet ((,macroname
(x) `(aref data
,x
)))
541 (setf (,macroname x
) 123)))))))
545 return data[x] = 123;
549 (test macro-environment2
550 (is (string= (normalize-js-code (let ((outer-lexical-variable 1))
551 (defpsmacro macro-environment2-macro
(x)
552 `(+ ,outer-lexical-variable
,x
))
553 (ps* '(macro-environment2-macro 2))))
554 (normalize-js-code "1 + 2;"))))
556 (test-ps-js ampersand-whole-1
557 (macrolet ((foo (&whole foo bar baz
)
558 (declare (ignore bar baz
))
559 (format nil
"~a" foo
)))
563 (test-ps-js keyword-consistent
567 (test-ps-js simple-symbol-macrolet
568 (symbol-macrolet ((x 1)) x
)
571 (test-ps-js compound-symbol-macrolet
572 (symbol-macrolet ((x 123)
577 (test-ps-js define-symbol-macro
578 (progn (define-symbol-macro tst-sym-macro
2)
582 (test-ps-js define-symbol-macro1
583 (progn (define-symbol-macro tst-sym-macro1
2)
584 (foo tst-sym-macro1
))
587 (test-ps-js expression-progn
588 (1+ (progn (foo) (if x
1 2)))
589 "(foo(), x ? 1 : 2) + 1;")
591 (test-ps-js let-decl-in-expression
593 (if x
1 (let* ((foo x
)) foo
)))
603 (test-ps-js special-var1
604 (progn (defvar *foo
*)
617 (test-ps-js special-var2
618 (progn (defvar *foo
*)
641 (test-ps-js setf-dec1
645 (test-ps-js setf-dec2
649 (test-ps-js special-char-equals
653 (test-ps-js setf-operator-priority
654 (return (or (getprop cache id
)
655 (setf (getprop cache id
) ((@ document get-element-by-id
) id
))))
656 "return cache[id] || (cache[id] = document.getElementById(id));")
658 (test-ps-js aref-operator-priority
659 (aref (if (and x
(> (length x
) 0))
663 "(x && x.length > 0 ? x[0] : y)[z];")
665 (test-ps-js aref-operator-priority1
666 (aref (or (getprop x
'y
)
671 (test-ps-js aref-operator-priority2
675 (test-ps-js negate-operator-priority
684 (delete (if a
(or b c
) d
))
685 "delete (a ? b || c : d);")
688 (not (if (or x
(not y
)) z
))
689 "!(x || !y ? z : null);")
696 (instanceof (or a b
) (if x y z
))
697 "((a || b) instanceof (x ? y : z));")
700 (or x
(if (= x
0) "zero" "empty"))
701 "x || (x === 0 ? 'zero' : 'empty');")
703 (test-ps-js named-op-expression
707 (test-ps-js named-op-expression1
711 (test-ps-js aref-array-expression
715 (test-ps-js getprop-operator
716 (getprop (or a b c
) 'd
)
719 (test-ps-js getprop-parens
720 (getprop (getprop foo
'bar
) 'baz
)
723 (test-ps-js funcall-funcall
727 (test-ps-js expression-funcall
728 ((or (@ window eval
) eval
) foo nil
)
729 "(window.eval || eval)(foo, null);")
731 (test-ps-js expression-funcall1
732 (((or (@ window eval
) eval
) foo nil
))
733 "(window.eval || eval)(foo, null)();")
735 (test-ps-js expression-funcall2
736 (((or (@ window eval
) eval
)) foo nil
)
737 "(window.eval || eval)()(foo, null);")
739 (test-ps-js who-html1
740 (who-ps-html (:span
:class
"ticker-symbol"
741 :ticker-symbol symbol
742 (:a
:href
"http://foo.com"
744 (:span
:class
"ticker-symbol-popup")))
745 "['<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"', symbol, '\"><A HREF=\"http://foo.com\">', symbol, '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>']['join']('');")
748 ((lambda () (flet ((foo (x)
752 var foo = function (x) {
759 (flet ((foo (x) (1+ x
))
762 "var foo = function (x) {
765 var bar = function (y) {
771 (flet ((foo (x) (+ 2 x
)))
772 (flet ((foo (x) (1+ x
))
773 (bar (y) (+ 2 (foo y
))))
775 "var foo = function (x) {
778 var foo1 = function (x) {
781 var bar = function (y) {
787 ((lambda () (labels ((foo (x)
790 (+ x
(foo (1- x
))))))
793 var foo = function (x) {
797 return x + foo(x - 1);
804 (labels ((foo (x) (1+ (bar x
)))
805 (bar (y) (+ 2 (foo y
))))
807 "var foo = function (x) {
810 var bar = function (y) {
816 (labels ((foo (x) (1+ x
))
817 (bar (y) (+ 2 (foo y
))))
819 "var foo = function (x) {
822 var bar = function (y) {
827 (test-ps-js for-loop-var-init-exp
829 (do* ((y (if x
0 1) (1+ y
))
834 return (function () {
835 for (var y = x ? 0 : 1, z = 0; y !== 3; y += 1, z += 1) {
845 (test-ps-js literal-array
849 (test-ps-js literal-array-1
853 (test ps-lisp-expands-in-lexical-environment
854 (is (string= "5;" (let ((x 5)) (ps (lisp x
))))))
856 (test ps
*-lisp-expands-in-null-lexical-environment
857 (signals error
(let ((x 5)) (declare (ignore x
)) (ps* '(lisp x
)))))
859 (test ps
*-lisp-expands-in-dynamic-environment
860 (is (string= "1 + 2;" (let ((foo 2)) (declare (special foo
)) (ps* '(+ 1 (lisp (locally (declare (special foo
)) foo
))))))))
862 (test ps-lisp-dynamic-environment
863 (is (string= "1 + 2;" (let ((foo 2)) (declare (special foo
)) (ps (+ 1 (lisp foo
)))))))
865 (test-ps-js nested-if-expressions1
866 (return (if (if x y z
) a b
))
867 "return (x ? y : z) ? a : b;")
869 (test-ps-js nested-if-expressions2
870 (return (if x y
(if z a b
)))
871 "return x ? y : (z ? a : b);")
972 (test-ps-js symbol-macrolet-var
973 (symbol-macrolet ((x y
))
977 (test-ps-js setf-conditional1
978 (setf x
(unless (null a
) (1+ a
)))
979 "x = a != null ? a + 1 : null;")
981 (test-ps-js setf-let1
982 (setf x
(let ((a 1)) a
))
985 (test-ps-js setf-let2
986 (setf x
(let ((a (foo)))
989 "x = (a = foo(), a != null ? a + 1 : null);")
991 (test-ps-js symbol-macro-env1
992 (symbol-macrolet ((bar 1))
993 (macrolet ((bar (x y
) `(+ ,x
,y
)))
997 (test-ps-js symbol-macrolet-fun1
998 (symbol-macrolet ((baz +))
1002 (test-ps-js lisp2-namespaces1
1004 (setf list
(list 1 2 3)))
1008 (test-ps-js let-shadows-symbol-macrolet
1009 (symbol-macrolet ((x y
))
1017 (test-ps-js let-rename-optimization1
1023 (test-ps-js let-rename-optimization2
1032 (test-ps-js symbol-macro-array
1033 (symbol-macrolet ((x 1))
1037 (test-ps-js symbol-macro-obj
1038 (symbol-macrolet ((x y
))
1042 (test-ps-js symbol-macro-conditional1
1043 (symbol-macrolet ((x y
))
1051 (test-ps-js symbol-macro-conditional2
1052 (symbol-macrolet ((x y
))
1053 (return (if x x x
)))
1054 "return y ? y : y;")
1056 (test-ps-js flet-apply
1057 (flet ((foo () 'bar
))
1058 (apply (function foo
) nil
))
1059 "var foo = function () {
1062 foo.apply(this, null);")
1064 (test-ps-js let-apply
1065 (let ((foo (lambda () 1)))
1066 (let ((foo (lambda () 2)))
1068 "var foo = function () {
1071 var foo1 = function () {
1074 foo1.apply(this, null);")
1076 (test-ps-js flet-let
1077 (flet ((x (x) (1+ x
)))
1080 "var x = function (x) {
1086 (test-ps-js let-flet
1088 (flet ((x (x) (1+ x
)))
1091 var x1 = function (x) {
1096 (test-ps-js labels-let
1097 (labels ((x (x) (1+ x
)))
1100 "var x = function (x) {
1106 (test-ps-js let-labels
1108 (labels ((x (x) (1+ x
)))
1111 var x1 = function (x) {
1116 (test-ps-js macrolet-let-inteference
1117 (macrolet ((a (n) `(+ ,n
5)))
1119 (let ((b (a (- a
4))))
1125 (test-ps-js let-subtract-add
1139 (test-ps-js create-reserved-word
1141 "{ 'default' : 1 };")
1143 (test-ps-js getprop-reserved-word
1144 (getprop foo
:default
)
1147 (test-ps-js getprop-reserved-word1
1148 (getprop foo
'default
)
1151 (test-ps-js eval-when-ps-side
1152 (eval-when (:execute
)
1156 (defvar *lisp-output
* nil
)
1158 (test eval-when-lisp-side
()
1159 (setf *lisp-output
* 'original-value
)
1160 (let ((js-output (normalize-js-code
1161 (ps-doc* `(eval-when (:compile-toplevel
)
1162 (setf *lisp-output
* 'it-works
))))))
1163 (is (eql 'it-works
*lisp-output
*))
1164 (is (string= "" js-output
))))
1166 (defpsmacro my-in-package
(package-name)
1167 `(eval-when (:compile-toplevel
)
1168 (setf *lisp-output
* ,package-name
)))
1170 (test eval-when-macro-expansion
()
1171 (setf *lisp-output
* 'original-value
)
1172 (let ((js-output (normalize-js-code
1174 (my-in-package :cl-user
)
1176 (declare (ignore js-output
))
1177 (is (eql :cl-user
*lisp-output
*))))
1179 (test eval-when-macrolet-expansion
()
1180 (setf *lisp-output
* 'original-value
)
1181 (let ((js-output (normalize-js-code
1182 (ps-doc* `(macrolet ((my-in-package2 (package-name)
1183 `(eval-when (:compile-toplevel
)
1184 (setf *lisp-output
* ,package-name
))))
1185 (my-in-package2 :cl-user
)
1187 (declare (ignore js-output
))
1188 (is (eql :cl-user
*lisp-output
*))))
1190 (test-ps-js getprop-keyword
1194 (test-ps-js nary-comparison1
1195 (lambda () (< 1 2 3))
1198 return (_cmp1 = 2, 1 < _cmp1 && _cmp1 < 3);
1201 (test-ps-js chain-getprop1
1202 (chain ($
"foo") (bar x z
) frob
(baz 5))
1203 "$('foo').bar(x, z).frob.baz(5);")
1205 (test-ps-js chain-getprop2
1206 (chain ($
"foo") bar baz
)
1207 "$('foo').bar.baz;")
1209 (test-ps-js chain-getprop3
1210 (chain ($
"foo") bar
(x y
) baz
)
1211 "$('foo').bar.x(y).baz;")
1213 (test-ps-js flet-expression
1214 (1+ (flet ((foo (x) (1+ x
)))
1216 "(foo = function (x) {
1220 (test-ps-js return-case-break-elimination
1231 (test-ps-js aplusplus
1235 (test-ps-js astarstar
1239 (test-ps-js switch-return-fallthrough
1254 (test-ps-js return-last-case
1265 (test-ps-js return-macrolet
1267 (macrolet ((x () 1))
1278 (test-ps-js mv-bind1
1279 (multiple-value-bind (a b
)
1285 "var prevmv2 = null;
1287 prevmv2 = arguments['callee']['mv'];
1289 arguments['callee']['mv'] = true;
1291 var mv1 = typeof arguments['callee']['mv'] === 'object' ? arguments['callee']['mv'] : new Array(1);
1296 if (undefined === prevmv2) {
1297 delete arguments['callee']['mv'];
1299 arguments['callee']['mv'] = prevmv2;
1303 (test-ps-js mv-bind2
1304 (multiple-value-bind (a b
)
1310 "var prevmv2 = null;
1313 prevmv2 = arguments['callee']['mv'];
1315 arguments['callee']['mv'] = true;
1317 var mv1 = typeof arguments['callee']['mv'] === 'object' ? arguments['callee']['mv'] : new Array(1);
1322 if (undefined === prevmv2) {
1323 delete arguments['callee']['mv'];
1325 arguments['callee']['mv'] = prevmv2;
1330 (lambda () (values))
1343 if (undefined !== arguments['callee']['caller']['mv']) {
1344 arguments['callee']['caller']['mv'] = valrest2;
1351 var valrest2 = [y, z];
1352 if (undefined !== arguments['callee']['caller']['mv']) {
1353 arguments['callee']['caller']['mv'] = valrest2;
1357 (test-ps-js values-return
1358 (return (values x y
))
1361 if (undefined !== arguments['callee']['caller']['mv']) {
1362 arguments['callee']['caller']['mv'] = valrest2;
1366 (test-ps-js return-macrolet
1368 (symbol-macrolet ((x 2))
1375 (test-ps-js return-cond
1377 (cond ((foo? x
) (loop for y in x do
(foo y
)))
1381 var _js2 = x.length;
1395 } else if (barwhat(x)) {
1401 (test-ps-js switch-loop
1406 for (var a = null, _js_idx1 = 0; _js_idx1 < b.length; _js_idx1 += 1) {
1411 (test-ps-js switch-folds-blocks
1413 (1 (loop repeat
3 do
(alert "foo"))))
1416 for (var _js1 = 0; _js1 < 3; _js1 += 1) {
1421 (test-ps-js setf-places-before-macros
1423 (defsetf left
(el) (offset)
1424 `(setf (@ ,el style left
) ,offset
))
1425 (macrolet ((left (el)
1426 `(@ ,el offset-left
)))
1431 _js2.style.left = _js1;
1434 (test-ps-js for-return
1435 (lambda () (dolist (arg args
) (foo arg
)))
1437 for (var arg = null, _js_idx1 = 0; _js_idx1 < args.length; _js_idx1 += 1) {
1438 arg = args[_js_idx1];
1443 (test-ps-js try-catch-return
1457 (test-ps-js defun-setf-optional
1458 (defun (setf foo
) (new-value b
&optional c
)
1459 (setf (aref b
(or c
0)) new-value
))
1460 "function __setf_foo(newValue, b, c) {
1461 return b[c || 0] = newValue;
1464 (test-ps-js defun-setf-rest
1465 (progn (defun (setf foo
) (new-value b
&rest foo
)
1466 (do-something b foo new-value
))
1467 (setf (foo x
1 2 3 4) 5))
1468 "function __setf_foo(newValue, b) {
1470 for (var i1 = 0; i1 < arguments.length - 2; i1 += 1) {
1471 foo[i1] = arguments[i1 + 2];
1473 return doSomething(b, foo, newValue);
1475 __setf_foo(5, x, 1, 2, 3, 4);")
1477 (test-ps-js return-null
1481 (test-ps-js implicit-return-null
1488 (test-ps-js implicit-return-null
1495 (test-ps-js return-conditional-nested
1496 (defun blep (ss x y
)
1500 (destructuring-bind (a b
) pair
1501 (unless (or (null a
) (null b
))
1502 (let ((val (baz a b
)))
1507 "function blep(ss, x, y) {
1513 if (!(a == null || b == null)) {
1514 var val = baz(a, b);
1517 return !blee() ? true : null;
1525 ;; this test needs to be rewritten when named blocks are implemented!!!!
1526 (test-ps-js return-when-returns-broken-return
1531 return x ? 1 : null;
1535 (test-ps-js return-case-conditional
1538 (123 (when (bar) t
))
1542 return bar() ? true : null;
1547 (test-ps-js return-try-conditional
1553 return x ? 1 : null;
1560 (test-ps-js function-declare-special
1562 (declare (special *foo
*))
1568 FOO_TMPSTACK1 = FOO;
1572 FOO = FOO_TMPSTACK1;
1576 (test-ps-js declare-special-let
1578 (declare (special *foo
*))
1582 FOO_TMPSTACK1 = FOO;
1586 FOO = FOO_TMPSTACK1;
1589 (test-ps-js macro-null-toplevel
1591 (defmacro macro-null-toplevel
()
1593 (macro-null-toplevel))
1596 (test-ps-js define-symbol-macro-let
1598 (define-symbol-macro test-symbol-macro
1)
1599 (let ((test-symbol-macro 2))
1600 (1+ test-symbol-macro
))
1601 (1+ test-symbol-macro
))
1602 "var testSymbolMacro1 = 2;
1603 testSymbolMacro1 + 1;
1606 (test-ps-js define-symbol-macro-flet
1608 (define-symbol-macro test-symbol-macro1
1)
1609 (flet ((test-symbol-macro1 () 2))
1610 (foo test-symbol-macro1
)
1611 (test-symbol-macro1))
1612 (bar test-symbol-macro1
))
1613 "var testSymbolMacro1_1 = function () {
1617 testSymbolMacro1_1();
1620 (test compile-stream-nulls
1623 (with-input-from-string (s "
1624 (defmacro macro-null-toplevel ()
1626 (macro-null-toplevel)")
1627 (ps-compile-stream s
)))))
1629 (test compile-stream1
1631 "var testSymbolMacro1_1 = function () {
1635 testSymbolMacro1_1();
1638 (with-input-from-string (s "
1639 (define-symbol-macro test-symbol-macro1 1)
1640 (flet ((test-symbol-macro1 () 2))
1641 (foo test-symbol-macro1)
1642 (test-symbol-macro1))
1643 (bar test-symbol-macro1)")
1644 (ps::with-blank-compilation-environment
(ps-compile-stream s
))))))
1646 (test-ps-js equality-nary1
1647 (let ((x 10) (y 10) (z 10))
1653 x === _cmp1 && _cmp1 === z;")
1655 (test-ps-js equality1
1666 (test-ps-js getprop-quote-reserved
1667 (getprop foo
':break
)
1670 (test-ps-js defun-block-return-from
1681 (test-ps-js block-return-from
1685 (return-from scope
))
1695 (test-ps-js let-funcall
1707 (test-ps-js symbol-macrolet-funcall
1708 (symbol-macrolet ((foo bar
))
1709 (funcall foo
1 2 3))
1712 (test-ps-js times-assign
1716 (test-ps-js vector-literal
1721 (+ 1 (rem 2 (+ 3 4)))
1724 (test-ps-js non-associative
1725 (+ (/ 1 (/ 2 3)) (- 1 (- 2 3)))
1726 "1 / (2 / 3) + 1 - (2 - 3);")
1728 (test-ps-js lambda-apply
1730 (apply (lambda (y) (bar (1+ y
))) x
))
1732 return (function (y) {
1737 (test-ps-js operator-expressions-nested-let
1738 (let ((x (let ((y 1))
1741 "var x = (y = 1, y); x;")
1743 (test-ps-js operator-expressions-array-nested-let
1744 (list (let ((y 1)) y
) 2)
1747 (test-ps-js add-subtract-precedence
1751 (test-ps-js ps-inline-toplevel
1753 "'javascript:' + 'foo()';")
1755 (test-ps-js no-clause-progn-exp
1759 (test-ps-js no-clause-progn-return
1763 (test-ps-js empty-cond-clause
1764 (setf x
(cond ((foo))))
1765 "x = foo() ? null : null;")
1767 (test-ps-js empty-cond-clause1
1768 (setf x
(cond ((foo) 123)
1771 "x = foo() ? 123 : (bar() ? null : 456);")
1773 (test-ps-js let-no-body
1774 (return (let ((foo bar
))))
1778 (test-ps-js dont-hoist-lexical-dupes
1780 (list (let ((foo 12)) (* foo
2))
1781 (let ((foo 13)) (* foo
3))))
1784 return [(foo = 12, foo * 2), (foo = 13, foo * 3)];
1787 (test-ps-js defun-comment1
1789 "BARBAR is a revolutionary new foobar.
1793 * BARBAR is a revolutionary new foobar.
1800 (test-ps-js var-comment
1805 (test-ps-js case-return-break-broken-return
1808 ("bar" (if y
(return t
) nil
))
1822 (test-ps-js case-return-break1-broken-return
1825 ("bar" (if y
(return t
)))
1839 (test-ps-js setf-progn
1840 (setf foo
(progn (bar) (baz) 3))
1845 ;; (test-ps-js var-progn
1846 ;; (var x (progn (foo) (bar)))
1850 (test-ps-js implicit-return-loop
1854 (loop :repeat
100 :do
(bar))
1860 for (var _js1 = 0; _js1 < 100; _js1 += 1) {
1867 ;; closures in loops need a new binding per loop iteration (idea borrowed from Scheme2JS)
1868 (test-ps-js loop-closures
1869 (dotimes (i 10) (lambda () (+ i
1)))
1870 "for (var i = 0; i < 10; i += 1) {
1878 (test-ps-js loop-closures-let
1879 (dotimes (i 10) (let ((x (+ i
1))) (lambda () (+ i x
))))
1880 "for (var i = 0; i < 10; i += 1) {
1881 with ({ x : null, i : i }) {
1889 (test-ps-js loop-closures-flet
1890 (dotimes (i 10) (flet ((foo (x) (+ i x
))) (lambda () (foo i
))))
1891 "for (var i = 0; i < 10; i += 1) {
1892 with ({ foo : null, i : i }) {
1893 var foo = function (x) {
1902 (test-ps-js while-closures-let
1905 (lambda () (+ 1 x
))))
1907 with ({ x : null }) {
1915 (test-ps-js dotted-list-form
1918 (destructuring-bind (b . c
)
1924 var c = bar.length > 1 ? bar.slice(1) : [];
1929 (test-ps-js return-from-loop
1930 (dolist (x '(2 1 3))
1933 (chain console
(log x
)))
1934 "for (var x = null, _js_arrvar2 = [2, 1, 3], _js_idx1 = 0; _js_idx1 < _js_arrvar2.length; _js_idx1 += 1) {
1935 x = _js_arrvar2[_js_idx1];