Commit b51f35a7 authored by Boris Smilga's avatar Boris Smilga
Browse files

Additions to 116f9ca9, to not replace Φ() with Φ.call(this) unless Φ refers to...

Additions to 116f9ca9, to not replace Φ() with Φ.call(this) unless Φ refers to this. Also, fixed / added tests.
parent 7df36942
......@@ -214,6 +214,18 @@ CL environment)."
(values (ps-macroexpand form1) t)
form1)))
;;; lambda wrapping
(defvar this-in-lambda-wrapped-form? nil)
(defun lambda-wrap (form)
(let ((this-in-lambda-wrapped-form? :query)
(*ps-gensym-counter* *ps-gensym-counter*))
(ps-compile form)
(if (eq this-in-lambda-wrapped-form? :yes)
`(chain (lambda () ,form) (call this))
`((lambda () ,form)))))
;;;; compiler interface
(defparameter *compilation-level* :toplevel
......@@ -242,12 +254,12 @@ form, FORM, returns the new value for *compilation-level*."
(let* ((op (car form))
(statement-impl (gethash op *special-statement-operators*))
(expression-impl (gethash op *special-expression-operators*)))
(cond ((not compile-expression?)
(cond ((or (not compile-expression?) this-in-lambda-wrapped-form?)
(apply (or statement-impl expression-impl) (cdr form)))
(expression-impl
(apply expression-impl (cdr form)))
((member op *lambda-wrappable-statements*)
(compile-expression `(chain (lambda () ,form) (call this))))
(compile-expression (lambda-wrap form)))
(t (error 'compile-expression-error :form form)))))
(defun ps-compile (form)
......@@ -255,14 +267,17 @@ form, FORM, returns the new value for *compilation-level*."
`(multiple-value-bind (expansion expanded?) (ps-macroexpand ,form)
(if expanded?
(ps-compile expansion)
,@body))))
(progn ,@body)))))
(typecase form
((or null number string character)
form)
(vector
(ps-compile `(quote ,(coerce form 'list))))
(symbol
(try-expanding form form))
(try-expanding form
(when (and (eq form 'this) (eq this-in-lambda-wrapped-form? :query))
(setq this-in-lambda-wrapped-form? :yes))
form))
(cons
(try-expanding form
(let ((*compilation-level*
......
......@@ -208,7 +208,7 @@ of (declare ...) forms, and the remaining body."
`(ps-js:lambda ,args1 ,body-block)))
(defmacro local-functions (special-op &body bindings)
`(if in-function-scope?
`(if (or in-function-scope? this-in-lambda-wrapped-form?)
(let* ((fn-renames (collect-function-names fn-defs))
,@bindings)
`(,(if compile-expression? 'ps-js:|,| 'ps-js:block)
......
......@@ -403,5 +403,5 @@
,@(awhen (accum-var state) (list it))))
(full `(block ,(name state) ,@(prologue-wrap (prologue state) main))))
(if (accum-var state)
`(chain (lambda () ,full) (call this))
(lambda-wrap full)
full))))
......@@ -160,7 +160,7 @@
body))
(define-statement-operator block (name &rest body)
(if in-function-scope?
(if (or in-function-scope? this-in-lambda-wrapped-form?)
(let* ((name (or name 'nilBlock))
(in-loop-scope? (if name in-loop-scope? nil))
(*dynamic-return-tags* (cons (cons name nil) *dynamic-return-tags*))
......@@ -418,7 +418,7 @@ Parenscript now implements implicit return, update your code! Things like (lambd
(ps-gensym (symbol-name x))))
(defun with-lambda-scope (body)
(prog1 `(chain (lambda () ,body) (call this))
(prog1 (lambda-wrap body)
(setf *vars-needing-to-be-declared* ())))
(define-expression-operator let (bindings &body body)
......@@ -482,7 +482,7 @@ Parenscript now implements implicit return, update your code! Things like (lambd
(setf ,@(mapcan (lambda (x) `(,(var x) ,(rename x)))
dynamic-bindings)))))
renamed-body))))
(ps-compile (cond ((or in-function-scope?
(ps-compile (cond ((or in-function-scope? this-in-lambda-wrapped-form?
(null bindings))
let-body)
;; HACK
......
......@@ -2029,6 +2029,17 @@ return x + x;
(1+ (if x x x)))
"(y ? y : y) + 1;")
(test-ps-js preserve-this
(defun foo ()
(let ((y (block nil (bar this))))
(baz y)))
"function foo() {
var y = (function () {
return bar(this);
}).call(this);
return baz(y);
};")
(test-ps-js flet-apply
(flet ((foo () 'bar))
(apply (function foo) nil))
......@@ -2037,7 +2048,7 @@ var foo = function () {
return 'bar';
};
return foo.apply(this, null);
})();")
}).call(this);")
(test-ps-js let-apply
(let ((foo (lambda () 1)))
......@@ -2051,7 +2062,7 @@ var foo1 = function () {
return 2;
};
return foo1.apply(this, null);
})();")
}).call(this);")
(test-ps-js flet-let
(flet ((x (x) (1+ x)))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment