(define-builtin string-upcase (x)
(code "make_lisp_string(xstring(" x ").toUpperCase())"))
+(define-builtin %lisp-to-js (x) (code "lisp_to_js(" x ")"))
+(define-builtin %js-to-lisp (x) (code "js_to_lisp(" x ")"))
+
(define-builtin string-length (x)
(code x ".length"))
(defvar *js-package*
(make-package "JS"))
+(defun lisp-to-js (x) (%lisp-to-js x))
+(defun js-to-list (x) (%js-to-lisp x))
+
(defun ffi-intern-hook (symbol)
(when (eq (symbol-package symbol) *js-package*)
(let ((sym-name (symbol-name symbol))
;; consing, as well as allow inline declarations.
(fset symbol
(eval `(lambda (&rest ,args)
- (let ((,args (list-to-vector ,args)))
- (%js-call (%js-vref ,sym-name) ,args)))))
+ (let ((,args (list-to-vector (mapcar #'lisp-to-js ,args))))
+ (js-to-list (%js-call (%js-vref ,sym-name) ,args))))))
;; Define it as a symbol macro to access to the
;; Javascript variable literally.
(%define-symbol-macro symbol `(%js-vref ,(string symbol))))))
function xstring(x){ return x.join(''); }
+
+function lisp_to_js (x) {
+ if (typeof x == 'object' && 'length' in x && x.type == 'character')
+ return xstring(x);
+ else if (typeof x == 'function'){
+ // Trampoline calling the Lisp function
+ return (function(){
+ return x.apply(this, [pv, arguments.length] + Array.prototype.slice.call(arguments));
+ })
+ }
+ else return x;
+}
+
+function js_to_lisp (x) {
+ if (typeof x == 'string')
+ return make_lisp_string(x);
+ else if (typeof x == 'function'){
+ // Trampoline calling the JS function
+ return (function(values, nargs){
+ return x.apply(this, Array.prototype.slice.call(arguments, 2));
+ })
+ } else return x;
+}