Annotation of 43BSDReno/pgrm/lisp/pearl/vars.l, revision 1.1

1.1     ! root        1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vars.l ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             2: ; Functions for declaring and creating pattern-matching variables
        !             3: ;    and blocks and for freezing and thawing them.
        !             4: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             5: ; Copyright (c) 1983 ,  The Regents of the University of California.
        !             6: ; All rights reserved.  
        !             7: ; Authors: Joseph Faletti and Michael Deering.
        !             8: 
        !             9: ; Convert a question mark variable ?var to either (*global* var) if "var"
        !            10: ;    is in *globallist* or else make it local (*var* var).
        !            11: (drm \?
        !            12:   (lambda ()
        !            13:          (let ((nextchar (tyipeek))
        !            14:                var)
        !            15:               (cond ((\=&  9. nextchar) '\?)
        !            16:                     ((\=& 10. nextchar) '\?)
        !            17:                     ((\=& 13. nextchar) '\?)
        !            18:                     ((\=& 32. nextchar) '\?)
        !            19:                     ((\=& 41. nextchar) '\?)
        !            20:                     ( t (setq var (read))
        !            21:                         (cond ((memq var *globallist*)
        !            22:                                (list '*global* var))
        !            23:                               (  t  (list '*var* var))))))))
        !            24:  
        !            25: ; VALUEOF and VARVALUE are EXPR and FEXPR versions of a function to
        !            26: ;     get the value of the variable VAR in the structure STRUCT.
        !            27: (de valueof (var struct)
        !            28:   (getvalofequivorvar
        !            29:    (cdr (or (assq var (getalist struct))
        !            30:            (assq var (getalistcp struct))
        !            31:            (progn (msg t "VALUEOF: Variable " var
        !            32:                        " does not occur in structure:" struct t)
        !            33:                   (pearlbreak))))))
        !            34:  
        !            35: ;    This is a FEXPR version of valueof (above).
        !            36: (df varvalue (l)     ; (VAR STRUCT)
        !            37:   (let ((var (car l))
        !            38:        (struct (eval (cadr l))))
        !            39:        (getvalofequivorvar
        !            40:        (cdr (or (assq var (getalist struct))
        !            41:                 (assq var (getalistcp struct))
        !            42:                 (progn (msg t "VARVALUE: Variable " var
        !            43:                             " does not occur in structure:" struct t)
        !            44:                        (pearlbreak)))))))
        !            45: 
        !            46: ; Set the given variable, in the given environment (if present) to
        !            47: ;    the value given.  If no environment given, look first at
        !            48: ;    *currentstructure*, then at *currentpearlstructure*, then at
        !            49: ;    *blockstack*, else complain.
        !            50: (df setv (l)    ; (var 'val 'environment)
        !            51:   (let*
        !            52:    ((var (car l))
        !            53:     (type (car var))
        !            54:     (name (cadr var))
        !            55:     (val (eval (cadr l)))
        !            56:     (environment (eval (caddr l)))
        !            57:     varcell
        !            58:     oldvarval)
        !            59:    (cond ((eq '*global* type)   ; global variable.
        !            60:          (setq oldvarval (eval name))
        !            61:          (set name val))
        !            62:         ((eq '*var* type)      ; local or block variable.
        !            63:          (cond (environment
        !            64:                 ; optional 3rd argument given for environment.
        !            65:                 (cond ((structurep environment)
        !            66:                        (setq varcell
        !            67:                              (or (assq name (getalist environment))
        !            68:                                  (assq name (getalistcp environment))
        !            69:                                  (progn (msg t "SETV: No variable named: " name
        !            70:                                              " in structure: " t environment t)
        !            71:                                         (pearlbreak)))))
        !            72:                       ((blockp environment)
        !            73:                        (setq varcell
        !            74:                              (or (assq name environment)
        !            75:                                  (progn (msg t "SETV: No variable named: " name
        !            76:                                              " in block: " t environment t)
        !            77:                                         (pearlbreak)))))
        !            78:                       ( t (msg t "SETV: Given environment is neither "
        !            79:                                "a block nor a structure: " t environment)
        !            80:                           (pearlbreak))))
        !            81:                ; otherwise, try to find in standard environment.
        !            82:                ((setq varcell
        !            83:                       (or (and (structurep *currentstructure*)
        !            84:                                (or (assq name (getalist *currentstructure*))
        !            85:                                    (assq name (getalistcp *currentstructure*))
        !            86:                                    ))
        !            87:                           (and (structurep *currentpearlstructure*)
        !            88:                                (or (assq name
        !            89:                                          (getalist *currentpearlstructure*))
        !            90:                                    (assq name
        !            91:                                          (getalistcp *currentpearlstructure*))
        !            92:                                    ))
        !            93:                           (and *blockstack*
        !            94:                                (assq name (cdar *blockstack*))))))
        !            95:                ( t ; Else if not there either, blow up.
        !            96:                    (msg t "SETV: No variable in the current"
        !            97:                         " environment named: " name t)
        !            98:                    (pearlbreak)))
        !            99:          ; Successfully found the variable.
        !           100:          (and varcell
        !           101:               (setq oldvarval (cdr varcell))
        !           102:               (rplacd varcell val)))
        !           103:         ( t (msg t "SETV: " var " is not a variable." t)
        !           104:             (pearlbreak)))
        !           105:    (and (equivclassp oldvarval)
        !           106:        (mapc (funl (newvar) (cond ((dtpr newvar)           ; a local var cell.
        !           107:                                    (and (eq (cdr newvar) oldvarval)
        !           108:                                         (rplacd newvar val)))
        !           109:                                   ( t ; otherwise a global var's name.
        !           110:                                       (and (eq (eval newvar) oldvarval)
        !           111:                                            (set newvar val)))))
        !           112:              (cdr oldvarval)))
        !           113:    val))
        !           114: 
        !           115: ; Get the value of a local variable.   Look in the same places as
        !           116: ;    SETV above but return nil if not found.
        !           117: (df *var* (l)
        !           118:   (let ((var (car l)))
        !           119:        (getvalofequivorvar
        !           120:          (cdr (or (and (structurep *currentstructure*)
        !           121:                        (or (assq var (getalist *currentstructure*))
        !           122:                            (assq var (getalistcp *currentstructure*))))
        !           123:                   (and (structurep *currentpearlstructure*)
        !           124:                        (or (assq var (getalist *currentpearlstructure*))
        !           125:                            (assq var
        !           126:                                  (getalistcp *currentpearlstructure*))))
        !           127:                   (and *blockstack*
        !           128:                        (assq var (cdar *blockstack*))))))))
        !           129: 
        !           130: ; Get the value of a global variable.
        !           131: (df *global* (l)
        !           132:   (getvalofequivorvar
        !           133:      (eval (car l))))
        !           134: 
        !           135: ; Declare a variable to be GLOBAL by entering it on the *GLOBALLIST*
        !           136: ;    and PEARL-unbinding it.
        !           137: (df global (l)
        !           138:   (let ((variable (car l)))
        !           139:        (set variable (punbound))
        !           140:        (push variable *globallist*)
        !           141:        variable))
        !           142:  
        !           143: ; PEARL-unbind a global variable. ("unbindvars" does the local variables
        !           144: ;    in an entire structure (see match.l)).
        !           145: (df unbind (l)
        !           146:   (let ((var (car l)))
        !           147:        (cond ((memq var *globallist*)
        !           148:              (set var (punbound)))
        !           149:             ( t (set var (punbound))
        !           150:                 (and *warn*
        !           151:                      (msg t "UNBIND: Warning: " var
        !           152:                           " is not a global variable but unbound it anyway."
        !           153:                           t))))))
        !           154: 
        !           155: ; Determine if the variable is GLOBAL, i.e., on the *GLOBALLIST*
        !           156: (de globalp (variable)
        !           157:   (memq variable *globallist*))
        !           158:  
        !           159: ; (BLOCK <name> (<LIST OF VARIABLES>)) starts a (possibly embedded)
        !           160: ;    set of variables accessible to all structure CREATEd within
        !           161: ;    the block.   Terminated by a call to (ENDBLOCK <name>).
        !           162: ; The name is optional.  If used, then the block may be reaccessed
        !           163: ;    with b:<name>.
        !           164:  
        !           165: (df block (l)
        !           166:   (let ((name (car l))
        !           167:        varlist
        !           168:        alist)
        !           169:        (cond ((reallitatom name) (setq varlist (cadr l)))
        !           170:             ( t  (setq varlist name)
        !           171:                  (setq name 'unnamedblock)))
        !           172:        (setq alist
        !           173:             (nconc (ncons (cons nil (punbound)))  ; Cell for Frozen vars.
        !           174:                    (mapcar (funl (varname) (cons varname (punbound)))
        !           175:                            varlist)
        !           176:                    (cond (*blockstack* (cdar *blockstack*))
        !           177:                          ( t nil))))
        !           178:        (and name
        !           179:            (set name alist))
        !           180:        ; Create a special cons cell, point b:<name> at it and push it.
        !           181:        (push (set (blockatom name)
        !           182:                  (cons name alist))
        !           183:             *blockstack*)
        !           184:        name))
        !           185:  
        !           186: ; (ENDBLOCK <name>) ends the block with name <name>.
        !           187: ;    If <name> is * then close one block, regardless of name.
        !           188: ;    If <name> is nil then close one unnamed block only.
        !           189: (df endblock (l)
        !           190:   (let ((name (car l)))
        !           191:        (and (null name)
        !           192:            (setq name 'unnamedblock))
        !           193:        (cond ((not *blockstack*)
        !           194:              (msg t "ENDBLOCK: No blocks to end")
        !           195:              (msg ", not even named: " name t)
        !           196:              (pearlbreak))
        !           197:             ((or (eq name '*)
        !           198:                  (eq name (caar *blockstack*)))
        !           199:              (prog1 (caar *blockstack*)
        !           200:                     (setq *blockstack* (cdr *blockstack*))))
        !           201:             ( t (msg t "ENDBLOCK: Block to be ended, "
        !           202:                      name " doesn't match innermost block, named: "
        !           203:                      (caar *blockstack*) t)
        !           204:                 (pearlbreak)))))
        !           205: 
        !           206: ; (ENDANYBLOCKS <name>) ends all blocks back through the block
        !           207: ;    with name <name>.
        !           208: ; If <name> is * then end all blocks.
        !           209: ; If <name> is nil then end all blocks back through the
        !           210: ;    last unnamed block.
        !           211: (df endanyblocks (l)
        !           212:   (let ((name (car l))
        !           213:        (block *blockstack*))
        !           214:        (cond ((not *blockstack*)    nil)
        !           215:             ((eq name '*)       (setq *blockstack* nil))
        !           216:             ((null (while (and block
        !           217:                                (neq (caar block) name))
        !           218:                           (setq block (cdr block))))
        !           219:              (msg t "ENDANYBLOCKS: No currently open block named "
        !           220:                   name " to end blocks back to." t)
        !           221:              (pearlbreak))
        !           222:             ( t (setq *blockstack* (pop block))
        !           223:                 (caar *blockstack*)))
        !           224:        t))
        !           225: 
        !           226: ; (ENDALLBLOCKS <name>) ends any open blocks, regardless of name.
        !           227: (de endallblocks ()
        !           228:   (setq *blockstack* nil)
        !           229:   t)
        !           230: 
        !           231: ; (SETBLOCK <blockname>) changes the current scope to that of
        !           232: ;      <blockname>, BUT doesn't allow ending former blocks!
        !           233: (df setblock (l)
        !           234:   (let ((blockname (car l)))
        !           235:        (cond ((and (boundp (blockatom blockname))
        !           236:                   (blockp (eval (blockatom blockname))))
        !           237:              (setq *blockstack* (eval (blockatom blockname))))
        !           238:             ( t (msg t "SETBLOCK: There is no block named: " blockname t)
        !           239:                 (pearlbreak)))))
        !           240:  
        !           241: ; Take all the bound variables off the STRUCT'S ALIST, and put them on
        !           242: ; the ALISTCP, preserving unique alist pairs.  Also take care of all the
        !           243: ; BLOCK alists.  WARNING: This code is tough so be careful with it!
        !           244: (de freezebindings (struct)
        !           245:   (let ((oldalist (getalist struct))     ; to be frozen.
        !           246:        (unboundalist (ncons nil))       ; to still unbound variables.
        !           247:        (boundalist (getalistcp struct)) ; already frozen.
        !           248:        rest
        !           249:        currentblock)
        !           250:        ; While there are more variables to process, and we haven't reached
        !           251:        ;     a block, add either to "unboundalist" or "boundalist".
        !           252:        (while (and oldalist
        !           253:                   (reallitatom (caar oldalist)))
        !           254:              (setq rest (cdr oldalist))
        !           255:              (cond ((eq (cdar oldalist) (punbound))
        !           256:                     (tconc unboundalist (car oldalist)))
        !           257:                    ( t (setq boundalist (rplacd oldalist boundalist))))
        !           258:              (setq oldalist rest))
        !           259:        (and oldalist
        !           260:            (rplaca unboundalist
        !           261:                    (nconc (car unboundalist)
        !           262:                           oldalist))) ; pointer to the enclosing blocks.
        !           263:        ; Store new lists.
        !           264:        (putalist (car unboundalist) struct)
        !           265:        (putalistcp boundalist struct)
        !           266:        ; Process blocks one at a time.
        !           267:        (while oldalist
        !           268:              (setq currentblock oldalist)
        !           269:              (setq oldalist (cdr oldalist))
        !           270:              (setq unboundalist (ncons nil))
        !           271:              (setq boundalist (caar currentblock))
        !           272:              (while (and oldalist
        !           273:                          (reallitatom (caar oldalist)))
        !           274:                     (setq rest (cdr oldalist))
        !           275:                     (cond ((eq (cdar oldalist) (punbound))
        !           276:                            (tconc unboundalist (car oldalist)))
        !           277:                           ( t (setq boundalist (rplacd oldalist boundalist))))
        !           278:                     (setq oldalist rest))
        !           279:              (and oldalist
        !           280:                   (rplaca unboundalist
        !           281:                           (nconc (car unboundalist)
        !           282:                                  oldalist))) ; pointer to the enclosing blocks.
        !           283:              ; store frozen vars.
        !           284:              (rplaca (car currentblock) boundalist)
        !           285:              (rplacd currentblock (car unboundalist)))
        !           286:        t))
        !           287:  
        !           288: ; Take all the bound variables off the STRUCT's ALIST, and put them on
        !           289: ;   the ALISTCP, preserving unique alist pairs.
        !           290: (de freezestruct (struct)
        !           291:   (let ((oldalist (getalist struct))
        !           292:        (unboundalist (ncons nil))
        !           293:        (boundalist (getalistcp struct))
        !           294:        rest)
        !           295:        (while (and oldalist                       ; is not NIL, and
        !           296:                   (reallitatom (caar oldalist))) ; have not reached block
        !           297:              (setq rest (cdr oldalist))
        !           298:              (cond ((eq (cdar oldalist) (punbound))
        !           299:                     (tconc unboundalist (car oldalist)))
        !           300:                    ( t (setq boundalist (rplacd oldalist boundalist))))
        !           301:              (setq oldalist rest))
        !           302:        (and oldalist
        !           303:            (rplaca unboundalist
        !           304:                    (nconc (car unboundalist)
        !           305:                           oldalist))) ; pointer to the enclosing blocks.
        !           306:        (putalist (car unboundalist) struct)
        !           307:        (putalistcp boundalist struct)
        !           308:        t))
        !           309:  
        !           310: (df freezeblock (blockname)
        !           311:   (let (block
        !           312:        oldalist
        !           313:        unboundalist
        !           314:        boundalist
        !           315:        rest)
        !           316:        (cond ((and (boundp (blockatom (car blockname)))
        !           317:                   (setq block (eval (blockatom (car blockname))))
        !           318:                   (blockp block)))
        !           319:             ( t (msg t "FREEZEBLOCK: " blockname
        !           320:                      " is not the name of a block." t)
        !           321:                 (pearlbreak)))
        !           322:        (setq oldalist (cddr block))
        !           323:        (setq unboundalist (ncons nil))
        !           324:        (setq boundalist (caadr block))
        !           325:        (while (and oldalist
        !           326:                   (reallitatom (caar oldalist)))
        !           327:              (setq rest (cdr oldalist))
        !           328:              (cond ((eq (cdar oldalist) (punbound))
        !           329:                     (tconc unboundalist (car oldalist)))
        !           330:                    ( t (setq boundalist (rplacd oldalist boundalist))))
        !           331:              (setq oldalist rest))
        !           332:        (and oldalist
        !           333:            (rplaca unboundalist
        !           334:                    (nconc (car unboundalist)
        !           335:                           oldalist))) ; pointer to the enclosing blocks.
        !           336:        (rplaca (cadr block) boundalist) ; store frozen vars.
        !           337:        (rplacd (cdr block) (car unboundalist))
        !           338:        t))
        !           339:  
        !           340: (dm findnextblockstart (none) ; But expects ALIST
        !           341:   '(while (and alist
        !           342:               (reallitatom (caar alist)))
        !           343:          (setq alist (cdr alist))))
        !           344:  
        !           345: ; This is for JUST THE STRUCT.
        !           346: (de thawstruct (struct)
        !           347:   (let ((alist (getalist struct)))
        !           348:        (putalist (nconc (getalistcp struct) alist) struct)
        !           349:        (putalistcp nil struct)
        !           350:        t))
        !           351:  
        !           352: ; Restore the Alist to include all values. (Undo FREEZEBINDINGS)
        !           353: ; This is done for ALL BLOCKs that STRUCT is a member of.
        !           354: (de thawbindings (struct)
        !           355:   (let ((alist (getalist struct)))
        !           356:        (putalist (nconc (getalistcp struct) alist) struct)
        !           357:        (putalistcp nil struct)
        !           358:        (while (findnextblockstart)
        !           359:              (rplacd alist (nconc (caar alist) (cdr alist)))
        !           360:              (rplaca (car alist) nil))
        !           361:        t))
        !           362:  
        !           363: ; This is for JUST ONE BLOCK.
        !           364: (df thawblock (blockname)
        !           365:   (let (alist
        !           366:        block)
        !           367:        (cond ((and (boundp (blockatom (car blockname)))
        !           368:                   (setq block (eval (blockatom (car blockname))))
        !           369:                   (blockp block))
        !           370:              block)
        !           371:             ( t (msg t "THAWBLOCK: " blockname
        !           372:                      " is not the name of a block." t)
        !           373:                 (pearlbreak)))
        !           374:        (setq alist (cddr block))
        !           375:        (rplacd (cdr block) (nconc (caadr block) alist))
        !           376:        (rplaca (cadr block) nil)
        !           377:        t))
        !           378: 
        !           379: 
        !           380: ; vi: set lisp:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.