From fc772f726fef4f366bf0a2529db348a554a092fa Mon Sep 17 00:00:00 2001 From: Vladimir Sedach Date: Wed, 12 Aug 2009 15:01:51 -0600 Subject: [PATCH] Fixed a bug where 'create' was special-casing keywords in inappropriate ways. (slot-value (create :foo-bar 1) :foo-bar) was being translated as ({ fooBar : 1 })['foo-bar'] --- docs/reference.lisp | 16 ++++++++-------- src/compiler.lisp | 3 ++- src/printer.lisp | 8 ++------ src/special-forms.lisp | 36 ++++++++++++++++++++---------------- t/ps-tests.lisp | 8 ++++---- t/reference-tests.lisp | 16 ++++++++-------- 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/docs/reference.lisp b/docs/reference.lisp index 9af69c9..173e70b 100644 --- a/docs/reference.lisp +++ b/docs/reference.lisp @@ -191,15 +191,15 @@ UNDEFINED UNLESS VAR VOID VOLATILE WHEN WHILE WITH WITH-SLOTS ;;; to the `CREATE' form is a list of property names and values. To be ;;; more "lispy", the property names can be keywords. -(create :foo "bar" :blorg 1) -=> { foo : 'bar', blorg : 1 }; +(create foo "bar" :blorg 1) +=> { foo : 'bar', 'blorg' : 1 }; -(create :foo "hihi" - :blorg (array 1 2 3) - :another-object (create :schtrunz 1)) +(create foo "hihi" + blorg (array 1 2 3) + another-object (create :schtrunz 1)) => { foo : 'hihi', blorg : [ 1, 2, 3 ], - anotherObject : { schtrunz : 1 } }; + anotherObject : { 'schtrunz' : 1 } }; ;;; Object properties can be accessed using the `SLOT-VALUE' form, ;;; which takes an object and a slot-name. @@ -856,7 +856,7 @@ a-variable => aVariable; ;;; `FOR-IN' is translated to the JS `for...in' statement. -(let ((obj (create :a 1 :b 2 :c 3))) +(let ((obj (create a 1 b 2 c 3))) (for-in (i obj) ((@ document write) (+ i ": " (aref obj i) "
")))) => var obj = { a : 1, b : 2, c : 3 }; @@ -939,7 +939,7 @@ a-variable => aVariable; ;;; adds the object `object' as an intermediary scope objects when ;;; executing the body. -(with (create :foo "foo" :i "i") +(with (create foo "foo" i "i") (alert (+ "i is now intermediary scoped: " i))) => with ({ foo : 'foo', i : 'i' }) { alert('i is now intermediary scoped: ' + i); diff --git a/src/compiler.lisp b/src/compiler.lisp index 9933be1..4daf9e9 100644 --- a/src/compiler.lisp +++ b/src/compiler.lisp @@ -16,7 +16,8 @@ (pushnew (symbol-name-to-js-string name) *ps-reserved-symbol-names* :test #'equalp)) (defun ps-reserved-symbol-p (symbol) - (find (symbol-name-to-js-string symbol) *ps-reserved-symbol-names* :test #'equalp)) + (when (symbolp symbol) + (find (symbol-name-to-js-string symbol) *ps-reserved-symbol-names* :test #'equalp))) ;;; special forms diff --git a/src/printer.lisp b/src/printer.lisp index edaa39d..89c6d22 100644 --- a/src/printer.lisp +++ b/src/printer.lisp @@ -172,12 +172,8 @@ arguments, defines a printer for that form using the given body." (defprinter js:object (&rest slot-defs) (psw "{ ") (loop for ((slot-name . slot-value) . remaining) on slot-defs do - (if (and (listp slot-name) (eq 'quote (car slot-name)) (symbolp (second slot-name))) - (psw (symbol-to-js-string (second slot-name))) - (ps-print slot-name)) - (psw " : ") - (ps-print slot-value) - (when remaining (psw ", "))) + (ps-print slot-name) (psw " : ") (ps-print slot-value) + (when remaining (psw ", "))) (psw " }")) (defprinter js:slot-value (obj slot) diff --git a/src/special-forms.lisp b/src/special-forms.lisp index 8afdaaf..7b8df5d 100644 --- a/src/special-forms.lisp +++ b/src/special-forms.lisp @@ -475,22 +475,26 @@ lambda-list::= (define-ps-symbol-macro {} (create)) (define-ps-special-form create (&rest arrows) - `(js:object ,@(loop for (key-expr val-expr) on arrows by #'cddr collecting - (let ((key (compile-parenscript-form (ps-macroexpand key-expr) :expecting :expression))) - (when (keywordp key) - (setf key `(js:variable ,key))) - (when (and (listp key) - (ps-reserved-symbol-p (second key))) - (setf key (symbol-name-to-js-string (second key)))) - (assert (or (stringp key) - (numberp key) - (and (listp key) - (or (eq 'js:variable (car key)) - (eq 'quote (car key))))) - () - "Slot key ~s is not one of js-variable, keyword, string or number." key) - (cons key (compile-parenscript-form (ps-macroexpand val-expr) :expecting :expression)))))) - + `(js:object + ,@(loop for (key-expr val-expr) on arrows by #'cddr collecting + (let ((compiled-key (compile-parenscript-form (ps-macroexpand key-expr) + :expecting :expression))) + (assert (or (stringp compiled-key) + (numberp compiled-key) + (keywordp compiled-key) + (and (listp compiled-key) + (eq 'js:variable (car compiled-key)))) + () + "Slot key ~s is not one of js-variable, keyword, string or number." + compiled-key) + (let ((key (aif (ps-reserved-symbol-p (if (listp compiled-key) + (second compiled-key) + compiled-key)) + it + compiled-key))) + (cons key (compile-parenscript-form (ps-macroexpand val-expr) + :expecting :expression))))))) + (define-ps-special-form instanceof (value type) `(js:instanceof ,(compile-parenscript-form value :expecting :expression) ,(compile-parenscript-form type :expecting :expression))) diff --git a/t/ps-tests.lisp b/t/ps-tests.lisp index 264db66..ee4ea47 100644 --- a/t/ps-tests.lisp +++ b/t/ps-tests.lisp @@ -55,7 +55,7 @@ x = 2 + sideEffect() + x + 5;") "'hi'.toString();") (test-ps-js method-call-lit-object - ((@ (create :to-string (lambda () (return "it works"))) to-string)) + ((@ (create to-string (lambda () (return "it works"))) to-string)) "( { toString : function () { return 'it works'; } } ).toString();") (test-ps-js method-call-conditional @@ -90,13 +90,13 @@ x = 2 + sideEffect() + x + 5;") (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)) + (let ((foo (create a 1)) (slot-name "a")) (alert (slot-value foo slot-name))) " var foo = { a : 1 }; @@ -749,7 +749,7 @@ try { "(window.eval || eval)()(foo, null);") (test-ps-js slot-value-object-literal - (slot-value (create :a 1) 'a) + (slot-value (create a 1) 'a) "({ a : 1 }).a;") (test-ps-js slot-value-lambda diff --git a/t/reference-tests.lisp b/t/reference-tests.lisp index 6dc23b1..8712a4f 100644 --- a/t/reference-tests.lisp +++ b/t/reference-tests.lisp @@ -87,16 +87,16 @@ "new Array(new Array(2, 3), new Array('foobar', 'bratzel bub'));") (test-ps-js object-literals-1 - (create :foo "bar" :blorg 1) - "{ foo : 'bar', blorg : 1 };") + (create foo "bar" :blorg 1) + "{ foo : 'bar', 'blorg' : 1 };") (test-ps-js object-literals-2 - (create :foo "hihi" - :blorg (array 1 2 3) - :another-object (create :schtrunz 1)) + (create foo "hihi" + blorg (array 1 2 3) + another-object (create :schtrunz 1)) "{ foo : 'hihi', blorg : [ 1, 2, 3 ], - anotherObject : { schtrunz : 1 } };") + anotherObject : { 'schtrunz' : 1 } };") (test-ps-js object-literals-3 (slot-value an-object 'foo) @@ -456,7 +456,7 @@ alert('Sum of ' + l + ' is: ' + (function () { })());") (test-ps-js iteration-constructs-8 - (let ((obj (create :a 1 :b 2 :c 3))) + (let ((obj (create a 1 b 2 c 3))) (for-in (i obj) ((@ document write) (+ i ": " (aref obj i) "
")))) "var obj = { a : 1, b : 2, c : 3 }; @@ -500,7 +500,7 @@ for (var i in obj) { };") (test-ps-js the-with-statement-1 - (with (create :foo "foo" :i "i") + (with (create foo "foo" i "i") (alert (+ "i is now intermediary scoped: " i))) "with ({ foo : 'foo', i : 'i' }) { alert('i is now intermediary scoped: ' + i); -- 2.20.1