jscl
jscl copied to clipboard
Lambda-list bug
We are have a problem with local binding:
SBCL:
CL-USER> (let ((b 10))
((lambda (&optional (a b) (b (1+ a))) (list a b))))
(10 11)
CL-USER>
JSCL:
CL-USER> (let ((b 10))
... ((lambda (&optional (a b) (b (1+ a))) (list a b))))
ERROR: Not a number!
CL-USER>
Good catch!
The problem seems to be here:
https://github.com/jscl-project/jscl/blob/master/src/compiler/compiler.lisp#L460-L465
The environment is extended with all the bindings for the lambda in advanced. But I guess instead the environment should be 'cascaded', so each variable can be the previous ones.
The lambda
compilation is a bit complex though. It might be a good chance to simplify. I guess defining some JS functions in prelude.js and using them could help, and it would reduce the final jscl.js size as well.
There is more
CL-USER> (defun bug (string (&optional (style t) (escape t)))
... string)
BUG
CL-USER> (bug 111)
ERROR: too few arguments
CL-USER> (bug 111 2)
111
CL-USER> (disassemble 'bug)
function JSCL_USER_BUG(values,v1,v2){internals.checkArgs(arguments.length-1,2);
var v3=this;
return (function(){return v1;
})();
}
NIL
CL-USER> (multiple-value-bind (required-arguments
... optional-arguments
... keyword-arguments
... rest-argument)
... (jscl::parse-lambda-list '(string (&optional (style t) (escape t))) )
... (values required-arguments
... optional-arguments
... keyword-arguments
... rest-argument))
(STRING (&OPTIONAL (STYLE T) (ESCAPE T)))
NIL
NIL
NIL
CL-USER>
That is not a valid ordinary lambda list, so I guess it should be rejected.
JSCL
CL-USER> (labels ((%f (x &aux (b (%g x))) b)
... (%g (y) (+ y y)))
... (%f 10))
ERROR: too few arguments
SBCL
CL-USER> (labels ((%f (x &aux (b (%g x))) b)
(%g (y) (+ y y)))
(%f 10))
20
JSCL
CL-USER> (labels ((%f (x &optional (b (%g x))) b)
... (%g (y) (+ y y)))
... (%f 10))
20
JSCL
CL-USER> (DEFUN CREATE-FOO (&OPTIONAL a (B 2) &KEY (C (QUOTE SEA)) ((:HRUM D) 2) &AUX (E 5) (F (QUOTE EFF)))
... (list (QUOTE FOO-E) :A A :B B :C C :D D :E E :F F))
CREATE-FOO
CL-USER> (create-foo)
(FOO-E :A NIL :B 2 :C #<JS-OBJECT undefined> :D #<JS-OBJECT undefined> :E #<JS-OBJECT undefined> :F #<JS-OBJECT undefined>)
CL-USER> (create-foo 1)
(FOO-E :A 1 :B 2 :C #<JS-OBJECT undefined> :D #<JS-OBJECT undefined> :E #<JS-OBJECT undefined> :F #<JS-OBJECT undefined>)
CL-USER> (create-foo 1 2)
(FOO-E :A 1 :B 2 :C SEA :D 2 :E 5 :F EFF)
CL-USER>
SBCL
WARNING: redefining COMMON-LISP-USER::CREATE-FOO in DEFUN
CREATE-FOO
CL-USER> (create-foo)
(FOO-E :A NIL :B 2 :C SEA :D 2 :E 5 :F EFF)
CL-USER>
Sorry, damn copy-paste