(test-ps-js setf-side-effects
(progn
- (let* ((x 10))
+ (let ((x 10))
(defun side-effect()
(setf x 4)
(return 3))
(test-ps-js method-call-op-form
((@ (+ "" x) to-string))
- "('' + x).toString()")
+ "('' + x).toString();")
(test-ps-js method-call-op-form-args
((@ (+ "" x) to-string) 1 2 :baz 3)
- "('' + x).toString(1, 2, { baz : 3 })")
+ "('' + x).toString(1, 2, 'baz', 3);")
(test-ps-js method-call-number
((@ 10 to-string))
- "( 10 ).toString()")
+ "( 10 ).toString();")
(test-ps-js method-call-string
((@ "hi" to-string))
- "'hi'.toString()")
+ "'hi'.toString();")
(test-ps-js method-call-lit-object
((@ (create :to-string (lambda () (return "it works"))) to-string))
- "( { toString : function () { return 'it works'; } } ).toString()")
+ "( { toString : function () { return 'it works'; } } ).toString();")
(test-ps-js method-call-conditional
((if a x y) 1)
- "(a ? x : y)(1)")
+ "(a ? x : y)(1);")
(test-ps-js method-call-variable
((@ x to-string))
- "x.toString()")
+ "x.toString();")
(test-ps-js method-call-array
((@ (list 10 20) to-string))
- "[ 10, 20 ].toString()")
+ "[ 10, 20 ].toString();")
(test-ps-js method-call-fn-call
((@ (foo) to-string))
- "foo().toString()")
+ "foo().toString();")
(test-ps-js method-call-lambda-fn
((@ (lambda () (alert 10)) to-string))
- "( function () { alert(10); } ).toString()")
+ "( function () { alert(10); } ).toString();")
(test-ps-js method-call-lambda-call
((@ ((lambda (x) (return x)) 10) to-string))
- "(function (x) { return x; })(10).toString()")
+ "(function (x) { return x; })(10).toString();")
(test no-whitespace-before-dot
- (let* ((str (ps1* '((@ ((lambda (x) (return x)) 10) to-string))))
+ (let* ((str (ps* '((@ ((lambda (x) (return x)) 10) to-string))))
(dot-pos (position #\. str :test #'char=))
(char-before (elt str (1- dot-pos)))
(a-parenthesis #\)))
(is (char= char-before a-parenthesis))))
(test-ps-js simple-slot-value
- (let* ((foo (create :a 1)))
+ (let ((foo (create :a 1)))
(alert (slot-value foo 'a)))
"var foo = { a : 1 };
alert(foo.a);")
(test-ps-js buggy-slot-value
- (let* ((foo (create :a 1))
- (slot-name "a"))
+ (let ((foo (create :a 1))
+ (slot-name "a"))
(alert (slot-value foo slot-name)))
" var foo = { a : 1 };
var slotName = 'a';
(test-ps-js buggy-slot-value-two
(slot-value foo (get-slot-name))
- "foo[getSlotName()]")
+ "foo[getSlotName()];")
(test-ps-js old-case-is-now-switch
;; Switch was "case" before, but that was very non-lispish.
(1 (alert "one"))
(2 (alert "two"))
(default (alert "default clause")))
- "switch (blorg[i]) {
+ "switch (blorg[i]) {
case 1: alert('one');
case 2: alert('two');
default: alert('default clause');
- }")
+ };")
(test-ps-js lisp-like-case
(case (aref blorg i)
alert('two');
break;
default: alert('default clause');
- }")
+ };")
(test-ps-js even-lispier-case
alert('Three');
break;
default: alert('Something else');
- }")
+ };")
(test-ps-js otherwise-case
(case (aref blorg i)
alert('one');
break;
default: alert('default clause');
- }")
+ };")
(test escape-sequences-in-string
(let ((escapes `((#\\ . #\\)
("u0080" . ,(code-char 128)) ;;Character over 127. Actually valid, parenscript escapes them to be sure.
("uABCD" . ,(code-char #xabcd)))));; Really above ascii.
(loop for (js-escape . lisp-char) in escapes
- for generated = (ps1* `(let* ((x ,(format nil "hello~ahi" lisp-char)))))
+ for generated = (ps-doc* `(let ((x ,(format nil "hello~ahi" lisp-char)))))
for wanted = (format nil "var x = 'hello\\~ahi';" js-escape)
do (is (string= (normalize-js-code generated) wanted)))))
-(test-ps-js complicated-symbol-name1
- grid-rows[foo].bar
- "gridRows[foo].bar")
-
-(test-ps-js complicated-symbol-name2
- *grid-rows*[foo].bar
- "GRIDROWS[foo].bar")
-
(test-ps-js slot-value-setf
(setf (slot-value x 'y) (+ (+ a 3) 4))
"x.y = (a + 3) + 4;")
(test-ps-js slot-value-conditional1
(slot-value (if zoo foo bar) 'x)
- "(zoo ? foo : bar).x")
+ "(zoo ? foo : bar).x;")
(test-ps-js slot-value-conditional2
(slot-value (if (not zoo) foo bar) 'x)
- "(!zoo ? foo : bar).x")
+ "(!zoo ? foo : bar).x;")
(test script-star-eval1
(is (string= "x = 1; y = 2;" (normalize-js-code (ps* '(setf x 1) '(setf y 2))))))
(test script-star-eval2
(is (string= "x = 1;" (normalize-js-code (ps* '(setf x 1))))))
-(test-ps-js slot-value-null1
- (slot-value foo nil)
- "foo")
-
-(test-ps-js slot-value-null2
- (slot-value foo 'nil)
- "foo")
-
(test-ps-js unquoted-nil
nil
- "null")
+ "null;")
(test-ps-js list-with-single-nil
- (array 'nil)
- "[null]")
+ (array nil)
+ "[null];")
-(test-ps-js quoted-nil
+(test-ps-js quoted-nil-is-array
'nil
- "null")
-
-(test defsetf1
- (ps (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval)))
- (is (string= "var _js2 = 1; var _js3 = 2; var _js1 = 3; setBaz(_js2, _js3, _js1);"
- (normalize-js-code (let* ((ps:*ps-gensym-counter* 0))
- (ps (setf (baz 1 2) 3)))))))
-
-(test defsetf-short
- (ps (defsetf baz set-baz "blah"))
- (is (string= "setBaz(1, 2, 3, 'foo');" (normalize-js-code (ps (setf (baz 1 2 3) "foo"))))))
-
-(test defun-setf1
- (is (and (string= (normalize-js-code (ps:ps (defun (setf some-thing) (new-val i1 i2)
- (setf (aref *some-thing* i1 i2) new-val))))
- "function __setf_someThing(newVal, i1, i2) { SOMETHING[i1][i2] = newVal; };")
- (string= (normalize-js-code (ps:ps-doc (setf (some-thing 1 2) "foo")))
- "var _js2 = 1; var _js3 = 2; var _js1 = 'foo'; __setf_someThing(_js1, _js2, _js3);"))))
+ "[];")
+
+(test-ps-js defsetf1
+ (progn (defsetf baz (x y) (newval) `(set-baz ,x ,y ,newval))
+ (setf (baz 1 2) 3))
+ "var _js2 = 1;
+var _js3 = 2;
+var _js1 = 3;
+setBaz(_js2, _js3, _js1);")
+
+(test-ps-js setf-macroexpands1
+ (macrolet ((baz (x y) `(aref ,x ,y 1)))
+ (setf (baz foo 2) 3))
+ "foo[2][1] = 3;")
+
+(test-ps-js defsetf-short
+ (progn (defsetf baz set-baz "docstring")
+ (setf (baz 1 2 3) "foo"))
+ "setBaz(1, 2, 3, 'foo');")
+
+(test-ps-js defun-setf1
+ (progn (defun (setf some-thing) (new-val i1 i2)
+ (setf (aref *some-thing* i1 i2) new-val))
+ (setf (some-thing 1 2) "foo"))
+"function __setf_someThing(newVal, i1, i2) {
+ SOMETHING[i1][i2] = newVal;
+};
+var _js2 = 1;
+var _js3 = 2;
+var _js1 = 'foo';
+__setf_someThing(_js1, _js2, _js3);")
(test-ps-js defun-optional1
(defun test-opt (&optional x) (return (if x "yes" "no")))
x = null;
};
return x ? 'yes' : 'no';
-}")
+};")
(test-ps-js defun-optional2
(defun foo (x &optional y) (+ x y))
y = null;
};
x + y;
-}")
+};")
(test-ps-js defun-optional3
(defun blah (&optional (x 0))
x = 0;
};
return x;
-}")
+};")
(test-ps-js return-nothing
(return)
- "return null")
+ "return null;")
(test-ps-js set-timeout
(do-set-timeout (10) (alert "foo"))
- "setTimeout(function () { alert('foo'); }, 10)")
+ "setTimeout(function () { alert('foo'); }, 10);")
+
(test-ps-js operator-precedence
(* 3 (+ 4 5) 6)
- "3 * (4 + 5) * 6")
+ "3 * (4 + 5) * 6;")
(test-ps-js operators-1
(in prop obj)
- "prop in obj")
+ "prop in obj;")
(test-ps-js incf1
(incf foo bar)
- "foo += bar")
+ "foo += bar;")
(test-ps-js decf1
(decf foo bar)
- "foo -= bar")
+ "foo -= bar;")
(test-ps-js incf2
(incf x 5)
- "x += 5")
+ "x += 5;")
(test-ps-js decf2
(decf y 10)
- "y -= 10")
+ "y -= 10;")
(test-ps-js setf-conditional
(setf foo (if x 1 2))
(test-ps-js obj-literal-numbers
(create 1 "foo")
- "{ 1 : 'foo' }")
+ "{ 1 : 'foo' };")
(test-ps-js obj-literal-strings
(create "foo" 2)
- "{ 'foo' : 2 }")
+ "{ 'foo' : 2 };")
(test-ps-js slot-value-string
(slot-value foo "bar")
- "foo['bar']")
+ "foo['bar'];")
(test-ps-js slot-value-string1
(slot-value "bar" 'length)
- "'bar'.length")
+ "'bar'.length;")
(test-ps-js slot-value-progn
(slot-value (progn (some-fun "abc") "123") "length")
- "(someFun('abc'), '123')['length']")
+ "(someFun('abc'), '123')['length'];")
(test-ps-js method-call-block
((@ (progn (some-fun "abc") "123") to-string))
- "(someFun('abc'), '123').toString()")
+ "(someFun('abc'), '123').toString();")
(test-ps-js create-blank
(create)
- "{ }")
+ "{ };")
(test-ps-js blank-object-literal
{}
- "{ }")
+ "{ };")
(test-ps-js array-literal1
[]
- "[]")
+ "[];")
(test-ps-js array-literal2
([])
- "[]")
+ "[];")
(test-ps-js array-literal3
([] 1 2 3)
- "[1, 2, 3]")
+ "[1, 2, 3];")
(test-ps-js array-literal4
([] 1 (2 3))
- "[1, [2, 3]]")
+ "[1, [2, 3]];")
(test-ps-js array-literal5
([] (1 2) ("a" "b"))
- "[[1, 2], ['a', 'b']]")
+ "[[1, 2], ['a', 'b']];")
(test-ps-js defun-rest1
- (defun foo (&rest bar) (alert bar[1]))
+ (defun foo (&rest bar) (alert (aref bar 1)))
"function foo() {
var bar = [];
- for (var i2 = 0; i2 < arguments.length - 0; i2 += 1) {
- bar[i2] = arguments[i2 + 0];
+ for (var i1 = 0; i1 < arguments.length - 0; i1 += 1) {
+ bar[i1] = arguments[i1 + 0];
};
alert(bar[1]);
-}")
+};")
(test-ps-js defun-rest2
(defun foo (baz &rest bar) (return (+ baz (aref bar 1))))
"function foo(baz) {
var bar = [];
- for (var i2 = 0; i2 < arguments.length - 1; i2 += 1) {
- bar[i2] = arguments[i2 + 1];
+ for (var i1 = 0; i1 < arguments.length - 1; i1 += 1) {
+ bar[i1] = arguments[i1 + 1];
};
return baz + bar[1];
-}")
+};")
(test-ps-js defun-keyword1
(defun zoo (foo bar &key baz) (return (+ foo bar baz)))
- "function zoo(foo, bar, _js1) {
- if (_js1 === undefined) {
- _js1 = { };
+"function zoo(foo, bar) {
+ var baz;
+ var _js2 = arguments.length;
+ for (var n1 = 2; n1 < _js2; n1 += 2) {
+ switch (arguments[n1]) {
+ case 'baz':
+ {
+ baz = arguments[n1 + 1];
+ };
+ };
};
- return foo + bar + _js1.baz;
-}")
+ if (baz === undefined) {
+ baz = null;
+ };
+ return foo + bar + baz;
+};")
(test-ps-js defun-keyword2
(defun zoo (&key baz) (return (* baz baz)))
- "function zoo(_js1) {
- if (_js1 === undefined) {
- _js1 = { };
+ "function zoo() {
+ var baz;
+ var _js2 = arguments.length;
+ for (var n1 = 0; n1 < _js2; n1 += 2) {
+ switch (arguments[n1]) {
+ case 'baz':
+ {
+ baz = arguments[n1 + 1];
+ };
+ };
};
- return _js1.baz * _js1.baz;
-}")
+ if (baz === undefined) {
+ baz = null;
+ };
+ return baz * baz;
+};")
(test-ps-js defun-keyword3
(defun zoo (&key baz (bar 4)) (return (* baz bar)))
- "function zoo(_js1) {
- if (_js1 === undefined) {
- _js1 = { };
+ "function zoo() {
+ var baz;
+ var bar;
+ var _js2 = arguments.length;
+ for (var n1 = 0; n1 < _js2; n1 += 2) {
+ switch (arguments[n1]) {
+ case 'baz':
+ {
+ baz = arguments[n1 + 1];
+ };
+ break;
+ case 'bar':
+ {
+ bar = arguments[n1 + 1];
+ };
+ };
+ };
+ if (baz === undefined) {
+ baz = null;
+ };
+ if (bar === undefined) {
+ bar = 4;
+ };
+ return baz * bar;
+};")
+
+(test-ps-js defun-keyword4
+ (defun hello-world (&key ((:my-name-key my-name) 1))
+ my-name)
+ "function helloWorld() {
+ var myName;
+ var _js2 = arguments.length;
+ for (var n1 = 0; n1 < _js2; n1 += 2) {
+ switch (arguments[n1]) {
+ case 'my-name-key':
+ {
+ myName = arguments[n1 + 1];
+ };
+ };
};
- if (_js1.bar === undefined) {
- _js1.bar = 4;
+ if (myName === undefined) {
+ myName = 1;
};
- return _js1.baz * _js1.bar;
-}")
+ myName;
+};")
(test-ps-js keyword-funcall1
(func :baz 1)
- "func({ baz : 1 })")
+ "func('baz', 1);")
(test-ps-js keyword-funcall2
(func :baz 1 :bar foo)
- "func({ baz : 1, bar : foo })")
+ "func('baz', 1, 'bar', foo);")
(test-ps-js keyword-funcall3
(fun a b :baz c)
- "fun(a, b, { baz : c })")
+ "fun(a, b, 'baz', c);")
(test-ps-js cond1
(cond ((= x 1) 1))
"if (x == 1) {
1;
-}")
+};")
(test-ps-js cond2
- (cond ((= x 1) 2) ((= y (* x 4)) (foo "blah") (* x y)))
+ (cond ((= x 1) 2)
+ ((= y (* x 4)) (foo "blah") (* x y)))
"if (x == 1) {
2;
} else if (y == x * 4) {
foo('blah');
x * y;
-}")
+};")
(test-ps-js if-exp-without-else-returns-null
(return (if x 1))
- "return x ? 1 : null")
+ "return x ? 1 : null;")
(test-ps-js progn-expression-single-statement
(return (progn (* x y)))
- "return x * y")
+ "return x * y;")
(test-ps-js cond-expression1
(defun foo () (return (cond ((< 1 2) (bar "foo") (* 4 5)))))
"function foo() {
return 1 < 2 ? (bar('foo'), 4 * 5) : null;
-}")
+};")
(test-ps-js cond-expression2
(defun foo () (return (cond ((< 2 1) "foo") ((= 7 7) "bar"))))
"function foo() {
return 2 < 1 ? 'foo' : (7 == 7 ? 'bar' : null);
-}")
+};")
(test-ps-js cond-expression-final-t-clause
(defun foo () (return (cond ((< 1 2) (bar "foo") (* 4 5)) ((= a b) (+ c d)) ((< 1 2 3 4 5) x) (t "foo"))))
"function foo() {
return 1 < 2 ? (bar('foo'), 4 * 5) : (a == b ? c + d : (1 < 2 < 3 < 4 < 5 ? x : 'foo'));
-}")
+};")
(test-ps-js cond-expression-middle-t-clause ;; should this signal a warning?
(defun foo () (return (cond ((< 2 1) 5) (t "foo") ((< 1 2) "bar"))))
"function foo() {
return 2 < 1 ? 5 : 'foo';
-}")
+};")
(test-ps-js funcall-if-expression
- (document.write
+ ((@ document write)
(if (= *linkornot* 1)
(ps-html ((:a :href "#"
:onclick (ps-inline (transport)))
img))
img))
- "document.write(LINKORNOT == 1 ? '<A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport()') + '\">' + img + '</A>' : img)")
+ "document.write(LINKORNOT == 1 ? '<A HREF=\"#\" ONCLICK=\"' + ('javascript:' + 'transport' + '(' + ')') + '\">' + img + '</A>' : img);")
(test-ps-js negate-number-literal ;; ok, this was broken and fixed before, but no one bothered to add the test!
(- 1)
- "-1")
+ "-1;")
(test macro-environment1
(is (string= (normalize-js-code (let* ((macroname (gensym)))
(test-ps-js keyword-consistent
:x
- "'x'")
+ "'x';")
(test-ps-js simple-symbol-macrolet
(symbol-macrolet ((x 1)) x)
(defun f () (return (progn (foo) (if x 1 2))))
"function f() {
return (foo(), x ? 1 : 2);
-}")
+};")
(test-ps-js let-decl-in-expression
- (defun f (x) (return (if x 1 (let* ((foo x)) foo))))
+ (defun f (x)
+ (return (if x
+ 1
+ (let* ((foo x))
+ foo))))
"function f(x) {
var foo;
return x ? 1 : (foo = x, foo);
-}")
+};")
(test-ps-js special-var1
- (progn (defvar *foo*) (let* ((*foo* 2)) (* *foo* 2)))
+ (progn (defvar *foo*)
+ (let* ((*foo* 2))
+ (* *foo* 2)))
"var FOO;
-var tempstackvar1;
+var FOO_TMPSTACK1;
try {
- tempstackvar1 = FOO;
+ FOO_TMPSTACK1 = FOO;
FOO = 2;
FOO * 2;
} finally {
- FOO = tempstackvar1;
- delete tempstackvar1;
+ FOO = FOO_TMPSTACK1;
};")
(test-ps-js special-var2
- (progn (defvar *foo*) (let* ((*baz* 3) (*foo* 2)) (* *foo* 2 *baz*)))
+ (progn (defvar *foo*)
+ (let* ((*baz* 3)
+ (*foo* 2))
+ (* *foo* 2 *baz*)))
"var FOO;
var BAZ = 3;
-var tempstackvar1;
+var FOO_TMPSTACK1;
try {
- tempstackvar1 = FOO;
+ FOO_TMPSTACK1 = FOO;
FOO = 2;
FOO * 2 * BAZ;
} finally {
- FOO = tempstackvar1;
- delete tempstackvar1;
-};
-")
+ FOO = FOO_TMPSTACK1;
+};")
(test-ps-js literal1
(setf x undefined)
(test-ps-js literal2
(aref this x)
- "this[x]")
+ "this[x];")
(test-ps-js setf-dec1
(setf x (- 1 x 2))
(test-ps-js special-char-equals
blah=
- "blahequals")
+ "blahequals;")
(test-ps-js setf-operator-priority
(return (or (slot-value cache id)
- (setf (slot-value cache id) (document.get-element-by-id id))))
- "return cache[id] || (cache[id] = document.getElementById(id))")
+ (setf (slot-value cache id) ((@ document get-element-by-id) id))))
+ "return cache[id] || (cache[id] = document.getElementById(id));")
(test-ps-js aref-operator-priority
(aref (if (and x (> (length x) 0))
(aref x 0)
y)
z)
- "(x && x.length > 0 ? x[0] : y)[z]")
+ "(x && x.length > 0 ? x[0] : y)[z];")
(test-ps-js aref-operator-priority1
(aref (or (slot-value x 'y)
(slot-value a 'b))
z)
- "(x.y || a.b)[z]")
+ "(x.y || a.b)[z];")
(test-ps-js aref-operator-priority2
(aref (if a b c) 0)
- "(a ? b : c)[0]")
+ "(a ? b : c)[0];")
(test-ps-js negative-operator-priority
(- (if x y z))
- "-(x ? y : z)")
+ "-(x ? y : z);")
(test-ps-js op-p1
(new (or a b))
- "new (a || b)")
+ "new (a || b);")
(test-ps-js op-p2
(delete (if a (or b c) d))
- "delete (a ? b || c : d)")
+ "delete (a ? b || c : d);")
(test-ps-js op-p3
(not (if (or x (not y)) z))
- "!(x || !y ? z : null)")
+ "!(x || !y ? z : null);")
(test-ps-js op-p4
(- (- (* 1 2) 3))
- "-(1 * 2 - 3)")
+ "-(1 * 2 - 3);")
(test-ps-js op-p5
(instanceof (or a b) (if x y z))
- "((a || b) instanceof (x ? y : z))")
-
-(test-ps-js op-p6
- (doeach (x (or a b)))
- "for (var x in (a || b)) { };")
+ "((a || b) instanceof (x ? y : z));")
(test-ps-js op-p7
(or x (if (= x 0) "zero" "empty"))
- "x || (x == 0 ? 'zero' : 'empty')")
+ "x || (x == 0 ? 'zero' : 'empty');")
(test-ps-js named-op-expression
(throw (if a b c))
- "throw a ? b : c")
+ "throw a ? b : c;")
(test-ps-js named-op-expression1
(typeof (or x y))
- "typeof (x || y)")
+ "typeof (x || y);")
(test-ps-js aref-array-expression
(aref (or a b c) 0)
- "(a || b || c)[0]")
+ "(a || b || c)[0];")
(test-ps-js slot-value-operator
(slot-value (or a b c) 'd)
- "(a || b || c).d")
+ "(a || b || c).d;")
(test-ps-js slot-value-parens
(slot-value (slot-value foo 'bar) 'baz)
- "foo.bar.baz")
+ "foo.bar.baz;")
(test-ps-js funcall-funcall
((foo))
- "foo()()")
+ "foo()();")
(test-ps-js expression-funcall
((or (@ window eval) eval) foo nil)
- "(window.eval || eval)(foo, null)")
+ "(window.eval || eval)(foo, null);")
(test-ps-js expression-funcall1
(((or (@ window eval) eval) foo nil))
- "(window.eval || eval)(foo, null)()")
+ "(window.eval || eval)(foo, null)();")
(test-ps-js expression-funcall2
(((or (@ window eval) eval)) foo nil)
- "(window.eval || eval)()(foo, null)")
+ "(window.eval || eval)()(foo, null);")
(test-ps-js slot-value-object-literal
(slot-value (create :a 1) 'a)
- "({ a : 1 }).a")
+ "({ a : 1 }).a;")
(test-ps-js slot-value-lambda
(slot-value (lambda ()) 'prototype)
- "(function () { }).prototype")
+ "(function () { }).prototype;")
(test-ps-js who-html1
(who-ps-html (:span :class "ticker-symbol"
(:a :href "http://foo.com"
symbol)
(:span :class "ticker-symbol-popup")))
- "'<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"' + symbol + '\"><A HREF=\"http://foo.com\">' + symbol + '</A><SPAN CLASS=\"ticker-symbol-popup\"/></SPAN>'")
+ "'<SPAN CLASS=\"ticker-symbol\" TICKER-SYMBOL=\"' + symbol + '\"><A HREF=\"http://foo.com\">' + symbol + '</A><SPAN CLASS=\"ticker-symbol-popup\"></SPAN></SPAN>';")
(test-ps-js flet1
- ((lambda () (flet ((foo (x) (return (1+ x)))) (return (foo 1)))))
+ ((lambda () (flet ((foo (x)
+ (return (1+ x))))
+ (return (foo 1)))))
"(function () {
- var foo = function (x) {
+ var foo1 = function (x) {
return x + 1;
};
- return foo(1);
-})()")
+ return foo1(1);
+})();")
+
+(test-ps-js flet2
+ (flet ((foo (x) (return (1+ x)))
+ (bar (y) (return (+ 2 y))))
+ (bar (foo 1)))
+"var foo1 = function (x) {
+ return x + 1;
+};
+var bar2 = function (y) {
+ return 2 + y;
+};
+bar2(foo1(1));")
+
+(test-ps-js flet3
+ (flet ((foo (x) (return (1+ x)))
+ (bar (y) (return (+ 2 (foo y)))))
+ (bar (foo 1)))
+ "var foo1 = function (x) {
+ return x + 1;
+};
+var bar2 = function (y) {
+ return 2 + foo(y);
+};
+bar2(foo1(1));")
(test-ps-js labels1
((lambda () (labels ((foo (x)
(+ x (foo (1- x)))))))
(return (foo 3)))))
"(function () {
- var foo = function foo(x) {
- return 0 === x ? 0 : x + foo(x - 1);
+ var foo1 = function (x) {
+ return 0 === x ? 0 : x + foo1(x - 1);
};
- return foo(3);
-})()")
+ return foo1(3);
+})();")
+
+(test-ps-js labels2
+ (labels ((foo (x) (return (1+ (bar x))))
+ (bar (y) (return (+ 2 (foo y)))))
+ (bar (foo 1)))
+ "var foo1 = function (x) {
+ return bar2(x) + 1;
+};
+var bar2 = function (y) {
+ return 2 + foo1(y);
+};
+bar2(foo1(1));")
+
+(test-ps-js labels3
+ (labels ((foo (x) (return (1+ x)))
+ (bar (y) (return (+ 2 (foo y)))))
+ (bar (foo 1)))
+ "var foo1 = function (x) {
+ return x + 1;
+};
+var bar2 = function (y) {
+ return 2 + foo1(y);
+};
+bar2(foo1(1));")
+
+(test-ps-js for-loop-var-init-exp
+ ((lambda (x)
+ (return (do* ((y (if x 0 1) (1+ y))
+ (z 0 (1+ z)))
+ ((= y 3) z))))
+ true)
+ "(function (x) {
+ return (function () {
+ for (var y = x ? 0 : 1, z = 0; y != 3; y += 1, z += 1) {
+ };
+ return z;
+ })();
+})(true);")
+
+(test-ps-js math-pi
+ pi
+ "Math.PI;")
+
+(test-ps-js literal-array
+ '(1 2 3)
+ "[1, 2, 3];")
+
+(test-ps-js literal-array-1
+ '(1 foo 3)
+ "[1, 'foo', 3];")
+
+(test ps-lisp-expands-in-lexical-environment
+ (is (string= "5;" (let ((x 5)) (ps (lisp x))))))
+
+(test ps*-lisp-expands-in-null-lexical-environment
+ (signals error (let ((x 5)) (declare (ignore x)) (ps* '(lisp x)))))
+
+(test ps*-lisp-expands-in-dynamic-environment
+ (is (string= "1 + 2;" (let ((*print-level* 2)) (ps* '(+ 1 (lisp *print-level*)))))))
+
+(test ps-lisp-dynamic-environment
+ (is (string= "1 + 2;" (let ((*print-level* 2)) (ps (+ 1 (lisp *print-level*)))))))
+
+(test-ps-js ps-js-target-version-keyword-test1
+ (defun foo (x y &key bar baz))
+ "function foo(x, y) {
+ var x1 = Array.prototype.indexOf.call(arguments, 'bar', 2);
+ var bar = -1 == x1 ? null : arguments[x1 + 1];
+ var x2 = Array.prototype.indexOf.call(arguments, 'baz', 2);
+ var baz = -1 == x2 ? null : arguments[x2 + 1];
+};"
+ :js-target-version 1.6)
+
+(test-ps-js nested-if-expressions1
+ (return (if (if x y z) a b))
+ "return (x ? y : z) ? a : b;")
+
+(test-ps-js nested-if-expressions2
+ (return (if x y (if z a b)))
+ "return x ? y : (z ? a : b);")
+
+(test-ps-js let1
+ (let (x)
+ (+ x x))
+ "var x = null;
+x + x;")
+
+(test-ps-js let2
+ (let ((x 1))
+ (+ x x))
+ "var x = 1;
+x + x;")
+
+(test-ps-js let-x-x
+ (let ((x (1+ x)))
+ (+ x x))
+ "var x1 = x + 1;
+x1 + x1;")
+
+(test-ps-js let3
+ (let ((x 1)
+ (y 2))
+ (+ x x))
+ "var x = 1;
+var y = 2;
+x + x;")
+
+(test-ps-js let4
+ (let ((x 1)
+ (y (1+ x)))
+ (+ x y))
+ "var x1 = 1;
+var y = x + 1;
+x1 + y;")
+
+(test-ps-js let5
+ (let ((x 1))
+ (+ x 1)
+ (let ((x (+ x 5)))
+ (+ x 1))
+ (+ x 1))
+ "var x = 1;
+x + 1;
+var x1 = x + 5;
+x1 + 1;
+x + 1;")
+
+(test-ps-js let6
+ (let ((x 2))
+ (let ((x 1)
+ (y (1+ x)))
+ (+ x y)))
+ "var x = 2;
+var x1 = 1;
+var y = x + 1;
+x1 + y;")
+
+(test-ps-js let-exp1
+ (lambda ()
+ (return (let (x) (+ x x))))
+ "function () {
+ var x;
+ return (x = null, x + x);
+};")
+
+(test-ps-js let*1
+ (let* ((x 1)) (+ x x))
+"var x = 1;
+x + x;")
+
+(test-ps-js let*2
+ (let* ((x 1)
+ (y (+ x 2)))
+ (+ x y))
+ "var x = 1;
+var y = x + 2;
+x + y;")
+
+(test-ps-js let*3
+ (let ((x 3))
+ (let* ((x 1)
+ (y (+ x 2)))
+ (+ x y)))
+ "var x = 3;
+var x1 = 1;
+var y = x1 + 2;
+x1 + y;")
+
+(test-ps-js let*4
+ (let ((x 3))
+ (let* ((y (+ x 2))
+ (x 1))
+ (+ x y)))
+ "var x = 3;
+var y = x + 2;
+var x1 = 1;
+x1 + y;")
+
+(test-ps-js symbol-macrolet-var
+ (symbol-macrolet ((x y))
+ (var x))
+ "var y;")
+
+(test-ps-js setf-conditional1
+ (setf x (unless (null a) (1+ a)))
+ "x = a != null ? a + 1 : null;")
+
+(test-ps-js setf-let1
+ (setf x (let ((a 1)) a))
+ "x = (a = 1, a);")
+
+(test-ps-js setf-let2
+ (setf x (let ((a (foo)))
+ (unless (null a)
+ (1+ a))))
+ "x = (a = foo(), a != null ? a + 1 : null);")
+
+(test-ps-js symbol-macro-env1
+ (symbol-macrolet ((bar 1))
+ (macrolet ((bar (x y) `(+ ,x ,y)))
+ (bar bar bar)))
+ "1 + 1;")
+
+(test-ps-js symbol-macrolet-fun1
+ (symbol-macrolet ((baz +))
+ (baz 1 2))
+ "baz(1, 2);")
+
+(test-ps-js lisp2-namespaces1
+ (let ((list nil))
+ (setf list (list 1 2 3)))
+ "var list = null;
+list = [1, 2, 3];")
+
+(test-ps-js let-shadows-symbol-macrolet
+ (symbol-macrolet ((x y))
+ (let ((x 1))
+ (+ x x))
+ (+ x x))
+ "var x1 = 1;
+x1 + x1;
+y + y;")
+
+(test-ps-js let-rename-optimization1
+ (let ((x 1))
+ (+ x x))
+ "var x = 1;
+x + x;")
+
+(test-ps-js let-rename-optimization2
+ (lambda (x)
+ (let ((x (+ 1 x)))
+ (return x)))
+ "function (x) {
+ var x1 = 1 + x;
+ return x1;
+};")
+
+(test-ps-js symbol-macro-array
+ (symbol-macrolet ((x 1))
+ (list x))
+ "[1];")
+
+(test-ps-js symbol-macro-obj
+ (symbol-macrolet ((x y))
+ (create x 1))
+ "{ y : 1 };")
+
+(test-ps-js symbol-macro-conditional1
+ (symbol-macrolet ((x y))
+ (if x x x))
+ "if (y) {
+ y;
+} else {
+ y;
+};")
+
+(test-ps-js symbol-macro-conditional2
+ (symbol-macrolet ((x y))
+ (return (if x x x)))
+ "return y ? y : y;")
+
+(test-ps-js flet-apply
+ (flet ((foo () 'bar))
+ (apply (function foo) nil))
+ "var foo1 = function () {
+ 'bar';
+};
+foo1.apply(this, null);")
+
+(test-ps-js let-apply
+ (let ((foo (lambda () (return 1))))
+ (let ((foo (lambda () (return 2))))
+ (apply foo nil)))
+ "var foo = function () {
+ return 1;
+};
+var foo1 = function () {
+ return 2;
+};
+foo1.apply(this, null);")
+
+(test-ps-js flet-let
+ (flet ((x (x) (return (1+ x))))
+ (let ((x 2))
+ (x x)))
+ "var x1 = function (x) {
+ return x + 1;
+};
+var x = 2;
+x1(x);")
+
+(test-ps-js let-flet
+ (let ((x 2))
+ (flet ((x (x) (return (1+ x))))
+ (x x)))
+ "var x = 2;
+var x1 = function (x) {
+ return x + 1;
+};
+x1(x);")
+
+(test-ps-js macrolet-let-inteference
+ (macrolet ((a (n) `(+ ,n 5)))
+ (let ((a (a 1)))
+ (let ((b (a (- a 4))))
+ (+ a b))))
+ "var a = 1 + 5;
+var b = (a - 4) + 5;
+a + b;")
+
+(test-ps-js let-subtract-add
+ (let ((x 1))
+ (let ((x 2))
+ (- x x)
+ (- x)
+ (decf x)
+ (incf x)))
+ "var x = 1;
+var x1 = 2;
+x1 - x1;
+-x1;
+--x1;
+++x1;")
+
+(test-ps-js create-reserved-word
+ (create :default 1)
+ "{ 'default' : 1 };")
+
+(test-ps-js slot-value-reserved-word
+ (slot-value foo :default)
+ "foo['default'];")
+
+(test-ps-js eval-when-ps-side
+ (eval-when (:execute)
+ 5)
+ "5;")
+
+(defvar *lisp-output* nil)
+
+(test eval-when-lisp-side ()
+ (setf *lisp-output* 'original-value)
+ (let ((js-output (normalize-js-code
+ (ps-doc* `(eval-when (:compile-toplevel)
+ (setf *lisp-output* 'it-works))))))
+ (is (eql 'it-works *lisp-output*))
+ (is (string= "" js-output))))
+
+(defpsmacro my-in-package (package-name)
+ `(eval-when (:compile-toplevel)
+ (setf *lisp-output* ,package-name)))
+
+(test eval-when-macro-expansion ()
+ (setf *lisp-output* 'original-value)
+ (let ((js-output (normalize-js-code
+ (ps-doc* `(progn
+ (my-in-package :cl-user)
+ 3)))))
+ (declare (ignore js-output))
+ (is (eql :cl-user *lisp-output*))))
+
+(test eval-when-macrolet-expansion ()
+ (setf *lisp-output* 'original-value)
+ (let ((js-output (normalize-js-code
+ (ps-doc* `(macrolet ((my-in-package2 (package-name)
+ `(eval-when (:compile-toplevel)
+ (setf *lisp-output* ,package-name))))
+ (my-in-package2 :cl-user)
+ 3)))))
+ (declare (ignore js-output))
+ (is (eql :cl-user *lisp-output*))))