- (new-env (extend-local-env
- (append (ensure-list rest-argument)
- required-arguments
- optional-arguments)
- env)))
- (concat "(function ("
- (join (mapcar (lambda (x)
- (translate-variable x new-env))
- (append required-arguments optional-arguments))
- ",")
- "){" *newline*
- ;; Check number of arguments
- (indent
- (if required-arguments
- (concat "if (arguments.length < " (integer-to-string n-required-arguments)
- ") throw 'too few arguments';" *newline*)
- "")
- (if (not rest-argument)
- (concat "if (arguments.length > "
- (integer-to-string (+ n-required-arguments n-optional-arguments))
- ") throw 'too many arguments';" *newline*)
- "")
- ;; Optional arguments
- (if optional-arguments
- (concat "switch(arguments.length){" *newline*
- (let ((optional-and-defaults
- (lambda-list-optional-arguments-with-default lambda-list))
- (cases nil)
- (idx 0))
- (progn
- (while (< idx n-optional-arguments)
- (let ((arg (nth idx optional-and-defaults)))
- (push (concat "case "
- (integer-to-string (+ idx n-required-arguments)) ":" *newline*
- (translate-variable (car arg) new-env)
- "="
- (ls-compile (cadr arg) new-env)
- ";" *newline*)
- cases)
- (incf idx)))
- (push (concat "default: break;" *newline*) cases)
- (join (reverse cases))))
- "}" *newline*)
- "")
- ;; &rest/&body argument
- (if rest-argument
- (let ((js!rest (translate-variable rest-argument new-env)))
- (concat "var " js!rest "= " (ls-compile nil) ";" *newline*
- "for (var i = arguments.length-1; i>="
- (integer-to-string (+ n-required-arguments n-optional-arguments))
- "; i--)" *newline*
- (indent js!rest " = "
- "{car: arguments[i], cdr: ") js!rest "};"
- *newline*))
- "")
- ;; Body
- (concat (ls-compile-block (butlast body) new-env)
- "return " (ls-compile (car (last body)) new-env) ";")) *newline*
- "})"))))
+ (*environment* (extend-local-env
+ (append (ensure-list rest-argument)
+ required-arguments
+ optional-arguments))))
+ (lambda-docstring-wrapper
+ documentation
+ "(function ("
+ (join (mapcar #'translate-variable
+ (append required-arguments optional-arguments))
+ ",")
+ "){" *newline*
+ ;; Check number of arguments
+ (indent
+ (if required-arguments
+ (concat "if (arguments.length < " (integer-to-string n-required-arguments)
+ ") throw 'too few arguments';" *newline*)
+ "")
+ (if (not rest-argument)
+ (concat "if (arguments.length > "
+ (integer-to-string (+ n-required-arguments n-optional-arguments))
+ ") throw 'too many arguments';" *newline*)
+ "")
+ ;; Optional arguments
+ (if optional-arguments
+ (concat "switch(arguments.length){" *newline*
+ (let ((optional-and-defaults
+ (lambda-list-optional-arguments-with-default lambda-list))
+ (cases nil)
+ (idx 0))
+ (progn
+ (while (< idx n-optional-arguments)
+ (let ((arg (nth idx optional-and-defaults)))
+ (push (concat "case "
+ (integer-to-string (+ idx n-required-arguments)) ":" *newline*
+ (translate-variable (car arg))
+ "="
+ (ls-compile (cadr arg))
+ ";" *newline*)
+ cases)
+ (incf idx)))
+ (push (concat "default: break;" *newline*) cases)
+ (join (reverse cases))))
+ "}" *newline*)
+ "")
+ ;; &rest/&body argument
+ (if rest-argument
+ (let ((js!rest (translate-variable rest-argument)))
+ (concat "var " js!rest "= " (ls-compile nil) ";" *newline*
+ "for (var i = arguments.length-1; i>="
+ (integer-to-string (+ n-required-arguments n-optional-arguments))
+ "; i--)" *newline*
+ (indent js!rest " = "
+ "{car: arguments[i], cdr: ") js!rest "};"
+ *newline*))
+ "")
+ ;; Body
+ (ls-compile-block body t)) *newline*
+ "})"))))