- (code
- ;; Declare variables
- (mapconcat (lambda (arg)
- (let ((var (second (car arg))))
- (code "var " (translate-variable var) "; " *newline*
- (when (third arg)
- (code "var " (translate-variable (third arg))
- " = " (ls-compile nil)
- ";" *newline*)))))
- keyword-arguments)
- ;; Parse keywords
- (flet ((parse-keyword (keyarg)
- ;; ((keyword-name var) init-form)
- (code "for (i=" (+ n-required-arguments n-optional-arguments)
- "; i<nargs; i+=2){" *newline*
- (indent
- "if (arguments[i+2] === " (ls-compile (caar keyarg)) "){" *newline*
- (indent (translate-variable (cadr (car keyarg)))
- " = arguments[i+3];"
- *newline*
- (let ((svar (third keyarg)))
- (when svar
- (code (translate-variable svar) " = " (ls-compile t) ";" *newline*)))
- "break;" *newline*)
- "}" *newline*)
- "}" *newline*
- ;; Default value
- "if (i == nargs){" *newline*
- (indent (translate-variable (cadr (car keyarg))) " = " (ls-compile (cadr keyarg)) ";" *newline*)
- "}" *newline*)))
- (when keyword-arguments
- (code "var i;" *newline*
- (mapconcat #'parse-keyword keyword-arguments))))
- ;; Check for unknown keywords
- (when keyword-arguments
- (code "var start = " (+ n-required-arguments n-optional-arguments) ";" *newline*
- "if ((nargs - start) % 2 == 1){" *newline*
- (indent "throw 'Odd number of keyword arguments';" *newline*)
- "}" *newline*
- "for (i = start; i<nargs; i+=2){" *newline*
- (indent "if ("
- (join (mapcar (lambda (x)
- (concat "arguments[i+2] !== " (ls-compile (caar x))))
- keyword-arguments)
- " && ")
- ")" *newline*
- (indent
- "throw 'Unknown keyword argument ' + xstring(arguments[i+2].name);" *newline*))
- "}" *newline*)))))
+ `(progn
+ ;; Declare variables
+ ,@(with-collect
+ (dolist (keyword-argument keyword-arguments)
+ (destructuring-bind ((keyword-name var) &optional initform svar)
+ keyword-argument
+ (declare (ignore keyword-name initform))
+ (collect `(var ,(translate-variable var)))
+ (when svar
+ (collect
+ `(var (,(translate-variable svar)
+ ,(convert nil))))))))
+
+ ;; Parse keywords
+ ,(flet ((parse-keyword (keyarg)
+ (destructuring-bind ((keyword-name var) &optional initform svar) keyarg
+ ;; ((keyword-name var) init-form svar)
+ `(progn
+ (for ((= i ,(+ n-required-arguments n-optional-arguments))
+ (< i |nargs|)
+ (+= i 2))
+ ;; ....
+ (if (=== (property |arguments| (+ i 2))
+ ,(convert keyword-name))
+ (progn
+ (= ,(translate-variable var)
+ (property |arguments| (+ i 3)))
+ ,(when svar `(= ,(translate-variable svar)
+ ,(convert t)))
+ (break))))
+ (if (== i |nargs|)
+ (= ,(translate-variable var) ,(convert initform)))))))
+ (when keyword-arguments
+ `(progn
+ (var i)
+ ,@(mapcar #'parse-keyword keyword-arguments))))
+
+ ;; Check for unknown keywords
+ ,(when keyword-arguments
+ `(progn
+ (var (start ,(+ n-required-arguments n-optional-arguments)))
+ (if (== (% (- |nargs| start) 2) 1)
+ (throw "Odd number of keyword arguments."))
+ (for ((= i start) (< i |nargs|) (+= i 2))
+ (if (and ,@(mapcar (lambda (keyword-argument)
+ (destructuring-bind ((keyword-name var) &optional initform svar)
+ keyword-argument
+ (declare (ignore var initform svar))
+ `(!== (property |arguments| (+ i 2)) ,(convert keyword-name))))
+ keyword-arguments))
+ (throw (+ "Unknown keyword argument "
+ (call |xstring|
+ (property
+ (property |arguments| (+ i 2))
+ "name")))))))))))