VARIABLE-ARITY helper macro
authorDavid Vázquez <davazp@Portatil.(none)>
Sun, 20 Jan 2013 14:45:10 +0000 (14:45 +0000)
committerDavid Vázquez <davazp@Portatil.(none)>
Sun, 20 Jan 2013 14:45:10 +0000 (14:45 +0000)
ecmalisp.lisp

index 46b9293..d042b08 100644 (file)
                decls)
      (concat "return " (progn ,@body) ";" *newline*)))
 
+;;; VARIABLE-ARITY compiles variable arity operations. ARGS stand 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, yo must pass a symbol"))
+  `(variable-arity-call ,args
+                        (lambda (,args)
+                          (concat "return " ,@body ";" *newline*))))
+
+
 (defun num-op-num (x op y)
   (type-check (("x" "number" x) ("y" "number" y))
     (concat "x" op "y")))