notinline version of + and -
[jscl.git] / ecmalisp.lisp
index d042b08..d015254 100644 (file)
@@ -98,8 +98,6 @@
 
   ;; Basic functions
   (defun = (x y) (= x y))
-  (defun + (x y) (+ x y))
-  (defun - (x y) (- x y))
   (defun * (x y) (* x y))
   (defun / (x y) (/ x y))
   (defun 1+ (x) (+ x 1))
 ;;; constructions.
 #+ecmalisp
 (progn
+  (defun + (&rest args)
+    (let ((r 0))
+      (dolist (x args r)
+       (incf r x))))
+
+  (defun - (x &rest others)
+    (if (null others)
+       (- x)
+       (let ((r x))
+         (dolist (y others r)
+           (decf r y)))))
+
   (defun append-two (list1 list2)
     (if (null list1)
         list2
                decls)
      (concat "return " (progn ,@body) ";" *newline*)))
 
-;;; VARIABLE-ARITY compiles variable arity operations. ARGS stand for
+;;; 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
     (error "ARGS must be a non-empty list"))
   (let ((counter 0)
         (variables '())
-        (prelude))
+        (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!';"
+                         "if (typeof " v " !== 'number') throw 'Not a number!';"
                          *newline*))))
     (js!selfcall prelude (funcall function (reverse variables)))))
 
   (type-check (("x" "number" x) ("y" "number" y))
     (concat "x" op "y")))
 
-(define-builtin + (x y) (num-op-num x "+" y))
-(define-builtin - (x y) (num-op-num x "-" y))
+(define-raw-builtin + (&rest numbers)
+  (if (null numbers)
+      "0"
+      (variable-arity numbers
+       (join numbers "+"))))
+
+(define-raw-builtin - (x &rest others)
+  (let ((args (cons x others)))
+    (variable-arity args
+      (if (null others)
+         (concat "-" (car args))
+         (join args "-")))))
+
+
 (define-builtin * (x y) (num-op-num x "*" y))
 (define-builtin / (x y) (num-op-num x "/" y))