BSD 4_3_Tahoe development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 30 Jul 1983 08:36:24 +0000 (00:36 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 30 Jul 1983 08:36:24 +0000 (00:36 -0800)
Work on file usr/src/ucb/lisp/lisplib/vector.l

Synthesized-from: CSRG/cd2/4.3tahoe

usr/src/ucb/lisp/lisplib/vector.l [new file with mode: 0644]

diff --git a/usr/src/ucb/lisp/lisplib/vector.l b/usr/src/ucb/lisp/lisplib/vector.l
new file mode 100644 (file)
index 0000000..c565547
--- /dev/null
@@ -0,0 +1,273 @@
+(setq rcs-vector-
+   "$Header: vector.l 1.5 83/07/30 15:35:51 layer Exp $")
+
+;; vector handling functions   -[Sun Jun 19 15:09:14 1983 by jkf]-
+;; [also contains closure functions]
+;;
+;; preliminary.  this is subject to change at any moment.
+;; Don't use the functions in this file!!      --jkf
+;;
+;; contains functions:
+;;  vector{,i-byte,i-word,i-long}   : create and initialize
+;;  vref{,i-byte,i-word,i-long}         : reference
+;;  vset{,i-byte,i-word,i-long}         : set
+;;  vsize      -- must write
+;;  vsize-word
+;;  vsize-byte 
+;;
+;; references external functions
+;;  new-vector{,i-byte,i-word,i-long
+;;
+;; references internal functions:
+;;  int:vref 'vect 'index 'class
+;;  int:vset 'vect 'index 'value 'class
+;;  int:vsize 'vect
+
+;--- vector
+;  call is (vector elmt0 elmt1 ... elmtn)
+; creates an n-1 size vector and initializes
+;
+(defmacro vector-macro (create class)
+   `(let ((vec (,create n)))
+      (do ((from n to)
+          (to (1- n) (1- to)))
+         ((< to 0))
+         (int:vset vec to (arg from) ,class))
+      vec))
+
+(defun vector n (vector-macro new-vector 3))
+(defun vectori-byte n (vector-macro new-vectori-byte 0))
+(defun vectori-word n (vector-macro new-vectori-word 1))
+(defun vectori-long n (vector-macro new-vectori-long 2))
+
+;--- vref
+; refernces an element of a vector
+;   (vref 'vect 'index)
+;
+(defmacro vref-macro (vector index predicate limit class)
+   `(cond ((not (,predicate ,vector))
+         ,(cond ((eq predicate 'vector)
+                 `(error "vref: non vector argument " ,vector))
+                (t `(error "vref: non vectori argument " ,vector))))
+        ((not (fixp ,index))
+         (error "vref: non fixnum index " ,index))
+        ((or (< ,index 0) (not (< ,index ,limit)))
+         (error "vref: index out of range " ,index ,vector))
+        (t (int:vref ,vector ,index ,class))))
+
+(defun vref (vect ind)
+   (vref-macro vect ind vectorp (vsize vect) 3))
+
+(defun vrefi-byte (vect ind)
+   (vref-macro vect ind vectorip (vsize-byte vect) 0))
+(defun vrefi-word (vect ind)
+   (vref-macro vect ind vectorip (vsize-word vect) 1))
+(defun vrefi-long (vect ind)
+   (vref-macro vect ind vectorip (vsize vect) 2))
+
+
+;--- vset
+; use:
+;      (vset 'vector 'index 'value)
+;
+(defmacro vset-macro (vector index value predicate limit class)
+   `(cond ((not (,predicate ,vector))
+         ,(cond ((eq predicate 'vector)
+                 `(error "vset: non vector argument " ,vector))
+                (t `(error "vset: non vectori argument " ,vector))))
+        ((not (fixp ,index))
+         (error "vset: non fixnum index " ,index))
+        ((or (<& ,index 0) (not (<& ,index ,limit)))
+         (error "vset: index out of range " ,index ,vector))
+        (t (int:vset ,vector ,index ,value ,class))))
+
+(defun vset (vect ind val)
+   (vset-macro vect ind val vectorp (vsize vect) 3))
+
+(defun vseti-byte (vect ind val)
+   (vset-macro vect ind val vectorip (vsize-byte vect) 0))
+
+(defun vseti-word (vect ind val)
+   (vset-macro vect ind val vectorip (vsize-word vect) 1))
+
+(defun vseti-long (vect ind val)
+   (vset-macro vect ind val vectorip  (vsize vect) 2))
+
+
+;;; vector sizes
+
+;--- vsize :: size of vector viewed as vector of longwords
+;
+(defun vsize (vector)
+   (if (or (vectorp vector) (vectorip vector))
+      then (int:vsize vector 2)
+      else (error "vsize: non vector argument " vector)))
+
+(defun vsize-word (vectori)
+   (if (vectorip vectori)
+      then (int:vsize vectori 1)
+      else (error "vsize-word: non vectori argument " vectori)))
+
+(defun vsize-byte (vectori)
+   (if (vectorip vectori)
+      then (int:vsize vectori 0)
+      else (error "vsize-byte: non vectori argument " vectori)))
+
+;; vector property list functions
+;;
+(defun vget (vector ind)
+   (let ((x (vprop vector)))
+      (if (dtpr x)
+        then (get x ind))))
+
+;--- vputprop :: store value, indicator pair on property list
+; if a non-dtpr is already there,  make it the car of the list
+;
+(defun vputprop (vector value ind)
+   (let ((x (vprop vector)))
+      (if (not (dtpr x))       
+        then (setq x (ncons x))
+             (vsetprop vector x))
+      (putprop x value ind)))
+
+            
+;; closures
+;
+;- closures are implemented in terms of vectors so we'll store the
+; code here for now
+;  a closure is a vector with leader field eq to 'closure'
+; the 0th element of a closure vector is the functional form
+; to funcall
+; then the elements go in triplets
+;                      1 is the symbol name
+;                          either
+;      2 is nil                        2 is a pointer to a vector
+;      3 is the saved value            3 is a fixnum index into the vector
+;       ^                                 ^
+;       |---- the simple case             |-- when we are sharing a value
+;                                             slot, this points to the
+;                                             value slot
+;
+; the size of the vector tells the number of variables.
+;
+
+;--- closure :: make a closure
+; form (closure 'l_vars 'g_fcn)
+; l_vars is a list of symbols
+; g_fcn is a functional form, either a symbol or a lambda expression
+; alist is a list of what has been already stored so far.
+;   it will always be non nil, so we can nconc to it to return values.
+;
+(defun make-fclosure-with-alist (vars fcn alist)
+   (cond ((not (or (null vars) (dtpr vars)))
+         (error "fclosure: vars list has a bad form " vars)))
+   
+   (let ((vect (new-vector (1+ (length vars)) nil 'fclosure)))
+      (do ((xx vars (cdr xx))
+          (val)
+          (sym)
+          (i 1 (1+ i)))
+         ((null xx)
+          (setf (vref vect 0) fcn)     ; store the function to call
+          vect)
+         (setq sym (car xx))
+         (cond ((not (symbolp sym))
+                (error "fclosure: non symbol in var list " sym)))
+
+         ; don't allow the variable nil to be closed over
+         (cond ((null sym)
+                (error "fclosure: you can't close over nil " vars)))
+
+         ; if the fclosure variable has already been given slot, use
+         ; it, else make a new one
+         (cond ((null (setq val (assq sym alist)))
+                  ; if the variable is bound use it's current value,
+                  ; else use nil
+                  (cond ((setq val (boundp sym))
+                         (setq val (cdr val))))
+                  ; generate a new closure variable object
+                  (setq val (cons sym (cons val (copyint* 0))))
+                  ; remember this value for later fclosures
+                  (nconc alist (list val))))
+         (setf (vref vect i) val))))
+   
+
+
+;--- fclosure :: generate a simple fclosure
+; 
+(defun fclosure (vars func)
+   (make-fclosure-with-alist vars func (list nil)))
+
+(defun fclosure-list n
+   (cond ((not (evenp n))
+         (error "fclosure-alist: not given an even number of arguments: "
+                (listify n))))
+   (do ((i 1 (+ i 2))
+       (alist (list nil))
+       (res))
+       ((> i n) (nreverse res))
+       (push (make-fclosure-with-alist (arg i) (arg (1+ i)) alist) res)))
+
+(defun fclosurep (fclosure)
+   (and (vectorp fclosure)
+       (eq 'fclosure (vprop fclosure))))
+(defun fclosure-alist (fclosure)
+   (cond ((fclosurep fclosure)
+         (do ((xx 1 (1+ xx))
+              (lim  (vsize fclosure))
+              (val)
+              (res))
+             ((not (< xx lim))
+              res)
+             (setq val (vref fclosure xx))
+             (push (cons (car val) (cadr val)) res)))
+        (t (error "fclosure-alist: non fclosure argument: " fclosure))))
+
+
+
+(defun fclosure-function (fclosure)
+   (and (fclosurep fclosure)
+       (vref fclosure 0)))
+
+(defun vector-dump (vect)
+   (let (size)
+      (msg "size = " (setq size (vsize vect)) ", prop= " (vprop vect) N)
+      (do ((ii 0 (1+ ii)))
+         ((not (< ii size)))
+         (msg ii ": " (vref vect ii) N ))))
+   
+       
+;--- symeval-in-fclosure :: determine the value of a symbol
+;   with respect to an fclosure.
+;
+(defun symeval-in-fclosure (fclosure symbol)
+  (cond ((not (fclosurep fclosure))
+        (error "set-in-fclosure: non fclosure first argument: " fclosure))
+       (t (do ((xx 1 (1+ xx))
+               (val)
+               (lim (vsize fclosure)))
+              ((not (< xx lim))
+               (error "symeval-in-fclosure: variable not found" symbol))
+              (setq val (vref fclosure xx))
+              (cond ((eq symbol (car val))
+                     (return (int:fclosure-stack-stuff val))))))))
+
+;--- set-in-fclosure :: set the value of a symbol in an fclosure
+;
+(defun set-in-fclosure (fclosure symbol value)
+  (cond ((not (fclosurep fclosure))
+        (error "set-in-fclosure: non fclosure first argument: " fclosure))
+       (t (do ((xx 1 (1+ xx))
+               (val)
+               (lim (vsize fclosure)))
+              ((not (< xx lim))
+               (error "set-in-fclosure: variable not found" symbol))
+              (setq val (vref fclosure xx))
+              (cond ((eq symbol (car val))
+                     (return (int:fclosure-stack-stuff val value))))))))
+
+(defmacro let-fclosed (vars function)
+  `(let ,vars (fclosure ',(mapcar #'(lambda (x) (if (atom x) x (car x))) vars)
+                       ,function)))
+               
+