jscl-project / jscl

A Lisp-to-JavaScript compiler bootstrapped from Common Lisp

Home Page:https://jscl-project.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Lambda-list bug

vlad-km opened this issue · comments

commented

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.

commented

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.

commented

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
commented

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