FFI conversion
authorDavid Vázquez <davazp@gmail.com>
Sat, 4 May 2013 02:20:56 +0000 (03:20 +0100)
committerDavid Vázquez <davazp@gmail.com>
Sat, 4 May 2013 02:20:56 +0000 (03:20 +0100)
jscl.html
src/compiler.lisp
src/ffi.lisp
src/prelude.js

index 782db20..47b4efb 100644 (file)
--- a/jscl.html
+++ b/jscl.html
 
         var startPrompt = function () {
           // Start the prompt with history enabled.
-          jqconsole.Write(xstring(lisp.evalString(pv, 1, make_lisp_string('(CL:PACKAGE-NAME CL:*PACKAGE*)'))) + '> ', 'jqconsole-prompt');
+          jqconsole.Write(lisp.evalString('(CL:PACKAGE-NAME CL:*PACKAGE*)') + '> ', 'jqconsole-prompt');
           jqconsole.Prompt(true, function (input) {
             // Output input with the class jqconsole-return.
             if (input[0] != ','){
                 try {
-                    var vs = lisp.evalInput(mv, 1, make_lisp_string(input));
-                    for (var i=0; i<vs.length; i++){
-                       jqconsole.Write(xstring(lisp.print(pv, 1, vs[i])) + '\n', 'jqconsole-return');
-                    }
+                    var vs = lisp.evalInput(input);
+                    // for (var i=0; i<vs.length; i++){
+                       jqconsole.Write(lisp.print(vs) + '\n', 'jqconsole-return');
+                    // }
                 } catch(error) {
                     var msg = error.message || error || 'Unknown error';
                     if (typeof(msg) != 'string') msg = xstring(msg);
                     jqconsole.Write('ERROR: ' + msg + '\n', 'jqconsole-error');
                 }
-            } else {
-                jqconsole.Write(xstring(lisp.compileString(pv, 1, make_lisp_string(input.slice(1)))) + '\n', 'jqconsole-return');
-            }
+            } else
+                jqconsole.Write(lisp.compileString(input.slice(1)) + '\n', 'jqconsole-return');
+
             // Restart the prompt.
             startPrompt();
           }, function(input){
             try {
-                lisp.read(pv, 1, make_lisp_string(input[0]==','? input.slice(1): input));
+                lisp.read(input[0]==','? input.slice(1): input);
             } catch(error) {
                 return 0;
             }
index 7171140..53ec318 100644 (file)
     "return args;" *newline*))
 
 
-;;; Javascript FFI
-
-(define-compilation %js-vref (var) var)
-
-(define-compilation %js-vset (var val)
-  (code "(" var " = " (ls-compile val) ")"))
-
-(define-setf-expander %js-vref (var)
-  (let ((new-value (gensym)))
-    (unless (stringp var)
-      (error "`~S' is not a string." var))
-    (values nil
-            (list var)
-            (list new-value)
-            `(%js-vset ,var ,new-value)
-            `(%js-vref ,var))))
-
-
 ;;; Backquote implementation.
 ;;;
 ;;;    Author: Guy L. Steele Jr.     Date: 27 December 1985
 (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"))
 
       (code "values(" (join (mapcar #'ls-compile args) ", ") ")")
       (code "pv(" (join (mapcar #'ls-compile args) ", ") ")")))
 
+
+;;; Javascript FFI
+
 ;; Receives the JS function as first argument as a literal string. The
 ;; second argument is compiled and should evaluate to a vector of
-;; values to apply to the the function. The result returned.
+;; values to apply to the the function. The result returned. No type
+;; conversion is done here. It is supposed to happen in the
+;; trampoline.
 (define-builtin %js-call (fun args)
-  (code fun ".apply(this, " args ")"))
+  (code fun ".apply(this, " args "))"))
+
+(define-compilation %js-vref (var)
+  (code "js_to_lisp(" var ")"))
+
+(define-compilation %js-vset (var val)
+  (code "(" var " = lisp_to_js(" (ls-compile val) "))"))
+
+(define-setf-expander %js-vref (var)
+  (let ((new-value (gensym)))
+    (unless (stringp var)
+      (error "`~S' is not a string." var))
+    (values nil
+            (list var)
+            (list new-value)
+            `(%js-vset ,var ,new-value)
+            `(%js-vref ,var))))
+
 
 #+common-lisp
 (defvar *macroexpander-cache*
index 73d95a0..24fc472 100644 (file)
@@ -16,9 +16,6 @@
 (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))
@@ -31,8 +28,7 @@
       ;; consing, as well as allow inline declarations.
       (fset symbol
             (eval `(lambda (&rest ,args)
-                     (let ((,args (list-to-vector (mapcar #'lisp-to-js ,args))))
-                       (js-to-list (%js-call (%js-vref ,sym-name) ,args))))))
+                     (%js-call (%js-vref ,sym-name) (list-to-vector ,args)))))
       ;; Define it as a symbol macro to access to the
       ;; Javascript variable literally.
       (%define-symbol-macro symbol `(%js-vref ,(string symbol))))))
index 601781f..e49b781 100644 (file)
@@ -68,8 +68,11 @@ function lisp_to_js (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));
-        })
+            var args = Array.prototype.slice.call(arguments);
+            for (var i in args)
+                args[i] = js_to_lisp(args[i]);
+            return lisp_to_js(x.apply(this, [pv, arguments.length].concat(args)));
+        });
     }
     else return x;
 }
@@ -80,7 +83,10 @@ function js_to_lisp (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));
-        })
+            var args = Array.prototype.slice.call(arguments, 2);
+            for (var i in args)
+                args[i] = lisp_to_js(args[i]);
+            return values(js_to_lisp(x.apply(this, args)));
+        });
     } else return x;
 }