Basic storage vectors operations and array construction
authorDavid Vázquez <davazp@gmail.com>
Fri, 24 May 2013 00:42:18 +0000 (01:42 +0100)
committerDavid Vázquez <davazp@gmail.com>
Fri, 24 May 2013 00:42:18 +0000 (01:42 +0100)
jscl.lisp
src/arrays.lisp
src/compiler.lisp
src/print.lisp
src/string.lisp

index 7a5e35a..0f0e6be 100644 (file)
--- a/jscl.lisp
+++ b/jscl.lisp
   '(("boot"             :target)
     ("compat"           :host)
     ("utils"            :both)
+    ("numbers"          :target)
     ("list"             :target)
+    ("arrays"           :target)
     ("string"           :target)
     ("sequence"         :target)
     ("print"            :target)
     ("package"          :target)
     ("ffi"              :target)
     ("misc"             :target)
-    ("numbers"          :target)
     ("read"             :both)
     ("defstruct"        :both)
     ("lambda-list"      :both)
index 0c614cf..0f6698a 100644 (file)
       'character
       t))
 
-(defun arrayp (x) (arrayp x))
+(defun make-array (dimensions &key element-type initial-element adjustable fill-pointer)
+  (let* ((dimensions (ensure-list dimensions))
+         (size (!reduce #'* dimensions 1))
+         (array (make-storage-vector size)))
+    ;; Upgrade type
+    (if (eq element-type 'character)
+        (setf element-type 'character
+              initial-element (or initial-element #\space))
+        (setf element-type t))
+    ;; Initialize array
+    (dotimes (i size)
+      (storage-vector-set array i initial-element))
+    ;; Record and return the object
+    (oset array "type" element-type)
+    (oset array "dimensions" dimensions)
+    array))
+
+
+(defun arrayp (x)
+  (storage-vector-p x))
 
 (defun adjustable-array-p (array)
   (unless (arrayp array)
     (error "~S is not an array." array))
   t)
 
-(defun make-array (dimensions &key element-type initial-contents adjustable fill-pointer)
-  )
+(defun array-element-type (array)
+  (unless (arrayp array)
+    (error "~S is not an array." array))
+  (oget array "type"))
+
+(defun array-dimensions (array)
+  (unless (arrayp array)
+    (error "~S is not an array." array))
+  (oget array "dimensions"))
+
+;; TODO: Error checking
+(defun array-dimension (array axis)
+  (nth axis (array-dimensions array)))
+
+(defun vectorp (x)
+  (and (arrayp x) (null (cdr (array-dimensions x)))))
index 763aa92..aca3a2b 100644 (file)
 (define-builtin write-string (x)
   (code "lisp.write(" x ")"))
 
-(define-builtin make-array (n)
+
+;;; Storage vectors. They are used to implement arrays and (in the
+;;; future) structures.
+
+(define-builtin storage-vector-p (x)
+  (js!bool
+   (js!selfcall
+     "var x = " x ";" *newline*
+     "return typeof x === 'object' && 'length' in x;")))
+
+(define-builtin make-storage-vector (n)
   (js!selfcall
     "var r = [];" *newline*
-    "for (var i = 0; i < " n "; i++)" *newline*
-    (indent "r.push(" (ls-compile nil) ");" *newline*)
+    "r.length = " n ";" *newline*
     "return r;" *newline*))
 
+(define-builtin storage-vector-size (x)
+  (code x ".length"))
+
+(define-builtin resize-storage-vector (vector new-size)
+  (code "(" vector ".length = " new-size ")"))
+
+(define-builtin storage-vector-ref (vector n)
+  (js!selfcall
+    "var x = " "(" vector ")[" n "];" *newline*
+    "if (x === undefined) throw 'Out of range';" *newline*
+    "return x;" *newline*))
+
+(define-builtin storage-vector-set (vector n value)
+  (js!selfcall
+    "var x = " vector ";" *newline*
+    "var i = " n ";" *newline*
+    "if (i < 0 || i >= x.length) throw 'Out of range';" *newline*
+    "return x[i] = " value ";" *newline*))
+
+
 ;;; FIXME: should take optional min-extension.
 ;;; FIXME: should use fill-pointer instead of the absolute end of array
 (define-builtin vector-push-extend (new vector)
     "v.push(" new ");" *newline*
     "return v;"))
 
-(define-builtin arrayp (x)
-  (js!bool
-   (js!selfcall
-     "var x = " x ";" *newline*
-     "return typeof x === 'object' && 'length' in x;")))
-
 (define-builtin aref (array n)
   (js!selfcall
     "var x = " "(" array ")[" n "];" *newline*
     "var n = " new-size ";" *newline*
     "return x.length = n;" *newline*))
 
+
+
 (define-builtin get-internal-real-time ()
   "(new Date()).getTime()")
 
index 7daa143..cb4a442 100644 (file)
                     (when (mark x)
                       (visit (car x))
                       (visit (cdr x))))
-                   ((arrayp x)
+                   ((vectorp x)
                     (when (mark x)
                       (dotimes (i (length x))
                         (visit (aref x i))))))))
   (let ((prefix ""))
     (when (and *print-circle*
                (or (consp form)
-                   (arrayp form)
+                   (vectorp form)
                    (and form (symbolp form) (null (symbol-package form)))))
       (let* ((ix (afind form known-objects))
              (id (aref object-ids ix)))
                                      " . "
                                      (write-to-string (cdr last) known-objects object-ids))))
                        ")"))
-              ((arrayp form)
+              ((vectorp form)
                (let ((result "#(")
                      (sep ""))
                  (dotimes (i (length form))
index 8bead9b..7e9ae1e 100644 (file)
@@ -13,6 +13,9 @@
 ;; You should have received a copy of the GNU General Public License
 ;; along with JSCL.  If not, see <http://www.gnu.org/licenses/>.
 
+;; (defun stringp (x)
+;;   (and (vectorp x) (eq (array-element-type x) 'character)))
+
 (defun string (x)
   (cond ((stringp x) x)
         ((symbolp x) (symbol-name x))