String and function FFI conversion
authorDavid Vázquez <davazp@gmail.com>
Sat, 4 May 2013 01:38:13 +0000 (02:38 +0100)
committerDavid Vázquez <davazp@gmail.com>
Sat, 4 May 2013 01:38:13 +0000 (02:38 +0100)
src/compiler.lisp
src/ffi.lisp
src/prelude.js

index 4379565..7171140 100644 (file)
 (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"))
 
index 7d902a7..73d95a0 100644 (file)
@@ -16,6 +16,9 @@
 (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))
@@ -28,8 +31,8 @@
       ;; 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))))))
index ca5cfdb..601781f 100644 (file)
@@ -61,3 +61,26 @@ function make_lisp_string (string){
 
 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;
+}