(not (ps-special-form-p form))
(not (null (op-precedence (first form))))))
+(defun method-call-form-p (form)
+ (and (listp form)
+ (symbolp (car form))
+ (char= #\. (char (symbol-name (car form)) 0))))
+
(defun funcall-form-p (form)
(and form
(listp form)
(defpsmacro ,name ,args ,@body)))
(defun ps-macroexpand (form)
- (aif (or (lookup-macro-def form *ps-symbol-macro-env*)
+ (aif (or (and (symbolp form) (lookup-macro-def form *ps-symbol-macro-env*))
(and (consp form) (lookup-macro-def (car form) *ps-macro-env*)))
(values (ps-macroexpand (funcall it form)) t)
form))
(ps-compile (string form)))
(defmethod ps-compile ((symbol symbol))
- (when (eq *ps-compilation-level* :toplevel)
- (multiple-value-bind (expansion expanded-p)
- (ps-macroexpand symbol)
- (when expanded-p
- (return-from ps-compile (ps-compile expansion)))))
- (cond ((keywordp symbol) symbol)
- ((ps-special-form-p (list symbol))
- (if (ps-reserved-symbol-p symbol)
- (funcall (get-ps-special-form symbol))
- (error "Attempting to use Parenscript special form ~a as variable" symbol)))
- (t `(js:variable ,symbol))))
+ (multiple-value-bind (expansion expanded?)
+ (ps-macroexpand symbol)
+ (if expanded?
+ (ps-compile expansion)
+ (cond ((keywordp symbol) symbol)
+ ((ps-special-form-p (list symbol))
+ (if (ps-reserved-symbol-p symbol)
+ (funcall (get-ps-special-form symbol))
+ (error "Attempting to use Parenscript special form ~a as variable" symbol)))
+ (t `(js:variable ,symbol))))))
;;; operators
-(defun op-precedence (op)
- (position op
- '((js:new js:slot-value js:aref)
- (postfix++ postfix--)
- (delete void typeof ++ -- unary+ unary- ~ !)
- (* / %)
- (+ -)
- (<< >> >>>)
- (< > <= >= js:instanceof js:in)
- (== != === !==)
- (&)
- (^)
- (\|)
- (\&\& and)
- (\|\| or)
- (js:?)
- (= *= /= %= += -= <<= >>= >>>= \&\= ^= \|=)
- (comma))
- :test #'member))
+(let ((precedence-table (make-hash-table :test 'eq)))
+ (loop for level in '((js:new js:slot-value js:aref)
+ (postfix++ postfix--)
+ (delete void typeof ++ -- unary+ unary- ~ !)
+ (* / %)
+ (+ -)
+ (<< >> >>>)
+ (< > <= >= js:instanceof js:in)
+ (== != === !==)
+ (&)
+ (^)
+ (\|)
+ (\&\& and)
+ (\|\| or)
+ (js:?)
+ (= *= /= %= += -= <<= >>= >>>= \&\= ^= \|=)
+ (comma))
+ for i from 0
+ do (mapcar (lambda (symbol)
+ (setf (gethash symbol precedence-table) i))
+ level))
+ (defun op-precedence (op)
+ (gethash op precedence-table)))
(defun ps-convert-op-name (op)
(case op
(ps-compile-expression (ps-macroexpand form)))
(cdr form))))
+(defun compile-method-call-form (form)
+ (compile-funcall-form
+ `((js:slot-value ,(second form)
+ ',(make-symbol (subseq (symbol-name (first form)) 1)))
+ ,@(cddr form))))
+
(defun compile-funcall-form (form)
`(js:funcall
- ,(ps-compile-expression (if (symbolp (car form))
- (maybe-rename-local-function (car form))
- (ps-macroexpand (car form))))
+ ,(if (symbolp (car form))
+ `(js:variable ,(maybe-rename-local-function (car form)))
+ (ps-compile-expression (ps-macroexpand (car form))))
,@(mapcar #'ps-compile-expression (cdr form))))
(defvar compile-expression?)
(compile-op-form form))))
((op-form-p form)
(compile-op-form form))
+ ((method-call-form-p form)
+ (compile-method-call-form form))
((funcall-form-p form)
(compile-funcall-form form))
- (t (error "Cannot compile ~S to a ParenScript form." form))))))
+ (t (error "Cannot compile ~S to a ParenScript form." form))))))
(defun ps-compile-statement (form)
(let ((compile-expression? nil))