'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)))))
(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()")
(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))