(flet ((special-append (form elt)
(let ((len (length form)))
(if (and (> len 0)
- (member (char form (1- len))
- '(#\; #\, #\})))
+ (string= (char form (1- len)) elt))
form
(concatenate 'string form elt)))))
(cond ((stringp form)
(defun import-macros-from-lisp (&rest names)
"Import the named lisp macros into the js macro expansion"
(dolist (name names)
- (undefine-js-compiler-macro name)
- (setf (gethash (symbol-name name) *js-macro-toplevel*)
- (lambda (&rest args)
- (macroexpand `(,name ,@args))))))
+ (let ((name name))
+ (undefine-js-compiler-macro name)
+ (setf (gethash (symbol-name name) *js-macro-toplevel*)
+ (lambda (&rest args)
+ (macroexpand `(,name ,@args)))))))
(defun js-expand-form (expr)
"Expand a javascript form."
,@(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)
+ (with new-context
(return ,expression))))))
(defvar *var-counter* 0)
(define-js-single-op delete)
(define-js-single-op void)
(define-js-single-op typeof)
-(define-js-single-op instanceof)
(define-js-single-op new)
+;; TODO this may not be the best integrated implementation of
+;; instanceof into the rest of the code
+(defjsclass js-instanceof (expression)
+ ((value)
+ (type :initarg :type)))
+
+(define-js-compiler-macro instanceof (value type)
+ (make-instance 'js-instanceof
+ :value (js-compile-to-expression value)
+ :type (js-compile-to-expression type)))
+
+(defmethod js-to-strings ((instanceof js-instanceof) start-pos)
+ (dwim-join
+ (list (js-to-strings (value instanceof) (+ start-pos 2))
+ (list "instanceof")
+ (js-to-strings (slot-value instanceof 'type) (+ start-pos 2)))
+ (- 80 start-pos 2)
+ :white-space
+ " "))
+
;;; assignment
(defjsclass js-setf (expression)
(let ((,var (aref ,arrvar ,idx)))
,@body)))))
-(defjsmacro map-into (function array)
- "Call FUNCTION on each element in ARRAY, replace element with the return value."
- ;; be friendly to both (map-into 'foo array) and (map-into foo array) calls
- (when (and (listp function)
- (eq 'quote (first function)))
- (setf function (eval function)))
- (with-unique-js-names (arrvar idx fn)
- `((lambda ()
- (let ((,arrvar ,array)
- (,fn ,function))
- (do ((,idx 0 (1+ ,idx)))
- ((>= ,idx (slot-value ,arrvar 'length)))
- (setf (aref ,arrvar ,idx) (,fn (aref ,arrvar ,idx)))))
- (return ,arrvar)))))
-
-(defjsmacro map (function array)
- "Call FUNCTION on each element in ARRAY and return the returned values in a new array."
- ;; be friendly to both (map 'foo array) and (map foo array) calls
- (when (and (listp function)
- (eq 'quote (first function)))
- (setf function (eval function)))
- (with-unique-js-names (arrvar result idx fn)
- `((lambda ()
- (let ((,arrvar ,array)
- (,fn ,function)
- (,result (make-array (slot-value ,arrvar 'length))))
- (do ((,idx 0 (1+ ,idx)))
- ((>= ,idx (slot-value ,arrvar 'length)))
- (setf (aref ,result ,idx) (,fn (aref ,arrvar ,idx)))))
- (return ,result)))))
-
(defmethod js-to-statement-strings ((for js-for) start-pos)
(let* ((init (dwim-join (mapcar #'(lambda (x)
(dwim-join (list (list (symbol-to-js (first (var-names x))))
(define-js-compiler-macro with (statement &rest body)
(make-instance 'js-with
- :obj (js-compile-to-expression (first statement))
- :body (js-compile-to-body (cons 'progn body) :indent " ")))
+ :obj (js-compile-to-expression statement)
+ :body (js-compile-to-body (cons 'progn body) :indent " ")))
(defmethod js-to-statement-strings ((with js-with) start-pos)
(nconc (dwim-join (list (js-to-strings (with-obj with) (+ start-pos 2)))
(define-js-compiler-macro regex (regex)
(make-instance 'regex :value (string regex)))
+(defun first-slash-p (string)
+ (and (> (length string) 0)
+ (eq (char string 0) '#\/)))
+
(defmethod js-to-strings ((regex regex) start-pos)
- (declare (ignore start-pos))
- (list (format nil "/~A/" (value regex))))
+ (declare (ignore start-pos))
+ (let ((slash (if (first-slash-p (value regex)) nil "/")))
+ (list (format nil (concatenate 'string slash "~A" slash) (value regex)))))
;;; conditional compilation