+(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)))
+
+