Annotation of researchv10no/cmd/sml/src/env/env.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: structure Env : ENV =
                      3: struct
                      4:   open PrintUtil ErrorMsg Symbol Access (* also uses: IntStrMap, Basics *)
                      5:   type binding = Basics.binding
                      6: 
                      7:   type info = {path: int list, strenv: Basics.strenv}
                      8:   type symtable = binding IntStrMap.intstrmap
                      9:   type key = int * string
                     10: 
                     11:   val debugLook = System.Control.debugLook
                     12:   val debugCollect = System.Control.debugCollect
                     13: 
                     14:   val defaultInfo = {path = []:int list, strenv = Basics.DIR}
                     15: 
                     16:   fun name(_,s) = s
                     17: 
                     18:   exception Unbound
                     19:        and Unboundrec
                     20:   exception UnboundTable = System.Unsafe.Assembly.UnboundTable
                     21: 
                     22:   datatype 'a locality = LOCAL of 'a | GLOBAL of 'a
                     23: 
                     24:   datatype env
                     25:     = TBL of
                     26:        {info: info, table: symtable, prev: env ref, isopen: bool}
                     27:     | REC of env ref
                     28:     | STR of env ref
                     29:     | NIL
                     30: 
                     31:   fun prevEnv(TBL{prev,...}) = prev
                     32:     | prevEnv(REC prev) = prev
                     33:     | prevEnv(STR prev) = prev
                     34:     | prevEnv _ = impossible "prevEnv"
                     35: 
                     36:   fun printEnv(TBL{prev,...}) = (print "TBL\n  "; printEnv(!prev))
                     37:     | printEnv(REC prev) = (print "REC\n  "; printEnv(!prev))
                     38:     | printEnv(STR prev) = (print "STR\n  "; printEnv(!prev))
                     39:     | printEnv(NIL) = ()
                     40: 
                     41:   fun printEnvs(e) = (print "Env:\n  "; printEnv e)
                     42: 
                     43:   fun eqEnv(NIL,NIL) = true
                     44:     | eqEnv(REC r, REC r') = r = r'
                     45:     | eqEnv(STR r, STR r') = r = r'
                     46:     | eqEnv(TBL{prev=r,...}, TBL{prev=r',...}) = r = r'
                     47:     | eqEnv _ = false
                     48: 
                     49:   fun appenv f (newenv,oldenv) =
                     50:       let fun loop env =
                     51:          if eqEnv(env,oldenv)
                     52:          then ()
                     53:          else case env
                     54:                 of TBL{table,prev=ref env',...} => (IntStrMap.app f table; loop env')
                     55:                  | REC(ref env') => loop env'
                     56:                  | STR(ref env') => loop env'
                     57:                  | NIL => ()
                     58:        in loop newenv
                     59:       end
                     60: 
                     61:  (* the global variable containing the current environment *)
                     62:   val env = ref(NIL)
                     63:   fun current() = !env
                     64: 
                     65:   fun closeCurrentNewEnv() =
                     66:       case current()
                     67:        of TBL{info,table,prev,isopen=true} =>
                     68:            TBL{info=info,table=table,prev=prev,isopen=false}
                     69:         | _ => impossible "Env.closeCurrentNewEnv()"
                     70: 
                     71:   fun newTable() = IntStrMap.new(32, UnboundTable) : symtable
                     72: 
                     73:   fun openOld (info: info, table: symtable) : unit =
                     74:       env := TBL{info=info, table=table, prev=ref(!env), isopen=false}
                     75: 
                     76:   fun openNew (info: info, table: symtable) : unit =
                     77:       env := TBL{info=info, table=table, prev=ref(!env), isopen=true}
                     78: 
                     79:   fun openRec () : unit = 
                     80:       env := REC(ref(!env))
                     81: 
                     82:   fun openStr () : unit =
                     83:       env := STR(ref(!env))
                     84: 
                     85:   fun popSTR(STR(ref e)) = e
                     86:     | popSTR(TBL{prev=ref e,...}) = popSTR e
                     87:     | popSTR(REC(ref e)) = popSTR e
                     88:     | popSTR NIL = impossible "popSTR"
                     89: 
                     90:   fun closeStr () = env := popSTR(!env)
                     91: 
                     92:   fun openScope () : env = 
                     93:       let val oldenv = !env
                     94:        in env := TBL{info=defaultInfo,table=newTable(),prev=ref oldenv,isopen=true};
                     95:          oldenv
                     96:       end
                     97: 
                     98:   fun resetEnv (e) = env := e
                     99: 
                    100:   fun add (binder) =
                    101:       case !env
                    102:        of TBL{table,isopen=true,...} => IntStrMap.add table binder
                    103:         | e =>
                    104:             let val table = newTable() : symtable
                    105:              in IntStrMap.add table binder;
                    106:                 env := TBL{info=defaultInfo,table=table,prev=ref e,isopen=true}
                    107:             end
                    108: 
                    109:   fun collectTable (collector) = 
                    110:       let fun save (REC(ref e)) = save e
                    111:            | save (TBL{info,table,prev=ref e,...}) =
                    112:                (save e;
                    113:                 IntStrMap.app (fn (binder) => collector(binder,info)) table)
                    114:             | save (STR(ref e)) = env := e
                    115:            | save _ = impossible "Env.collectTable.save"
                    116:        in save(!env)
                    117:       end
                    118: 
                    119:   fun splice (local':env, in':env) = 
                    120:       (* remove bindings between env in' and env local' *)
                    121:       prevEnv(in') := local'
                    122: 
                    123:   fun lookEnv (e:env, (key: key)) =
                    124:       let fun look1 (TBL{info,table,prev=ref e,...}) =
                    125:                ((IntStrMap.map table key, info)
                    126:                 handle UnboundTable => look1 e)
                    127:            | look1 (REC(ref e)) = look1 e
                    128:            | look1 (STR(ref e)) = look1 e
                    129:            | look1 NIL = 
                    130:                (ErrorMsg.flaggedmsg debugLook
                    131:                   ("lookEnv failed (global): "^name(key)^"\n");
                    132:                 raise Unbound)
                    133:        in look1(e)
                    134:       end
                    135: 
                    136:   fun look k = lookEnv (!env, k)
                    137: 
                    138:   fun lookStrLocal (key: key) = 
                    139:       let fun look1 (TBL{info,table,prev=ref e,...}) =
                    140:                     ((IntStrMap.map table key, info)
                    141:                       handle UnboundTable => look1 e)
                    142:            | look1 (REC(ref e)) = look1 e
                    143:            | look1 (STR(ref e)) =
                    144:                (ErrorMsg.flaggedmsg debugLook
                    145:                   ("lookStrLocal failed (structure): "^name(key)^"\n");
                    146:                 raise Unbound)
                    147:            | look1 NIL = 
                    148:                (ErrorMsg.flaggedmsg debugLook
                    149:                   ("lookStrLocal failed (global): "^name(key)^"\n");
                    150:                 raise Unbound)
                    151:        in look1(!env)
                    152:       end
                    153: 
                    154:   fun lookRec (key : key) =
                    155:       (* searches global env for index id
                    156:          marks result as LOCAL or GLOBAL depending on whether binding is
                    157:           found within rec boundary or not
                    158:         used for initial var/con lookup in expressions (namespace=0) *)
                    159:       let fun look1 (TBL{info,table,prev=ref e,...}) =
                    160:                (LOCAL(IntStrMap.map table key, info)
                    161:                 handle UnboundTable => look1 e)
                    162:            | look1 (REC(ref e)) =
                    163:                (GLOBAL(lookEnv(e,key))
                    164:                 handle Unbound => raise Unboundrec)
                    165:            | look1 (STR(ref e)) = look1 e
                    166:            | look1 NIL = 
                    167:                (ErrorMsg.flaggedmsg debugLook
                    168:                   ("lookRec failed : "^name(key)^"\n");
                    169:                 raise Unbound)
                    170:        in look1(!env)
                    171:       end
                    172: 
                    173:   fun lookRecLocal (key: key) = 
                    174:       (* searches global env upto nearest rec boundary
                    175:         used when attempting to patch variables in expressions *)
                    176:       let fun look1 (TBL{info,table,prev=ref e,...}) =
                    177:                ((IntStrMap.map table key, info)
                    178:                 handle UnboundTable => look1 e)
                    179:            | look1 (REC(ref e)) = raise Unboundrec
                    180:            | look1 (STR(ref e)) = look1 e
                    181:            | look1 NIL = raise Unbound
                    182:        in look1(!env)
                    183:       end
                    184: 
                    185:   (* environment management for toplevel loop *)
                    186:   val restoreEnv : env ref = ref NIL
                    187:   fun restore () = resetEnv(!restoreEnv)
                    188:   fun commit () = restoreEnv := openScope()
                    189:   fun previous () = !restoreEnv
                    190: 
                    191:   (* consolidating adjacent open tables *)
                    192:   fun consolidateEnv(e as TBL{table,prev=ref(pre),isopen=true,...}) =
                    193:         (case pre
                    194:           of TBL{isopen=true,...} =>
                    195:                let val ans as (_, adder) = consolidateEnv pre
                    196:                 in IntStrMap.app adder table; ans
                    197:                end
                    198:            | _ => (e,IntStrMap.add table))
                    199:     | consolidateEnv(e) = (e,(fn x => ()))
                    200: 
                    201:   fun consolidate () = 
                    202:       env := let val (x,_) = consolidateEnv(!env) in x end
                    203: 
                    204:   fun foldEnv (f: env * 'a -> 'a) (newenv:env) (oldenv:env) (base:'a) : 'a =
                    205:       if eqEnv(newenv,oldenv)
                    206:       then base
                    207:       else f(newenv, foldEnv f (!(prevEnv newenv)) oldenv base)
                    208: 
                    209:   fun collectEnv(newenv, oldenv) = 
                    210:       foldEnv (fn (TBL{table,...},acc) =>
                    211:                    (IntStrMap.app (IntStrMap.add acc) table; acc)
                    212:                | (REC _,acc) => acc
                    213:                | (STR _,acc) => acc
                    214:                | (NIL,acc)   => acc
                    215:              ) newenv oldenv (newTable())
                    216: 
                    217:   fun reset() = (env := NIL; restoreEnv := NIL)
                    218: 
                    219:   fun popModule(oldenv:env): symtable =
                    220:       (* Extract prefix of environment above oldenv (corresponding
                    221:         to module bindings).  oldenv will normally be pervasiveEnv.
                    222:         Then reset env to savedEnv. *)
                    223:       collectEnv(!env,oldenv)
                    224:             
                    225: end (* EnvFunc *)

unix.superglobalmegacorp.com

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