X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=ecmalisp.lisp;h=05ef19c6787eebd4335fcad3e47ef5560f1ed9e1;hb=1c8b1cc2bde530d701c9dfd0c590b47708b76608;hp=2e4c4a69a7d6fe946ff527c9d56a3c7ffbe30cd8;hpb=13b874aeb9802c26ad12821b9a24337c9c20bb64;p=jscl.git diff --git a/ecmalisp.lisp b/ecmalisp.lisp index 2e4c4a6..05ef19c 100644 --- a/ecmalisp.lisp +++ b/ecmalisp.lisp @@ -1534,39 +1534,56 @@ decls) (concat "return " (progn ,@body) ";" *newline*))) +;;; VARIABLE-ARITY compiles variable arity operations. ARGS stands for +;;; a variable which holds a list of forms. It will compile them and +;;; store the result in some Javascript variables. BODY is evaluated +;;; with ARGS bound to the list of these variables to generate the +;;; code which performs the transformation on these variables. + +(defun variable-arity-call (args function) + (unless (consp args) + (error "ARGS must be a non-empty list")) + (let ((counter 0) + (variables '()) + (prelude)) + (dolist (x args) + (let ((v (concat "x" (integer-to-string (incf counter))))) + (push v variables) + (concatf prelude + (concat "var " v " = " (ls-compile x) ";" *newline* + "if (typeof " v " !=== 'number') throw 'Not a number!';" + *newline*)))) + (js!selfcall prelude (funcall function (reverse variables))))) + + +(defmacro variable-arity (args &body body) + (unless (symbolp args) + (error "Bad usage of VARIABLE-ARITY, you must pass a symbol")) + `(variable-arity-call ,args + (lambda (,args) + (concat "return " ,@body ";" *newline*)))) + + +(define-raw-builtin plus (&rest numbers) + (variable-arity numbers + (join numbers "+"))) + +(define-raw-builtin minus (x &rest others) + (let ((args (cons x others))) + (variable-arity args + (if (null others) + (concat "-" (car args)) + (join args "+"))))) + + (defun num-op-num (x op y) (type-check (("x" "number" x) ("y" "number" y)) (concat "x" op "y"))) -(defmacro define-builtin-arithmetic (op) -`(define-raw-builtin ,op (&rest args) - (if args - (let ((res (ls-compile (car args)))) - (dolist (x (cdr args)) - (setq res (num-op-num res ,(symbol-name op) (ls-compile x)))) - res) - "0"))) - -(defmacro arithmetic (op &rest args) - (let ((counter 0) - (checks ())) - (dolist (x args) - (push (list (concat "v" (ls-compile counter)) - "number" - (ls-compile x)) - checks) - (incf counter)) - `(js-eval - (type-check ,checks - ,(let ((res "")) - (dolist (x checks) - (setq res (concat (car x) (symbol-name op) res))) - (subseq res 0 (1- (length res)))))))) - -(define-builtin-arithmetic +) -(define-builtin-arithmetic -) -(define-builtin-arithmetic *) -(define-builtin-arithmetic /) +(define-builtin + (x y) (num-op-num x "+" y)) +(define-builtin - (x y) (num-op-num x "-" y)) +(define-builtin * (x y) (num-op-num x "*" y)) +(define-builtin / (x y) (num-op-num x "/" y)) (define-builtin mod (x y) (num-op-num x "%" y)) @@ -1886,7 +1903,7 @@ set setq some string-upcase string string= stringp subseq symbol-function symbol-name symbol-package symbol-plist symbol-value symbolp t tagbody third throw truncate unless unwind-protect variable warn when write-line write-string zerop -arithmetic +arithmetic plus minus )) (setq *package* *user-package*)