[Moved some macros towards the top of the file due to dependencies attila.lendvai@gmail.com**20060706225147 In the long run we should cut js.lisp into several files. One dealing with the basic infrastructure like macro expansion, and the rest implementing the compiler based on this infrastructure/utilities. ] { hunk ./src/js.lisp 297 +(defvar *gen-js-name-counter* 0) + +(defun gen-js-name-string (&key (prefix "_ps_")) + "Generates a unique valid javascript identifier ()" + (concatenate 'string + prefix (princ-to-string (incf *gen-js-name-counter*)))) + +(defun gen-js-name (&key (prefix "_ps_")) + "Generate a new javascript identifier." + (intern (gen-js-name-string :prefix prefix) + (find-package :js))) + +(defmacro with-unique-js-names (symbols &body body) + "Evaluate BODY with the variables on SYMBOLS bound to new javascript identifiers. + +Each element of SYMBOLS is either a symbol or a list of (symbol +prefix)." + `(let* ,(mapcar (lambda (symbol) + (destructuring-bind (symbol &optional prefix) + (if (consp symbol) + symbol + (list symbol)) + (if prefix + `(,symbol (gen-js-name :prefix ,prefix)) + `(,symbol (gen-js-name))))) + symbols) + ,@body)) + +(defjsmacro rebind (variables expression) + ;; Creates a new js lexical environment and copies the given + ;; variable(s) there. Executes the body in the new environment. This + ;; has the same effect as a new (let () ...) form in lisp but works on + ;; the js side for js closures." + + (unless (listp variables) + (setf variables (list variables))) + `((lambda () + (let ((new-context (new *object))) + ,@(loop for variable in variables + do (setf variable (symbol-to-js variable)) + collect `(setf (slot-value new-context ,variable) (slot-value this ,variable))) + (with (new-context) + (return ,expression)))))) + hunk ./src/js.lisp 1428 -;;; helper functions - -(defvar *gen-js-name-counter* 0) - -(defun gen-js-name-string (&key (prefix "_ps_")) - "Generates a unique valid javascript identifier ()" - (concatenate 'string - prefix (princ-to-string (incf *gen-js-name-counter*)))) - -(defun gen-js-name (&key (prefix "_ps_")) - "Generate a new javascript identifier." - (intern (gen-js-name-string :prefix prefix) - (find-package :js))) - -(defmacro with-unique-js-names (symbols &body body) - "Evaluate BODY with the variables on SYMBOLS bound to new javascript identifiers. - -Each element of SYMBOLS is either a symbol or a list of (symbol -prefix)." - `(let* ,(mapcar (lambda (symbol) - (destructuring-bind (symbol &optional prefix) - (if (consp symbol) - symbol - (list symbol)) - (if prefix - `(,symbol (gen-js-name :prefix ,prefix)) - `(,symbol (gen-js-name))))) - symbols) - ,@body)) - hunk ./src/js.lisp 1430 -(defjsmacro rebind (variables expression) - ;; Creates a new js lexical environment and copies the given - ;; variable(s) there. Executes the body in the new environment. This - ;; has the same effect as a new (let () ...) form in lisp but works on - ;; the js side for js closures." - - (unless (listp variables) - (setf variables (list variables))) - `((lambda () - (let ((new-context (new *object))) - ,@(loop for variable in variables - do (setf variable (symbol-to-js variable)) - collect `(setf (slot-value new-context ,variable) (slot-value this ,variable))) - (with (new-context) - (return ,expression)))))) - }