CODEGEN: Use lexical variables instead of special ones
[jscl.git] / src / compiler.lisp
index a65cd33..09ca814 100644 (file)
 
 (defun gvarname (symbol)
   (declare (ignore symbol))
-  (code "v" (incf *variable-counter*)))
+  (incf *variable-counter*)
+  (concat "v" (integer-to-string *variable-counter*)))
 
 (defun translate-variable (symbol)
   (awhen (lookup-in-lexenv symbol *environment* 'variable)
         (when name      `(= (get func |fname|) ,name))
         (when docstring `(= (get func |docstring|) ,docstring))
         `(return func))
-      `(code ,code)))
+      code))
 
 (defun lambda-check-argument-count
     (n-required-arguments n-optional-arguments rest-p)
 (defvar *literal-counter* 0)
 
 (defun genlit ()
-  (code "l" (incf *literal-counter*)))
+  (incf *literal-counter*)
+  (concat "l" (integer-to-string *literal-counter*)))
 
 (defun dump-symbol (symbol)
   #-jscl
 
 (define-builtin characterp (x)
   (js!bool
-   (js!selfcall
-     "var x = " x ";"
-     "return (typeof(" x ") == \"string\") && (x.length == 1 || x.length == 2);")))
+   (js!selfcall*
+     `(var (x ,x))
+     `(return (and (== (typeof x) "string")
+                   (or (== (get x "length") 1)
+                       (== (get x "length") 2)))))))
 
 (define-builtin char-upcase (x)
   `(call |safe_char_upcase| ,x))
                    (== (get x "stringp") 1))))))
 
 (define-raw-builtin funcall (func &rest args)
-  (js!selfcall
-    "var f = " (ls-compile func) ";"
-    "return (typeof f === 'function'? f: f.fvalue)("
-    `(code
-     ,@(interleave (list* (if *multiple-value-p* "values" "pv")
-                          (integer-to-string (length args))
-                          (mapcar #'ls-compile args))
-                   ", "))
-    ")"))
+  (js!selfcall*
+    `(var (f ,(ls-compile func)))
+    `(return (call (if (=== (typeof f) "function")
+                       f
+                       (get f "fvalue"))
+                   ,@(list* (if *multiple-value-p* '|values| '|pv|)
+                            (length args)
+                            (mapcar #'ls-compile args))))))
 
 (define-raw-builtin apply (func &rest args)
   (if (null args)
     `(return r)))
 
 (define-builtin get-internal-real-time ()
-  `(call (get (new (call Date)) "getTime")))
+  `(call (get (new (call |Date|)) "getTime")))
 
 (define-builtin values-array (array)
   (if *multiple-value-p*
 
 (define-raw-builtin oset* (value object key &rest keys)
   (let ((keys (cons key keys)))
-    (js!selfcall
-      "var obj = " (ls-compile object) ";"
-      `(code ,@(mapcar (lambda (key)
-                         `(code "obj = obj[xstring(" ,(ls-compile key) ")];"
-                                "if (obj === undefined) throw 'Impossible to set Javascript property.';" ))
-                       (butlast keys)))
-      "var tmp = obj[xstring(" (ls-compile (car (last keys))) ")] = " (ls-compile value) ";"
-      "return tmp === undefined? " (ls-compile nil) " : tmp;" )))
+    (js!selfcall*
+      `(progn
+         (var (obj ,(ls-compile object)))
+         ,@(mapcar (lambda (key)
+                     `(progn
+                        (= obj (get obj (call |xstring| ,(ls-compile key))))
+                        (if (=== object undefined)
+                            (throw "Impossible to set object property."))))
+                   (butlast keys))
+         (var (tmp
+               (= (get obj (call |xstring| ,(ls-compile (car (last keys)))))
+                  ,(ls-compile value))))
+         (return (if (=== tmp undefined)
+                     ,(ls-compile nil)
+                     tmp))))))
 
 (define-raw-builtin oget (object key &rest keys)
   `(call |js_to_lisp| ,(ls-compile `(oget* ,object ,key ,@keys))))
   (js!bool `(in (call |xstring| ,key) ,object)))
 
 (define-builtin map-for-in (function object)
-  (js!selfcall
-   "var f = " function ";"
-   "var g = (typeof f === 'function' ? f : f.fvalue);"
-   "var o = " object ";"
-   "for (var key in o){"
-   `(code "g(" ,(if *multiple-value-p* "values" "pv") ", 1, o[key]);" )
-   "}"
-   " return " (ls-compile nil) ";" ))
+  (js!selfcall*
+    `(var (f ,function)
+          (g (if (=== (typeof f) "function") f (get f "fvalue")))
+          (o ,object))
+    `(for-in (key o)
+       (call g ,(if *multiple-value-p* '|values| '|pv|) 1 (get o "key")))
+    `(return ,(ls-compile nil))))
 
 (define-compilation %js-vref (var)
-  `(code "js_to_lisp(" ,var ")"))
+  `(call |js_to_lisp| ,(make-symbol var)))
 
 (define-compilation %js-vset (var val)
-  `(code "(" ,var " = lisp_to_js(" ,(ls-compile val) "))"))
+  `(= ,(make-symbol var) (call |lisp_to_js| ,(ls-compile val))))
 
 (define-setf-expander %js-vref (var)
   (let ((new-value (gensym)))