home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / package.d < prev    next >
Encoding:
Text File  |  1994-10-21  |  112.7 KB  |  2,607 lines

  1. # Package-Verwaltung fⁿr CLISP
  2. # Bruno Haible 21.10.1994
  3.  
  4. #include "lispbibl.c"
  5. #include "arilev0.c" # fⁿr Hashcode-Berechnung
  6.  
  7. # Datenstruktur des Symbols: siehe LISPBIBL.D
  8. # Datenstruktur der Symboltabelle:
  9. # ein Vektor mit 3 Slots:
  10. #   size    Fixnum >0, <2^16, = LΣnge der table
  11. #   table   Vektor der LΣnge size,
  12. #             enthΣlt einzelne Symbole (/= NIL) und Symbollisten
  13. #   count   Anzahl der Symbole in der Table, Fixnum >=0
  14.   #define Symtab_size(symtab)  (TheSvector(symtab)->data[0])
  15.   #define Symtab_table(symtab)  (TheSvector(symtab)->data[1])
  16.   #define Symtab_count(symtab)  (TheSvector(symtab)->data[2])
  17. # Konsistenzregel:
  18. # Zu jedem String gibt es in der Tabelle h÷chstens ein Symbol mit diesem
  19. # Printnamen.
  20.  
  21. # UP: Kreiert eine neue leere Symboltabelle.
  22. # make_symtab(size)
  23. # > size: gewⁿnschte Gr÷▀e der Tabelle (ungerade, >0, <2^16)
  24. # < ergebnis: neue Symboltabelle dieser Gr÷▀e
  25. # kann GC ausl÷sen
  26.   local object make_symtab (uintL size);
  27.   local object make_symtab(size)
  28.     var reg2 uintL size;
  29.     { var reg3 object table = allocate_vector(size); # Vektor mit size NIL-EintrΣgen
  30.       pushSTACK(table);
  31.      {var reg1 object symtab = allocate_vector(3); # Vektor der LΣnge 3
  32.       Symtab_table(symtab) = popSTACK(); # table einfⁿllen
  33.       Symtab_size(symtab) = fixnum(size); # size einfⁿllen
  34.       Symtab_count(symtab) = Fixnum_0; # count := 0 einfⁿllen
  35.       return symtab;
  36.     }}
  37.  
  38. # UP: berechnet den Hashcode eines Strings. Dies ist eine 16-Bit-Zahl.
  39. # string_hashcode(string)
  40. # > string: ein String.
  41. # < ergebnis: der Hashcode des Strings
  42.   local uint16 string_hashcode (object string);
  43.   local uint16 string_hashcode(string)
  44.     var reg5 object string;
  45.     { var uintL len;
  46.       var reg2 uintB* charptr = unpack_string(string,&len);
  47.       # ab charptr kommen len Zeichen
  48.       var reg1 uint32 hashcode = 0; # Hashcode, nur die unteren 16 Bit sind wesentlich
  49.       var reg3 uintC count;
  50.       dotimesC(count, (len>16 ? 16 : len), # min(len,16) mal:
  51.         { # hashcode um 5 Bit nach links rotieren:
  52.           hashcode = hashcode << 5; hashcode = hashcode | high16(hashcode);
  53.           # und nΣchstes Byte dazuXORen:
  54.           hashcode = hashcode ^ (uint32)(*charptr++);
  55.         });
  56.       return (uint16)hashcode;
  57.     }
  58.  
  59. # UP: Reorganisiert eine Symboltabelle, nachdem sie gewachsen ist, und
  60. # versucht dabei Conses zu sparen.
  61. # rehash_symtab(symtab)
  62. # > symtab: Symboltabelle
  63. # < ergebnis: reorganisierte Symboltabelle (EQ zur ersten).
  64. # nur bei gesetzter BREAK_SEM_2 aufzurufen
  65. # kann GC ausl÷sen
  66.   local object rehash_symtab (object symtab);
  67.   #
  68.   # Hilfsfunktionen:
  69.   #
  70.   # Entnimmt ein Cons aus free-conses oder liefert ein frisches.
  71.   # new_cons()
  72.   # < ergebnis: neues Cons.
  73.   # Stackaufbau: free-conses, newtable, listr, symbol, entry.
  74.   # kann GC ausl÷sen
  75.     local object new_cons (void);
  76.     local object new_cons()
  77.       { var reg1 object free = STACK_4; # free-conses
  78.         if (!nullp(free))
  79.           { STACK_4 = Cdr(free); # free-conses verkⁿrzen
  80.             return free;
  81.           }
  82.           else
  83.           { return allocate_cons(); } # neues Cons aus der Speicherverwaltung anfordern
  84.       }
  85.   #
  86.   # Fⁿgt ein Symbol zusΣtzlich in die neue Tabelle ein.
  87.   # newinsert(sym,size);
  88.   # > sym: Symbol
  89.   # Stackaufbau: tab, oldtable, free-conses, newtable, listr.
  90.   # kann GC ausl÷sen
  91.     local void newinsert (object sym, uintWL size);
  92.     local void newinsert(sym,size)
  93.       var reg4 object sym;
  94.       var reg5 uintWL size;
  95.       { var reg2 uintL index = # Index = Hashcode mod size
  96.                        (uintL)(string_hashcode(Symbol_name(sym)) % size);
  97.         var reg3 object entry = TheSvector(STACK_1)->data[index]; # entry in der newtable
  98.         if ((!nullp(entry)) || nullp(sym))
  99.           # Ist entry=NIL und sym/=NIL, so ist einfach sym einzutragen.
  100.           # Sonst mu▀ entry durch Consen erweitert werden:
  101.           { pushSTACK(sym); # Symbol retten
  102.             pushSTACK(entry); # entry retten
  103.             if (!listp(entry))
  104.               # Falls entry keine Liste ist, durch (new-cons entry NIL) ersetzen:
  105.               { var reg1 object new_entry = new_cons();
  106.                 Cdr(new_entry) = NIL; Car(new_entry) = STACK_0;
  107.                 STACK_0 = new_entry;
  108.               }
  109.             # und Symbol davorconsen:
  110.             { var reg1 object new_entry = new_cons();
  111.               Cdr(new_entry) = popSTACK(); # entry bzw. Liste als CDR eintragen
  112.               Car(new_entry) = popSTACK(); # Symbol als CAR eintragen
  113.               sym = new_entry; # und dann new_entry eintragen
  114.           } }
  115.         TheSvector(STACK_1)->data[index] = sym; # neue Entry in newtable eintragen
  116.       }
  117.   #
  118.   local object rehash_symtab(symtab)
  119.     var reg6 object symtab;
  120.     { pushSTACK(symtab); # Symboltabelle retten
  121.      {var reg5 uintL oldsize = posfixnum_to_L(Symtab_size(symtab)); # alte Gr÷▀e
  122.       var reg6 uintL newsize; # neue Gr÷▀e
  123.       var reg4 object size; # neue Gr÷▀e (als Fixnum)
  124.       pushSTACK(Symtab_table(symtab)); # oldtable = alter Tabellenvektor
  125.       pushSTACK(NIL); # free-conses := NIL
  126.       # neue Gr÷▀e = min(floor(oldsize*1.6),65535)
  127.       { # multipliziere oldsize (>0, <2^16) mit 1.6*2^15, dann durch 2^15 :
  128.         var reg1 uint32 prod = mulu16(oldsize,52429UL);
  129.         newsize = (prod < (1UL<<31) ? prod>>15 : (1UL<<16)-1 );
  130.       } # newsize ist jetzt >= oldsize > 0 und < 2^16
  131.       # newsize durch Abrunden ungerade machen:
  132.       newsize = (newsize - 1) | 1 ;
  133.       # size berechnen:
  134.       size = fixnum(newsize);
  135.       # Bei newsize <= oldsize braucht die Tabelle nicht vergr÷▀ert zu werden:
  136.       if (newsize <= oldsize) { skipSTACK(3); return symtab; }
  137.       { var reg1 object newtable = allocate_vector(newsize); # neuer Vektor mit size NILs
  138.         pushSTACK(newtable); # retten
  139.       }
  140.       # Hier k÷nnte man gegen Unterbrechungen schⁿtzen.
  141.       # Stackaufbau: tab, oldtable, free-conses, newtable.
  142.       # Symbole von oldtable nach newtable ⁿbertragen:
  143.         # Erst die Symbole verarbeiten, die auf Listen sitzen
  144.         # (dabei werden evtl. Conses frei):
  145.         { var reg3 object* offset = 0; # offset = sizeof(object)*index
  146.           var reg2 uintC count;
  147.           dotimespC(count,oldsize,
  148.             { var reg1 object oldentry = # Eintrag mit Nummer index in oldtable
  149.                   *(object*)(pointerplus(&TheSvector(STACK_2)->data[0],(aint)offset));
  150.               if (consp(oldentry)) # diesmal nur nichtleere Symbollisten verarbeiten
  151.                 do { pushSTACK(Cdr(oldentry)); # Restliste retten
  152.                      Cdr(oldentry) = STACK_2; STACK_2 = oldentry; # oldentry vor free-conses consen
  153.                      newinsert(Car(oldentry),newsize); # Symbol in die neue Tabelle eintragen
  154.                      oldentry = popSTACK(); # Restliste
  155.                    }
  156.                    while (consp(oldentry));
  157.               offset++;
  158.             });
  159.         }
  160.         # Dann die Symbole verarbeiten, die kollisionsfrei dasitzen:
  161.         { var reg3 object* offset = 0; # offset = sizeof(object)*index
  162.           var reg2 uintC count;
  163.           dotimespC(count,oldsize,
  164.             { var reg1 object oldentry = # Eintrag mit Nummer index in oldtable
  165.                   *(object*)(pointerplus(&TheSvector(STACK_2)->data[0],(aint)offset));
  166.               if (!(listp(oldentry))) # diesmal nur Symbole /= NIL verarbeiten
  167.                 { pushSTACK(oldentry); # Dummy, damit der Stack stimmt
  168.                   newinsert(oldentry,newsize); # in die neue Tabelle eintragen
  169.                   skipSTACK(1);
  170.                 }
  171.               offset++;
  172.             });
  173.         }
  174.         # Stackaufbau: tab, oldtable, free-conses, newtable.
  175.       # tab aktualisieren:
  176.       { var reg1 object newtable = popSTACK(); # newtable
  177.         skipSTACK(2);
  178.         symtab = popSTACK(); # tab
  179.         Symtab_size(symtab) = size;
  180.         Symtab_table(symtab) = newtable;
  181.       }
  182.       # Hier k÷nnte man Unterbrechungen wieder zulassen.
  183.       return symtab;
  184.     }}
  185.  
  186. # UP: Sucht ein Symbol gegebenen Printnamens in einer Symboltabelle.
  187. # symtab_lookup(string,symtab,&sym)
  188. # > string: String
  189. # > symtab: Symboltabelle
  190. # < ergebnis: TRUE falls gefunden, FALSE falls nicht gefunden.
  191. # falls gefunden:
  192. #   < sym: das Symbol aus der Symboltabelle, das den gegebenen Printnamen hat
  193.   local boolean symtab_lookup (object string, object symtab, object* sym_);
  194.   local boolean symtab_lookup(string,symtab,sym_)
  195.     var reg3 object string;
  196.     var reg4 object symtab;
  197.     var reg5 object* sym_;
  198.     { var reg2 uintL index = # Index = Hashcode mod size
  199.           (uintL)(string_hashcode(string) % (uintW)(posfixnum_to_L(Symtab_size(symtab))));
  200.       var reg1 object entry = TheSvector(Symtab_table(symtab))->data[index]; # entry in der table
  201.       if (!(listp(entry)))
  202.         # entry ist ein einzelnes Symbol
  203.         { # erster String und Printname des gefundenen Symbols gleich ?
  204.           if (string_gleich(string,Symbol_name(entry)))
  205.             { *sym_ = entry; return TRUE; }
  206.             else
  207.             { return FALSE; }
  208.         }
  209.         else
  210.         # entry ist eine Symbolliste
  211.         { while (consp(entry))
  212.             { # erster String und Printname des Symbols gleich ?
  213.               if (string_gleich(string,Symbol_name(Car(entry)))) { goto found; }
  214.               entry = Cdr(entry);
  215.             }
  216.           { return FALSE; } # nicht gefunden
  217.           found: # gefunden als CAR von entry
  218.           { *sym_ = Car(entry); return TRUE; }
  219.         }
  220.     }
  221.  
  222. # UP: Sucht ein gegebenes Symbol in einer Symboltabelle.
  223. # symtab_find(sym,symtab)
  224. # > sym: Symbol
  225. # > symtab: Symboltabelle
  226. # < ergebnis: TRUE wenn gefunden
  227.   local boolean symtab_find (object sym, object symtab);
  228.   local boolean symtab_find(sym,symtab)
  229.     var reg3 object sym;
  230.     var reg4 object symtab;
  231.     { var reg2 uintL index = # Index = Hashcode mod size
  232.           (uintL)(string_hashcode(Symbol_name(sym)) % (uintW)(posfixnum_to_L(Symtab_size(symtab))));
  233.       var reg1 object entry = TheSvector(Symtab_table(symtab))->data[index]; # entry in der table
  234.       if (!(listp(entry)))
  235.         # entry ist ein einzelnes Symbol
  236.         { # sym und gefundenes Symbol gleich ?
  237.           if (eq(sym,entry)) { return TRUE; } else { return FALSE; }
  238.         }
  239.         else
  240.         # entry ist eine Symbolliste
  241.         { while (consp(entry))
  242.             { # sym und Symbol aus entry gleich ?
  243.               if (eq(sym,Car(entry))) { goto found; }
  244.               entry = Cdr(entry);
  245.             }
  246.           { return FALSE; } # nicht gefunden
  247.           found: # gefunden als CAR von entry
  248.           { return TRUE; }
  249.         }
  250.     }
  251.  
  252. # UP: Fⁿgt ein gegebenes Symbol in eine Symboltabelle ein (destruktiv).
  253. # symtab_insert(sym,symtab)
  254. # > sym: Symbol
  255. # > symtab: Symboltabelle
  256. # < ergebnis: neue Symboltabelle, EQ zur alten
  257. # nur bei gesetzter BREAK_SEM_2 aufzurufen
  258. # kann GC ausl÷sen
  259.   local object symtab_insert (object sym, object symtab);
  260.   local object symtab_insert(sym,symtab)
  261.     var reg4 object sym;
  262.     var reg3 object symtab;
  263.     { # erst der Test, ob Reorganisieren n÷tig ist:
  264.       { var reg1 uintL size = posfixnum_to_L(Symtab_size(symtab));
  265.         var reg2 uintL count = posfixnum_to_L(Symtab_count(symtab));
  266.         # Bei count>=2*size mu▀ die Tabelle reorganisiert werden:
  267.         if (count >= 2*size)
  268.           { pushSTACK(sym); # Symbol retten
  269.             symtab = rehash_symtab(symtab);
  270.             sym = popSTACK();
  271.           }
  272.       }
  273.       # Dann das Symbol einfⁿgen:
  274.      {var reg2 uintL index = # Index = Hashcode mod size
  275.           (uintL)(string_hashcode(Symbol_name(sym)) % (uintW)(posfixnum_to_L(Symtab_size(symtab))));
  276.       var reg1 object entry = TheSvector(Symtab_table(symtab))->data[index]; # entry in der table
  277.       if ((!(nullp(entry))) || (nullp(sym)))
  278.         # Ist entry=NIL und sym/=NIL, so ist einfach sym einzutragen.
  279.         # Sonst mu▀ entry durch Consen erweitert werden:
  280.         { pushSTACK(symtab); # symtab retten
  281.           pushSTACK(sym); # Symbol retten
  282.           pushSTACK(entry); # entry retten
  283.           if (!(listp(entry)))
  284.             # Falls entry keine Liste ist, durch (cons entry NIL) ersetzen:
  285.             { var reg1 object new_entry = allocate_cons();
  286.               Car(new_entry) = STACK_0;
  287.               STACK_0 = new_entry;
  288.             }
  289.           # und Symbol davorconsen:
  290.           { var reg1 object new_entry = allocate_cons();
  291.             Cdr(new_entry) = popSTACK(); # entry bzw. Liste als CDR eintragen
  292.             Car(new_entry) = popSTACK(); # Symbol als CAR eintragen
  293.             sym = new_entry; # und dann new_entry eintragen
  294.           }
  295.           symtab = popSTACK();
  296.         }
  297.       TheSvector(Symtab_table(symtab))->data[index] = sym; # neue Entry eintragen
  298.       Symtab_count(symtab) = fixnum_inc(Symtab_count(symtab),1); # (incf count)
  299.       return symtab;
  300.     }}
  301.  
  302. # UP: Entfernt aus einer Symboltabelle ein darin vorkommendes Symbol.
  303. # symtab_delete(sym,symtab)
  304. # > sym: Symbol
  305. # > symtab: Symboltabelle
  306.   local void symtab_delete (object sym, object symtab);
  307.   local void symtab_delete(sym,symtab)
  308.     var reg3 object sym;
  309.     var reg4 object symtab;
  310.     { var reg2 uintL index = # Index = Hashcode mod size
  311.           (uintL)(string_hashcode(Symbol_name(sym)) % (uintW)(posfixnum_to_L(Symtab_size(symtab))));
  312.       var reg2 object* entryptr = &TheSvector(Symtab_table(symtab))->data[index];
  313.       var reg1 object entry = *entryptr; # entry in der table
  314.       if (!(listp(entry)))
  315.         # entry ist ein einzelnes Symbol
  316.         { # sym und gefundenes Symbol gleich ?
  317.           if (!eq(sym,entry)) { goto notfound; }
  318.           # entry durch NIL ersetzen:
  319.           *entryptr = NIL;
  320.         }
  321.         else
  322.         # entry ist eine Symbolliste
  323.         { while (consp(entry))
  324.             { # sym und Symbol aus entry gleich ?
  325.               if (eq(sym,Car(entry))) { goto found; }
  326.               entryptr = &Cdr(entry); entry = *entryptr;
  327.             }
  328.           goto notfound; # nicht gefunden
  329.           found: # gefunden als CAR von *entryptr = entry
  330.                  # -> ein Listenelement streichen:
  331.           { *entryptr = Cdr(entry); } # entry durch Cdr(entry) ersetzen
  332.         }
  333.       # schlie▀lich noch den SymbolzΣhler um 1 erniedrigen:
  334.       Symtab_count(symtab) = fixnum_inc(Symtab_count(symtab),-1); # (decf count)
  335.       return;
  336.       # nicht gefunden
  337.       notfound:
  338.         pushSTACK(unbound); # "Wert" fⁿr Slot PACKAGE von PACKAGE-ERROR
  339.         pushSTACK(sym);
  340.         fehler(package_error,
  341.                DEUTSCH ? "Symbol ~ kann nicht aus der Symboltabelle entfernt werden." :
  342.                ENGLISH ? "symbol ~ cannot be deleted from symbol table" :
  343.                FRANCAIS ? "Le symbole ~ ne peux pas Ωtre retirΘ de la table des symboles." :
  344.                ""
  345.               );
  346.     }
  347.  
  348. # Datenstruktur der Package siehe LISPBIBL.D.
  349. # Komponenten:
  350. # pack_external_symbols   Symboltabelle der extern prΣsenten Symbole
  351. # pack_internal_symbols   Symboltabelle der intern prΣsenten Symbole
  352. # pack_shadowing_symbols  Liste der Shadowing-Symbole
  353. # pack_use_list           Use-List, eine Liste von Packages
  354. # pack_used_by_list       Used-by-List, eine Liste von Packages
  355. # pack_name               der Name, ein Simple-String
  356. # pack_nicknames          die Nicknames, eine Liste von Simple-Strings
  357.  
  358. # Konsistenzregeln:
  359. # 1. Alle Packages sind genau einmal in ALL_PACKAGES aufgefⁿhrt.
  360. # 2. Die Vereinigung ⁿber ALL_PACKAGES von {Name} U Nicknames ist disjunkt.
  361. # 3. Fⁿr je zwei Packages p,q gilt:
  362. #    p in use_list(q) <==> q in used_by_list(q)
  363. # 4. p sei eine Package.
  364. #    accessible(p) = ISymbols(p) U ESymbols(p) U
  365. #                    U {ESymbols(q) | q in use_list(p)}
  366. # 5. Fⁿr jede Package p ist
  367. #    shadowing_symbols(p)  eine Teilmenge von  ISymbols(p) U ESymbols(p)
  368. #    und damit auch eine Teilmenge von  accessible(p).
  369. # 6. s sei ein String, p eine Package.
  370. #    Ist die Menge der Symbole in accessible(p) mit dem Printnamen = s
  371. #    mehr als einelementig,
  372. #    so liegt genau eines dieser Symbole in shadowing_symbols(p).
  373. # 7. s sei ein String, p eine Package.
  374. #    Es gibt h÷chstens ein Symbol mit dem Printnamen = s
  375. #    in  ISymbols(p) U ESymbols(p)  .
  376. # 8. Ist s ein Symbol mit der Home-Package p /= NIL,
  377. #    so ist s in  ISymbols(p) U ESymbols(p)  enthalten.
  378.  
  379. # UP: Erzeugt eine neue Package, ohne auf Namenskonflikte zu testen.
  380. # make_package(name,nicknames)
  381. # > name: Name (ein Simple-String)
  382. # > nicknames: Nicknames (eine Liste von Simple-Strings)
  383. # < ergebnis: neue Package
  384. # kann GC ausl÷sen
  385.   local object make_package (object name, object nicknames);
  386.   local object make_package(name,nicknames)
  387.     var reg3 object name;
  388.     var reg4 object nicknames;
  389.     { set_break_sem_2();
  390.       pushSTACK(nicknames); pushSTACK(name); # Nicknames und Namen retten
  391.       # Tabelle fⁿr externe Symbole erzeugen:
  392.       { var reg1 object symtab = make_symtab(11); pushSTACK(symtab); }
  393.       # Tabelle fⁿr interne Symbole erzeugen:
  394.       { var reg1 object symtab = make_symtab(63); pushSTACK(symtab); }
  395.       # neue Package erzeugen:
  396.       { var reg1 object pack = allocate_package();
  397.         # und fⁿllen:
  398.         ThePackage(pack)->pack_internal_symbols = popSTACK();
  399.         ThePackage(pack)->pack_external_symbols = popSTACK();
  400.         ThePackage(pack)->pack_shadowing_symbols = NIL;
  401.         ThePackage(pack)->pack_use_list = NIL;
  402.         ThePackage(pack)->pack_used_by_list = NIL;
  403.         ThePackage(pack)->pack_name = popSTACK();
  404.         ThePackage(pack)->pack_nicknames = popSTACK();
  405.         # und in ALL_PACKAGES einhΣngen:
  406.         pushSTACK(pack);
  407.        {var reg2 object new_cons = allocate_cons();
  408.         pack = popSTACK();
  409.         Car(new_cons) = pack; Cdr(new_cons) = O(all_packages);
  410.         O(all_packages) = new_cons;
  411.         # fertig:
  412.         clr_break_sem_2();
  413.         return pack;
  414.     } }}
  415.  
  416. # UP: Sucht ein Symbol gegebenen Printnamens in der Shadowing-Liste einer
  417. # Package.
  418. # shadowing_lookup(string,pack,&sym)
  419. # > string: String
  420. # > pack: Package
  421. # < ergebnis: TRUE, falls gefunden.
  422. # < sym: das Symbol aus der Shadowing-Liste, das den gegebenen Printnamen hat
  423. #        (falls gefunden)
  424.   local boolean shadowing_lookup (object string, object pack, object* sym_);
  425.   local boolean shadowing_lookup(string,pack,sym_)
  426.     var reg2 object string;
  427.     var reg4 object pack;
  428.     var reg3 object* sym_;
  429.     { var reg1 object list = ThePackage(pack)->pack_shadowing_symbols;
  430.       # Shadowing-Liste durchlaufen:
  431.       while (consp(list))
  432.         { if (string_gleich(string,Symbol_name(Car(list)))) { goto found; }
  433.           list = Cdr(list);
  434.         }
  435.       return FALSE; # nicht gefunden
  436.       found: # gefunden
  437.         *sym_ = Car(list); return TRUE;
  438.     }
  439.  
  440. # UP: Sucht ein gegebenes Symbol in der Shadowing-Liste einer Package.
  441. # shadowing_find(sym,pack)
  442. # > sym: Symbol
  443. # > pack: Package
  444. # < ergebnis: TRUE falls gefunden.
  445.   local boolean shadowing_find (object sym, object pack);
  446.   local boolean shadowing_find(sym,pack)
  447.     var reg2 object sym;
  448.     var reg3 object pack;
  449.     { var reg1 object list = ThePackage(pack)->pack_shadowing_symbols;
  450.       # Shadowing-Liste durchlaufen:
  451.       while (consp(list))
  452.         { if (eq(sym,Car(list))) { goto found; }
  453.           list = Cdr(list);
  454.         }
  455.       return FALSE; # nicht gefunden
  456.       found: # gefunden
  457.         return TRUE;
  458.     }
  459.  
  460. # UP: Fⁿgt ein Symbol zur Shadowing-Liste einer Package, die noch kein
  461. # Symbol desselben Namens enthΣlt, hinzu.
  462. # shadowing_insert(&sym,&pack)
  463. # > sym: Symbol (im STACK)
  464. # > pack: Package (im STACK)
  465. # < sym: Symbol, EQ zum alten
  466. # < pack: Package, EQ zur alten
  467. # kann GC ausl÷sen
  468.   local void shadowing_insert (object* sym_, object* pack_);
  469.   local void shadowing_insert(sym_,pack_)
  470.     var reg2 object* sym_;
  471.     var reg3 object* pack_;
  472.     { # neues Cons mit Symbol als CAR vor die Shadowing-Symbols einhΣngen:
  473.       var reg1 object new_cons = allocate_cons();
  474.       var reg2 object pack = *pack_;
  475.       Car(new_cons) = *sym_;
  476.       Cdr(new_cons) = ThePackage(pack)->pack_shadowing_symbols;
  477.       ThePackage(pack)->pack_shadowing_symbols = new_cons;
  478.     }
  479.  
  480. # UP: Entfernt ein Symbol gegebenen Namens aus der Shadowing-Liste
  481. # einer Package.
  482. # shadowing_delete(string,pack)
  483. # > string: String
  484. # > pack: Package
  485.   local void shadowing_delete (object string, object pack);
  486.   local void shadowing_delete(string,pack)
  487.     var reg3 object string;
  488.     var reg4 object pack;
  489.     { var reg2 object* listptr = &ThePackage(pack)->pack_shadowing_symbols;
  490.       var reg1 object list = *listptr;
  491.       # list = *listptr durchlΣuft die Shadowing-Liste
  492.       while (consp(list))
  493.         { if (string_gleich(string,Symbol_name(Car(list)))) { goto found; }
  494.           listptr = &Cdr(list); list = *listptr;
  495.         }
  496.       # kein Symbol dieses Namens gefunden, fertig.
  497.       return;
  498.       found:
  499.         # Gleichheit: entfernen. Danach ist man fertig, da es in der
  500.         # Shadowing-Liste nur ein Symbol desselben Printnamens geben kann.
  501.         *listptr = Cdr(list); # list durch Cdr(list) ersetzen
  502.         return;
  503.     }
  504.  
  505. # UP: testet, ob ein Symbol in einer Package accessible ist und dabei nicht
  506. # von einem anderen Symbol desselben Namens verdeckt wird.
  507. # accessiblep(sym,pack)
  508. # > sym: Symbol
  509. # > pack: Package
  510. # < ergebnis: TRUE falls sym in pack accessible und nicht verdeckt ist,
  511. #             FALSE sonst
  512.   global boolean accessiblep (object sym, object pack);
  513.   global boolean accessiblep(sym,pack)
  514.     var reg2 object sym;
  515.     var reg3 object pack;
  516.     { # Methode:
  517.       # Suche erst ein Symbol gleichen Namens in der Shadowing-Liste;
  518.       # falls nicht gefunden, suche das Symbol unter den prΣsenten und dann
  519.       # unter den vererbten Symbolen.
  520.       # Andere m÷gliche Methode (hier nicht realisiert):
  521.       # Ist die Home-Package von sym gleich pack, so ist sym in pack prΣsent,
  522.       # fertig. Sonst suche ein prΣsentes Symbol gleichen Namens.
  523.       # sym gefunden -> fertig.
  524.       # Ein anderes gefunden -> sym ist nicht auf der Shadowing-Liste und
  525.       # daher nicht sichtbar.
  526.       # Keins gefunden -> Suche sym unter den vererbten Symbolen.
  527.       var object shadowingsym;
  528.       # Suche erst in der Shadowing-Liste von pack:
  529.       if (shadowing_lookup(Symbol_name(sym),pack,&shadowingsym))
  530.         { # shadowingsym = in der Shadowing-Liste gefundenes Symbol
  531.           return (eq(shadowingsym,sym)); # mit sym vergleichen
  532.         }
  533.         else
  534.         # Kein Symbol gleichen Namens in der Shadowing-Liste
  535.         { # Suche unter den internen Symbolen:
  536.           if (symtab_find(sym,ThePackage(pack)->pack_internal_symbols))
  537.             goto found;
  538.           # Suche unter den externen Symbolen:
  539.           if (symtab_find(sym,ThePackage(pack)->pack_external_symbols))
  540.             goto found;
  541.           # Suche unter den externen Symbolen der Packages aus der Use-List:
  542.           { var reg1 object list = ThePackage(pack)->pack_use_list;
  543.             while (consp(list))
  544.               { if (symtab_find(sym,ThePackage(Car(list))->pack_external_symbols))
  545.                   goto found;
  546.                 list = Cdr(list);
  547.               }
  548.             return FALSE; # nicht gefunden
  549.           }
  550.           found: # gefunden
  551.             return TRUE;
  552.     }   }
  553.  
  554. # UP: testet, ob ein Symbol in einer Package als externes Symbol accessible
  555. # ist.
  556. # externalp(sym,pack)
  557. # > sym: Symbol
  558. # > pack: Package
  559. # < ergebnis:
  560. #     TRUE falls sym in pack als externes Symbol accessible ist,
  561. #     (in diesem Falle ist sym nicht verdeckt, denn ein eventuell sym
  562. #      vedeckendes Symbol mⁿ▀te in shadowing-symbols(pack) aufgefⁿhrt sein,
  563. #      nach den Konsistenzregeln 5 und 7 also mit sym identisch sein),
  564. #     FALSE sonst
  565.   global boolean externalp (object sym, object pack);
  566.   global boolean externalp(sym,pack)
  567.     var reg2 object sym;
  568.     var reg1 object pack;
  569.     { return symtab_find(sym,ThePackage(pack)->pack_external_symbols); }
  570.  
  571. # UP: sucht ein externes Symbol gegebenen Printnamens in einer Package.
  572. # find_external_symbol(string,pack,&sym)
  573. # > string: String
  574. # > pack: Package
  575. # < ergebnis: TRUE, falls ein externes Symbol dieses Printnamens in pack gefunden.
  576. # < sym: dieses Symbol, falls gefunden.
  577.   global boolean find_external_symbol (object string, object pack, object* sym_);
  578.   global boolean find_external_symbol(string,pack,sym_)
  579.     var reg2 object string;
  580.     var reg3 object pack;
  581.     var reg1 object* sym_;
  582.     { return symtab_lookup(string,ThePackage(pack)->pack_external_symbols,&(*sym_)); }
  583.  
  584. # UP: Nachfragefunktion an den Benutzer.
  585. # query_user(ml)
  586. # > ml: nichtleere Liste von M÷glichkeiten. Jede M÷glichkeit ist dabei eine
  587. #       Liste aus einem Kurz-String (den der Benutzer eintippen soll), einem
  588. #       Langstring (der der ErlΣuterung dient) und weiteren Informationen.
  589. # < ergebnis: Die vom Benutzer angewΣhlte M÷glichkeit.
  590. # kann GC ausl÷sen
  591.   local object query_user (object ml);
  592.   local object query_user(ml)
  593.     var reg5 object ml;
  594.     { pushSTACK(ml);
  595.      {var object stream = var_stream(S(query_io)); # Stream *QUERY-IO*
  596.       terpri(&stream); # Neue Zeile
  597.       write_sstring(&stream,OL(query_string1)); # "WΣhlen Sie bitte aus:"
  598.       # M÷glichkeiten ausgeben:
  599.       { var reg2 object mlistr = STACK_0; # restliche M÷glichkeiten
  600.         while (consp(mlistr))
  601.           { pushSTACK(mlistr);
  602.             terpri(&stream);
  603.             write_sstring(&stream,O(query_string2)); # "          "
  604.             { var reg1 object moeglichkeit = Car(STACK_0); # nΣchste M÷glichkeit
  605.               pushSTACK(Car(Cdr(moeglichkeit))); # Langstring retten
  606.               write_string(&stream,Car(moeglichkeit)); # Kurzstring ausgeben
  607.               write_sstring(&stream,O(query_string3)); # "  --  "
  608.               write_string(&stream,popSTACK()); # Langstring ausgeben
  609.             }
  610.             mlistr = popSTACK();
  611.             mlistr = Cdr(mlistr);
  612.       }   }
  613.       terpri(&stream);
  614.       terpri(&stream);
  615.       # Benutzer-Antwort einlesen:
  616.       loop
  617.         { write_sstring(&stream,O(query_string7)); # "> "
  618.           pushSTACK(stream); # Stream retten
  619.           pushSTACK(stream); funcall(L(read_line),1); # (READ-LINE stream) aufrufen
  620.           pushSTACK(value1); # Antwort retten
  621.           # Stackaufbau: M÷glichkeiten, Stream, Antwort
  622.             # Antwort mit den Kurzstrings vergleichen:
  623.             pushSTACK(STACK_2); # M÷glichkeiten durchgehen
  624.             while (mconsp(STACK_0))
  625.               { pushSTACK(Car(Car(STACK_0))); # nΣchsten Kurzstring
  626.                 pushSTACK(STACK_2); # mit Antwort vergleichen:
  627.                 funcall(L(string_gleich),2); # (STRING= Kurzstring Antwort)
  628.                 if (!nullp(value1)) goto antwort_ok;
  629.                 STACK_0 = Cdr(STACK_0); # M÷glichkeitenliste verkⁿrzen
  630.               }
  631.             skipSTACK(1);
  632.             # Antwort mit den Kurzstrings vergleichen, diesmal lascher:
  633.             pushSTACK(STACK_2); # M÷glichkeiten durchgehen
  634.             while (mconsp(STACK_0))
  635.               { pushSTACK(Car(Car(STACK_0))); # nΣchsten Kurzstring
  636.                 pushSTACK(STACK_2); # mit Antwort vergleichen:
  637.                 funcall(L(string_equal),2); # (STRING-EQUAL Kurzstring Antwort)
  638.                 if (!nullp(value1)) goto antwort_ok;
  639.                 STACK_0 = Cdr(STACK_0); # M÷glichkeitenliste verkⁿrzen
  640.               }
  641.             skipSTACK(1);
  642.           skipSTACK(1); # Antwort vergessen
  643.           stream = popSTACK(); # Stream zurⁿck
  644.           # bis jetzt immer noch keine korrekte Antwort
  645.           write_sstring(&stream,OL(query_string4)); # "WΣhlen Sie bitte eines von "
  646.           # M÷glichkeiten ausgeben:
  647.           { var reg2 object mlistr = STACK_0; # restliche M÷glichkeiten
  648.             while (consp(mlistr))
  649.               { pushSTACK(mlistr);
  650.                 write_string(&stream,Car(Car(mlistr))); # Kurzstring ausgeben
  651.                 mlistr = popSTACK();
  652.                 mlistr = Cdr(mlistr);
  653.                 if (atomp(mlistr)) break;
  654.                 pushSTACK(mlistr);
  655.                 write_sstring(&stream,O(query_string5)); # ", "
  656.                 mlistr = popSTACK();
  657.           }   }
  658.           write_sstring(&stream,OL(query_string6)); # " aus."
  659.           terpri(&stream);
  660.         }
  661.       antwort_ok:
  662.       { var reg1 object mlistr = popSTACK(); # letzte M÷glichkeitenliste
  663.         skipSTACK(3); # Antwort, Stream und M÷glichkeitenliste vergessen
  664.         return Car(mlistr); # angewΣhlte M÷glichkeit
  665.     }}}
  666.  
  667. # UP: sucht eine Package mit gegebenem Namen oder Nickname
  668. # find_package(string)
  669. # > string: String
  670. # < ergebnis: Package mit diesem Namen oder NIL
  671.   global object find_package (object string);
  672.   global object find_package(string)
  673.     var reg2 object string;
  674.     { var reg4 object packlistr = O(all_packages); # Package-Liste durchgehen
  675.       var reg3 object pack;
  676.       while (consp(packlistr))
  677.         { pack = Car(packlistr); # zu testende Package
  678.           # Teste Namen:
  679.           if (string_gleich(string,ThePackage(pack)->pack_name)) goto found;
  680.           # Teste Nicknamen:
  681.           { var reg1 object nicknamelistr = ThePackage(pack)->pack_nicknames; # Nickname-Liste durchgehen
  682.             while (consp(nicknamelistr))
  683.               { if (string_gleich(string,Car(nicknamelistr))) goto found;
  684.                 nicknamelistr = Cdr(nicknamelistr);
  685.           }   }
  686.           packlistr = Cdr(packlistr); # nΣchste Package
  687.         }
  688.       # nicht gefunden
  689.       return NIL;
  690.       found: # gefunden
  691.         return pack;
  692.     }
  693.  
  694. # UP: Sucht ein Symbol gegebenen Printnamens in einer Package.
  695. # find_symbol(string,pack,&sym)
  696. # > string: String
  697. # > pack: Package
  698. # < sym: Symbol, falls gefunden; sonst NIL
  699. # < ergebnis: 0, wenn nicht gefunden
  700. #             1, wenn als externes Symbol vorhanden
  701. #             2, wenn vererbt ⁿber use-list
  702. #             3, wenn als internes Symbol vorhanden
  703. #         + (-4, wenn in der Shadowing-Liste vorhanden)
  704.   local sintBWL find_symbol (object string, object pack, object* sym_);
  705.   local sintBWL find_symbol(string,pack,sym_)
  706.     var reg4 object string;
  707.     var reg5 object pack;
  708.     var reg3 object* sym_;
  709.     { # Suche erst in der Shadowing-Liste von pack:
  710.       if (shadowing_lookup(string,pack,&(*sym_)))
  711.         # *sym_ = in der Shadowing-Liste gefundenes Symbol
  712.         { # Suche es unter den internen Symbolen:
  713.           if (symtab_find(*sym_,ThePackage(pack)->pack_internal_symbols))
  714.             { return 3-4; } # unter den internen Symbolen gefunden
  715.           # Suche es unter den externen Symbolen:
  716.           if (symtab_find(*sym_,ThePackage(pack)->pack_external_symbols))
  717.             { return 1-4; } # unter den externen Symbolen gefunden
  718.           # Widerspruch zur Konsistenzregel 5.
  719.           pushSTACK(*sym_); pushSTACK(pack);
  720.           fehler(serious_condition,
  721.                  DEUTSCH ? "Inkonsistenz in ~ : Symbol ~ ist zwar unter SHADOWING-SYMBOLS vorhanden, aber nicht prΣsent." :
  722.                  ENGLISH ? "~ inconsistent: symbol ~ is a shadowing symbol but not present" :
  723.                  FRANCAIS ? "Inconsistence dans ~ : Le symbole ~ est ΘnumΘrΘ parmi les SHADOWING-SYMBOLS mais n'est pas prΘsent." :
  724.                  ""
  725.                 );
  726.         }
  727.         else
  728.         # Symbol noch nicht gefunden
  729.         { # Suche unter den internen Symbolen:
  730.           if (symtab_lookup(string,ThePackage(pack)->pack_internal_symbols,&(*sym_)))
  731.             { return 3; } # unter den internen Symbolen gefunden
  732.           # Suche unter den externen Symbolen:
  733.           if (symtab_lookup(string,ThePackage(pack)->pack_external_symbols,&(*sym_)))
  734.             { return 1; } # unter den externen Symbolen gefunden
  735.           # Suche unter den externen Packages aus der Use-List:
  736.           { var reg2 object packlistr = ThePackage(pack)->pack_use_list;
  737.             while (consp(packlistr))
  738.               { var reg1 object usedpack = Car(packlistr);
  739.                 if (symtab_lookup(string,ThePackage(usedpack)->pack_external_symbols,&(*sym_)))
  740.                   { return 2; } # unter den vererbten Symbolen gefunden
  741.                   # (nur einmal vererbt, sonst wΣre was in der
  742.                   #  Shadowing-Liste gewesen)
  743.                 packlistr = Cdr(packlistr);
  744.           }   }
  745.           # nicht gefunden
  746.           *sym_ = NIL; return 0;
  747.     }   }
  748.     # Eigentlich brΣuchte man in der Shadowing-Liste erst zu suchen, nachdem
  749.     # man die prΣsenten Symbole abgesucht hat, denn das Symbol in der
  750.     # Shadowing-Liste ist ja prΣsent (Konsistenzregel 5).
  751.  
  752. # UP: Fⁿgt ein Symbol in eine Package ein, in der noch kein Symbol desselben
  753. # Namens existiert. Achtet nicht auf Konflikte.
  754. # make_present(sym,pack);
  755. # > sym: Symbol
  756. # > pack: Package
  757. # nur bei gesetzter BREAK_SEM_2 aufzurufen
  758. # kann GC ausl÷sen
  759.   local void make_present (object sym, object pack);
  760.   local void make_present(sym,pack)
  761.     var reg1 object sym;
  762.     var reg2 object pack;
  763.     { if (!eq(pack,O(keyword_package)))
  764.         # Symbol in die internen Symbole einfⁿgen:
  765.         { symtab_insert(sym,ThePackage(pack)->pack_internal_symbols); }
  766.         else
  767.         # Symbol modifizieren und in die externen Symbole einfⁿgen:
  768.         { Symbol_value(sym) = sym; # sym erhΣlt sich selbst als Wert
  769.           # als konstant und als Keyword markieren:
  770.           TheSymbol(sym)->header_flags |= (bit(constant_bit_hf) | bit(keyword_bit_hf));
  771.           symtab_insert(sym,ThePackage(pack)->pack_external_symbols);
  772.     }   }
  773.  
  774. # UP: Interniert ein Symbol gegebenen Printnamens in einer Package.
  775. # intern(string,pack,&sym)
  776. # > string: String
  777. # > pack: Package
  778. # < sym: Symbol
  779. # < ergebnis: 0, wenn nicht gefunden, sondern neu erzeugt
  780. #             1, wenn als externes Symbol vorhanden
  781. #             2, wenn vererbt ⁿber use-list
  782. #             3, wenn als internes Symbol vorhanden
  783. # kann GC ausl÷sen
  784.   global uintBWL intern (object string, object pack, object* sym_);
  785.   global uintBWL intern(string,pack,sym_)
  786.     var reg3 object string;
  787.     var reg4 object pack;
  788.     var reg2 object* sym_;
  789.     { { var reg1 sintBWL ergebnis = find_symbol(string,pack,&(*sym_)); # suchen
  790.         if (!(ergebnis==0)) { return ergebnis & 3; } # gefunden -> fertig
  791.       }
  792.       pushSTACK(pack); # Package retten
  793.       string = coerce_imm_ss(string); # String in immutablen Simple-String umwandeln
  794.      {var reg1 object sym = make_symbol(string); # (make-symbol string) ausfⁿhren
  795.       pack = popSTACK();
  796.       # dieses neue Symbol in die Package eintragen:
  797.       set_break_sem_2(); # Vor Unterbrechungen schⁿtzen
  798.       Symbol_package(sym) = pack; # Home-Package eintragen
  799.       pushSTACK(sym); # Symbol retten
  800.       make_present(sym,pack); # und in diese internieren
  801.       *sym_ = popSTACK();
  802.       clr_break_sem_2(); # Unterbrechungen wieder zulassen
  803.       return 0;
  804.     }}
  805.  
  806. # UP: Interniert ein Symbol gegebenen Printnamens in der Keyword-Package.
  807. # intern_keyword(string)
  808. # > string: String
  809. # < ergebnis: Symbol, ein Keyword
  810. # kann GC ausl÷sen
  811.   global object intern_keyword (object string);
  812.   global object intern_keyword(string)
  813.     var reg1 object string;
  814.     { var object sym;
  815.       intern(string,O(keyword_package),&sym);
  816.       return sym;
  817.     }
  818.  
  819. # UP: Importiert ein Symbol in eine Package und macht es zum Shadowing-Symbol.
  820. # Eventuell wird dazu ein anderes in dieser Package prΣsentes Symbol
  821. # desselben Namens uninterniert.
  822. # shadowing_import(&sym,&pack);
  823. # > sym: Symbol (im STACK)
  824. # > pack: Package (im STACK)
  825. # < sym: Symbol, EQ zum alten
  826. # < pack: Package, EQ zur alten
  827. # kann GC ausl÷sen
  828.   local void shadowing_import (object* sym_, object* pack_);
  829.   local void shadowing_import(sym_,pack_)
  830.     var reg3 object* sym_;
  831.     var reg4 object* pack_;
  832.     { set_break_sem_2(); # Vor Unterbrechungen schⁿtzen
  833.      {var reg2 object sym = *sym_;
  834.       var reg1 object pack = *pack_;
  835.       # Suche ein internes oder ein externes Symbol gleichen Namens:
  836.       var object othersym;
  837.       var reg5 boolean i_found;
  838.       var reg6 object string = Symbol_name(sym);
  839.       pushSTACK(string); # String retten
  840.       if ( (i_found = symtab_lookup(string,ThePackage(pack)->pack_internal_symbols,&othersym))
  841.            || (symtab_lookup(string,ThePackage(pack)->pack_external_symbols,&othersym))
  842.          )
  843.         # ein Symbol othersym desselben Namens war schon prΣsent in der Package
  844.         { if (!eq(othersym,sym)) # war es das zu importierende Symbol selbst?
  845.             { # Nein -> mu▀ othersym aus den internen bzw. aus den externen
  846.               # Symbolen herausnehmen:
  847.               symtab_delete(othersym,
  848.                             i_found ? ThePackage(pack)->pack_internal_symbols
  849.                                     : ThePackage(pack)->pack_external_symbols
  850.                            );
  851.               # Wurde dieses Symbol aus seiner Home-Package herausgenommen,
  852.               # so mu▀ seine Home-Package auf NIL gesetzt werden:
  853.               if (eq(Symbol_package(othersym),pack))
  854.                 { Symbol_package(othersym) = NIL; }
  855.               # Symbol sym mu▀ in die Package pack neu aufgenommen werden.
  856.               make_present(sym,pack);
  857.         }   }
  858.         else
  859.         # Symbol sym mu▀ in die Package pack neu aufgenommen werden.
  860.         make_present(sym,pack);
  861.      }
  862.       # Symbol mu▀ in die Shadowing-Liste der Package aufgenommen werden.
  863.       shadowing_delete(popSTACK(),*pack_); # String aus der Shadowing-Liste herausnehmen
  864.       shadowing_insert(&(*sym_),&(*pack_)); # Symbol dafⁿr in die Shadowing-Liste aufnehmen
  865.       clr_break_sem_2(); # Unterbrechungen wieder zulassen
  866.     }
  867.  
  868. # UP: ▄berdeckt in einer Package alle aus anderen Packages accessiblen
  869. # Symbole gegebenen Namens durch ein in dieser Package prΣsentes Symbol
  870. # desselben Namens.
  871. # shadow(&sym,&pack)
  872. #ifdef X3J13_161
  873. # > sym: Symbol oder String (im STACK)
  874. #else
  875. # > sym: Symbol (im STACK)
  876. #endif
  877. # > pack: Package (im STACK)
  878. # < pack: Package, EQ zur alten
  879. # kann GC ausl÷sen
  880.   local void shadow (object* sym_, object* pack_);
  881.   local void shadow(sym_,pack_)
  882.     var reg2 object* sym_;
  883.     var reg3 object* pack_;
  884.     { set_break_sem_2(); # Vor Unterbrechungen schⁿtzen
  885.      {# Suche ein internes oder ein externes Symbol gleichen Namens:
  886.       var reg4 object string = # Nur der Name des Symbols interessiert.
  887.         #ifdef X3J13_161
  888.         (msymbolp(*sym_) ? Symbol_name(*sym_) : coerce_imm_ss(*sym_));
  889.         #else
  890.         Symbol_name(*sym_);
  891.         #endif
  892.       var reg1 object pack = *pack_;
  893.       pushSTACK(NIL); # Platz fⁿr othersym machen
  894.       pushSTACK(string); # String retten
  895.       if (!(symtab_lookup(string,ThePackage(pack)->pack_internal_symbols,&STACK_1)
  896.             || symtab_lookup(string,ThePackage(pack)->pack_external_symbols,&STACK_1)
  897.          ) )
  898.         # nicht gefunden -> neues Symbol desselben Namens erzeugen:
  899.         { var reg1 object othersym = make_symbol(STACK_0); # neues Symbol
  900.           STACK_1 = othersym;
  901.           make_present(othersym,*pack_); # in die Package eintragen
  902.           Symbol_package(STACK_1) = *pack_; # Home-Package des neuen Symbols sei pack
  903.      }  }
  904.       # Stackaufbau: othersym, string
  905.       # In der Package ist nun das Symbol othersym desselben Namens prΣsent.
  906.       shadowing_delete(popSTACK(),*pack_); # String aus der Shadowing-Liste herausnehmen
  907.       shadowing_insert(&STACK_0,&(*pack_)); # othersym dafⁿr in die Shadowing-Liste aufnehmen
  908.       skipSTACK(1); # othersym vergessen
  909.       clr_break_sem_2(); # Unterbrechungen wieder zulassen
  910.     }
  911.  
  912. # UP: Entfernt ein Symbol aus der Menge der prΣsenten Symbole einer Package
  913. # und sorgt fⁿr Konfliktaufl÷sung fⁿr den Fall, da▀ es in der Shadowing-List
  914. # dieser Package war und deswegen ein Namenskonflikt entsteht.
  915. # unintern(&sym,&pack)
  916. # > sym: Symbol (im STACK)
  917. # > pack: Package (im STACK)
  918. # < sym: Symbol, EQ zum alten
  919. # < pack: Package, EQ zur alten
  920. # < ergebnis: T wenn gefunden und gel÷scht, NIL falls nichts getan.
  921. # kann GC ausl÷sen
  922.   local object unintern (object* sym_, object* pack_);
  923.   local object unintern(sym_,pack_)
  924.     var reg3 object* sym_;
  925.     var reg4 object* pack_;
  926.     { var reg2 object sym = *sym_;
  927.       var reg1 object pack = *pack_;
  928.       var reg5 object symtab;
  929.       # sym unter den internen und den externen Symbolen suchen:
  930.       if (symtab_find(sym,symtab=ThePackage(pack)->pack_internal_symbols)
  931.           || symtab_find(sym,symtab=ThePackage(pack)->pack_external_symbols)
  932.          )
  933.         { # Symbol sym in der Tabelle symtab gefunden
  934.           if (shadowing_find(sym,pack)) # in der Shadowing-Liste suchen
  935.             # m÷glicher Konflikt -> Auswahlliste aufbauen:
  936.             { pushSTACK(symtab); # Symboltabelle retten
  937.               pushSTACK(NIL); # M÷glichkeitenliste anfangen
  938.               pushSTACK(ThePackage(pack)->pack_use_list); # Use-List durchgehen
  939.               # Stackaufbau: Symboltabelle, ML, Use-List-Rest
  940.               while (mconsp(STACK_0))
  941.                 { var object othersym;
  942.                   pack = Car(STACK_0); # Package aus der Use-List
  943.                   STACK_0 = Cdr(STACK_0);
  944.                   # vererbtes Symbol gleichen Namens suchen:
  945.                   if (symtab_lookup(Symbol_name(*sym_),ThePackage(pack)->pack_external_symbols,&othersym))
  946.                     # othersym ist ein Symbol gleichen Namens, aus pack vererbt
  947.                     { var reg1 object temp;
  948.                       pushSTACK(temp=ThePackage(pack)->pack_name); # Name von pack
  949.                       pushSTACK(othersym); # Symbol
  950.                        pushSTACK(OL(unint_string1)); # "Symbol "
  951.                        pushSTACK(Symbol_name(othersym)); # Symbolname
  952.                        pushSTACK(OL(unint_string2)); # " aus #<PACKAGE "
  953.                        pushSTACK(temp); # Packagename
  954.                        pushSTACK(OL(unint_string3)); # "> wird als Shadowing deklariert"
  955.                        temp = string_concat(5); # (STRING-CONCAT "..." Symbolname "..." Packagename "...")
  956.                       pushSTACK(temp); # Gesamtstring
  957.                       temp = allocate_cons(); Car(temp) = STACK_1;
  958.                       STACK_1 = temp; # (list othersym)
  959.                       temp = allocate_cons(); Car(temp) = popSTACK(); Cdr(temp) = popSTACK();
  960.                       pushSTACK(temp); # (list Gesamtstring othersym)
  961.                       temp = allocate_cons(); Cdr(temp) = popSTACK(); Car(temp) = popSTACK();
  962.                       # temp = (list Packagename Gesamtstring othersym)
  963.                       # STACK stimmt wieder
  964.                       # auf die M÷glichkeitenliste pushen:
  965.                       pushSTACK(temp);
  966.                       temp = allocate_cons();
  967.                       Car(temp) = popSTACK(); Cdr(temp) = STACK_1;
  968.                       STACK_1 = temp;
  969.                 }   }
  970.               skipSTACK(1);
  971.               # M÷glichkeitenliste fertig aufgebaut.
  972.               # Stackaufbau: Symboltabelle, ML
  973.               # Falls (length ML) >= 2, liegt ein Konflikt vor:
  974.               if (mconsp(STACK_0) && mconsp(Cdr(STACK_0)))
  975.                 # Continuable Error ausl÷sen:
  976.                 { pushSTACK(OL(unint_string4)); # "Sie dⁿrfen auswΣhlen..."
  977.                   pushSTACK(OL(unint_string5)); # "Durch Uninternieren von ~S aus ~S ..."
  978.                   pushSTACK(*sym_); # Symbol
  979.                   pushSTACK(*pack_); # Package
  980.                   funcall(S(cerror),4); # (CERROR "..." "..." Symbol Package)
  981.                   STACK_0 = query_user(STACK_0); # Auswahl erfragen
  982.                 }
  983.                 else
  984.                 { STACK_0 = NIL; }
  985.               # STACK_0 ist die Auswahl (NIL falls kein Konflikt entsteht)
  986.               # Stackaufbau: Symboltabelle, Auswahl
  987.               set_break_sem_3();
  988.               { var reg1 object sym = *sym_;
  989.                 var reg2 object pack = *pack_;
  990.                 # Symbol aus der Symboltabelle entfernen:
  991.                 symtab_delete(sym,STACK_1);
  992.                 # Falls es aus seiner Home-Package entfernt wurde,
  993.                 # setze die Home-Package auf NIL:
  994.                 if (eq(Symbol_package(sym),pack))
  995.                   { Symbol_package(sym) = NIL; }
  996.                 # Symbol aus Shadowing-Liste streichen:
  997.                 shadowing_delete(Symbol_name(sym),pack);
  998.               }
  999.               { var reg1 object auswahl = popSTACK(); # Auswahl
  1000.                 if (!nullp(auswahl))
  1001.                   # im Konfliktfalle: angewΣhltes Symbol importieren:
  1002.                   { pushSTACK(Car(Cdr(Cdr(auswahl))));
  1003.                     shadowing_import(&STACK_0,&(*pack_));
  1004.                     skipSTACK(1);
  1005.               }   }
  1006.               skipSTACK(1); # Symboltabelle vergessen
  1007.               clr_break_sem_3();
  1008.               return T; # Das war's
  1009.             }
  1010.             else
  1011.             # kein Konflikt
  1012.             { set_break_sem_2();
  1013.               symtab_delete(sym,symtab); # Symbol l÷schen
  1014.               if (eq(Symbol_package(sym),pack))
  1015.                 { Symbol_package(sym) = NIL; } # evtl. Home-Package auf NIL setzen
  1016.               clr_break_sem_2();
  1017.               return T;
  1018.             }
  1019.         }
  1020.         else
  1021.         # nicht gefunden
  1022.         { return NIL; }
  1023.     }
  1024.  
  1025. # UP: Importiert ein Symbol in eine Package und sorgt fⁿr Konfliktaufl÷sung
  1026. # fⁿr den Fall, da▀ ein Namenskonflikt entweder mit einem aus einer anderen
  1027. # Package vererbten Symbol oder mit einem bereits in dieser Package prΣsenten
  1028. # Symbol desselben Namens entsteht.
  1029. # import(&sym,&pack);
  1030. # > sym: Symbol (im STACK)
  1031. # > pack: Package (im STACK)
  1032. # < pack: Package, EQ zur alten
  1033. # kann GC ausl÷sen
  1034.   global void import (object* sym_, object* pack_);
  1035.   global void import(sym_,pack_)
  1036.     var reg3 object* sym_;
  1037.     var reg4 object* pack_;
  1038.     { var reg2 object sym = *sym_;
  1039.       var reg1 object pack = *pack_;
  1040.       var reg3 object string = Symbol_name(sym);
  1041.       var object othersym;
  1042.       var reg5 object othersymtab;
  1043.       # Symbol gleichen Namens unter den internen und den externen Symbolen suchen:
  1044.       if (symtab_lookup(string,othersymtab=ThePackage(pack)->pack_internal_symbols,&othersym)
  1045.           || symtab_lookup(string,othersymtab=ThePackage(pack)->pack_external_symbols,&othersym)
  1046.          )
  1047.         # othersym = Symbol desselben Namens, gefunden in othersymtab
  1048.         { if (eq(othersym,sym))
  1049.             # dasselbe Symbol -> nichts tun
  1050.             { return; }
  1051.           # nicht dasselbe Symbol war prΣsent -> mu▀ othersym rauswerfen und
  1052.           # dafⁿr das gegebene Symbol sym reinsetzen.
  1053.           # Zuvor feststellen, ob zusΣtzlich noch vererbte Symbole da sind,
  1054.           # und dann Continuable Error melden.
  1055.           pushSTACK(string);
  1056.           pushSTACK(othersym);
  1057.           pushSTACK(othersymtab);
  1058.           # erst Inherited-Flag berechnen:
  1059.           pushSTACK(ThePackage(pack)->pack_use_list); # Use-List wird abgesucht
  1060.           while (mconsp(STACK_0))
  1061.             { var object otherusedsym;
  1062.               var reg1 object usedpack = Car(STACK_0);
  1063.               STACK_0 = Cdr(STACK_0);
  1064.               # Symbol gleichen Namens in usedpack suchen:
  1065.               if (symtab_lookup(string,ThePackage(usedpack)->pack_external_symbols,&otherusedsym))
  1066.                 { STACK_0 = T; break; } # gefunden -> inherited-Flag := T
  1067.             } # sonst ist am Schlu▀ inherited-Flag = STACK_0 = NIL
  1068.           # Stackaufbau: Symbol-Name, othersym, othersymtab, inherited-Flag.
  1069.           # Continuable Error melden:
  1070.           { pushSTACK(OL(import_string1)); # "Sie dⁿrfen ⁿber das weitere Vorgehen entscheiden."
  1071.             pushSTACK(nullp(STACK_1) # bei inherited=NIL die kurze Meldung
  1072.                       ? OL(import_string2) # "Durch Importieren von ~S in ~S entsteht ein Namenskonflikt mit ~S."
  1073.                       : OL(import_string3) # "Durch Importieren von ~S in ~S ... Namenskonflikt mit ~S und weiteren Symbolen."
  1074.                      );
  1075.             pushSTACK(sym); # Symbol
  1076.             pushSTACK(pack); # Package
  1077.             pushSTACK(STACK_6); # othersym
  1078.             # vom Typ package_error??
  1079.             funcall(S(cerror),5); # (CERROR String1 String2/3 sym pack othersym)
  1080.           }
  1081.           # Antwort vom Benutzer erfragen:
  1082.           { var reg2 object ml = # M÷glichkeitenliste (("I" ... T) ("N" ... NIL))
  1083.                             (nullp(STACK_0) ? OL(import_list1) : OL(import_list2));
  1084.             var reg1 object antwort = query_user(ml);
  1085.             if (nullp(Car(Cdr(Cdr(antwort))))) # NIL-M÷glichkeit angewΣhlt?
  1086.               { skipSTACK(4); return; } # ja -> nicht importieren, fertig
  1087.           }
  1088.           # Importieren:
  1089.           set_break_sem_2();
  1090.           pack = *pack_;
  1091.           # othersym aus pack entfernen:
  1092.           { var reg1 object othersym = STACK_2;
  1093.             symtab_delete(othersym,STACK_1); # othersym aus othersymtab entfernen
  1094.             if (eq(Symbol_package(othersym),pack))
  1095.               { Symbol_package(othersym) = NIL; } # evtl. Home-Package := NIL
  1096.           }
  1097.           # sym in pack einfⁿgen:
  1098.           make_present(*sym_,pack);
  1099.           # Symbole gleichen Namens aus der Shadowing-List von pack entfernen:
  1100.           shadowing_delete(STACK_3,*pack_);
  1101.           # Falls inherited-Flag, sym in pack zum Shadowing-Symbol machen:
  1102.           if (!nullp(STACK_0))
  1103.             { shadowing_insert(&(*sym_),&(*pack_)); }
  1104.           clr_break_sem_2();
  1105.           skipSTACK(4); return;
  1106.         }
  1107.         else
  1108.         # Kein Symbol desselben Namens war prΣsent.
  1109.         # Suche ein Symbol desselben Namens, das vererbt ist (es gibt
  1110.         # nach den Konsistenzregeln 6 und 5 h÷chstens ein solches):
  1111.         { var object otherusedsym;
  1112.           { pushSTACK(ThePackage(pack)->pack_use_list); # Use-List wird abgesucht
  1113.             while (mconsp(STACK_0))
  1114.               { var reg1 object usedpack = Car(STACK_0);
  1115.                 STACK_0 = Cdr(STACK_0);
  1116.                 # Symbol gleichen Namens in usedpack suchen:
  1117.                 if (symtab_lookup(string,ThePackage(usedpack)->pack_external_symbols,&otherusedsym))
  1118.                   goto inherited_found;
  1119.               }
  1120.             skipSTACK(1);
  1121.             # Kein Symbol desselben Namens war accessible.
  1122.             # sym kann daher gefahrlos importiert werden.
  1123.             goto import_sym;
  1124.           }
  1125.           inherited_found: # gefunden.
  1126.             skipSTACK(1);
  1127.             # Wurde genau das gegebene Symbol gefunden?
  1128.             if (eq(otherusedsym,sym))
  1129.               goto import_sym; # ja -> importieren
  1130.             # nein -> Continuable Error melden und Benutzer fragen:
  1131.             { pushSTACK(OL(import_string1)); # "Sie dⁿrfen ⁿber das weitere Vorgehen entscheiden."
  1132.               pushSTACK(OL(import_string2)); # "Durch Importieren von ~S in ~S entsteht ein Namenskonflikt mit ~S."
  1133.               pushSTACK(sym); # Symbol
  1134.               pushSTACK(pack); # Package
  1135.               pushSTACK(otherusedsym); # otherusedsym
  1136.               funcall(S(cerror),5); # (CERROR String1 String2 sym pack otherusedsym)
  1137.             }
  1138.             { var reg1 object antwort = query_user(OL(import_list3));
  1139.               if (nullp(Car(Cdr(Cdr(antwort))))) # NIL-M÷glichkeit angewΣhlt?
  1140.                 { return; } # ja -> nicht importieren, fertig
  1141.             }
  1142.             # Importieren:
  1143.             set_break_sem_2();
  1144.             # sym in pack einfⁿgen:
  1145.             make_present(*sym_,*pack_);
  1146.             # sym in pack zum Shadowing-Symbol machen:
  1147.             shadowing_insert(&(*sym_),&(*pack_));
  1148.             clr_break_sem_2(); return;
  1149.           import_sym:
  1150.             # sym einfach in pack einfⁿgen:
  1151.             set_break_sem_2();
  1152.             make_present(sym,pack);
  1153.             clr_break_sem_2(); return;
  1154.         }
  1155.     }
  1156.  
  1157. # UP: Setzt ein Symbol vom externen auf den internen Status in einer Package
  1158. # zurⁿck.
  1159. # unexport(&sym,&pack);
  1160. # > sym: Symbol (im STACK)
  1161. # > pack: Package (im STACK)
  1162. # < pack: Package, EQ zur alten
  1163. # kann GC ausl÷sen
  1164.   local void unexport (object* sym_, object* pack_);
  1165.   local void unexport(sym_,pack_)
  1166.     var reg3 object* sym_;
  1167.     var reg4 object* pack_;
  1168.     { var reg2 object sym = *sym_;
  1169.       var reg1 object pack = *pack_;
  1170.       var reg3 object symtab;
  1171.       if (symtab_find(sym,symtab=ThePackage(pack)->pack_external_symbols))
  1172.         # sym ist in pack extern
  1173.         { if (eq(pack,O(keyword_package))) # auf Keyword-Package testen
  1174.             { pushSTACK(pack); # Wert fⁿr Slot PACKAGE von PACKAGE-ERROR
  1175.               pushSTACK(pack);
  1176.               fehler(package_error,
  1177.                      DEUTSCH ? "UNEXPORT ist in ~ nicht zulΣssig." :
  1178.                      ENGLISH ? "UNEXPORT in ~ is illegal" :
  1179.                      FRANCAIS ? "UNEXPORT n'est pas permis dans ~." :
  1180.                      ""
  1181.                     );
  1182.             }
  1183.           set_break_sem_2();
  1184.           symtab_delete(sym,symtab); # sym aus den externen Symbolen entfernen
  1185.           symtab_insert(sym,ThePackage(pack)->pack_internal_symbols); # dafⁿr in die internen Symbole einfⁿgen
  1186.           clr_break_sem_2();
  1187.         }
  1188.         else
  1189.         # Suchen, ob das Symbol ⁿberhaupt accessible ist.
  1190.         { # Suche unter den internen Symbolen:
  1191.           if (symtab_find(sym,ThePackage(pack)->pack_internal_symbols))
  1192.             goto found;
  1193.           # Suche unter den externen Symbolen der Packages aus der Use-List:
  1194.           { var reg1 object list = ThePackage(pack)->pack_use_list;
  1195.             while (consp(list))
  1196.               { if (symtab_find(sym,ThePackage(Car(list))->pack_external_symbols))
  1197.                   goto found;
  1198.                 list = Cdr(list);
  1199.           }   }
  1200.           # nicht gefunden unter den accessiblen Symbolen
  1201.           { pushSTACK(pack); # Wert fⁿr Slot PACKAGE von PACKAGE-ERROR
  1202.             pushSTACK(pack); pushSTACK(sym);
  1203.             fehler(package_error,
  1204.                    DEUTSCH ? "UNEXPORT ist nur auf accessiblen Symbolen m÷glich, nicht auf Symbol ~ in ~." :
  1205.                    ENGLISH ? "UNEXPORT works only on accessible symbols, not on ~ in ~" :
  1206.                    FRANCAIS ? "UNEXPORT n'est possible que pour des symboles accessibles mais pas pour le symbole ~ dans ~." :
  1207.                    ""
  1208.                   );
  1209.           }
  1210.           found: # gefunden unter den nicht-externen accessiblen Symbolen
  1211.             return; # nichts zu tun
  1212.     }   }
  1213.  
  1214. # UP: Setzt ein prΣsentes Symbol auf externen Status.
  1215. # make_external(sym,pack);
  1216. # > sym: Symbol
  1217. # > pack: Package, in der das Symbol prΣsent ist
  1218. # kann GC ausl÷sen
  1219.   local void make_external (object sym, object pack);
  1220.   local void make_external(sym,pack)
  1221.     var reg2 object sym;
  1222.     var reg1 object pack;
  1223.     { if (symtab_find(sym,ThePackage(pack)->pack_external_symbols))
  1224.         { return; } # Symbol bereits extern -> nichts zu tun
  1225.       set_break_sem_2();
  1226.       symtab_delete(sym,ThePackage(pack)->pack_internal_symbols); # sym aus den internen Symbolen entfernen
  1227.       symtab_insert(sym,ThePackage(pack)->pack_external_symbols); # dafⁿr in die externen Symbole einfⁿgen
  1228.       clr_break_sem_2();
  1229.     }
  1230.  
  1231. # UP: Exportiert ein Symbol aus einer Package
  1232. # export(&sym,&pack);
  1233. # > sym: Symbol (im STACK)
  1234. # > pack: Package (im STACK)
  1235. # < sym: Symbol, EQ zum alten
  1236. # < pack: Package, EQ zur alten
  1237. # kann GC ausl÷sen
  1238.   global void export (object* sym_, object* pack_);
  1239.   global void export(sym_,pack_)
  1240.     var reg3 object* sym_;
  1241.     var reg4 object* pack_;
  1242.     { var reg2 object sym = *sym_;
  1243.       var reg1 object pack = *pack_;
  1244.       # sym unter den externen Symbolen von pack suchen:
  1245.       if (symtab_find(sym,ThePackage(pack)->pack_external_symbols))
  1246.         { return; } # gefunden -> fertig
  1247.       { var reg6 boolean import_it = FALSE;
  1248.         # import_it = Flag, ob Symbol erst noch importiert werden mu▀.
  1249.         # sym unter den internen Symbolen von pack suchen:
  1250.         if (!(symtab_find(sym,ThePackage(pack)->pack_internal_symbols)))
  1251.           # Symbol sym ist nicht prΣsent in Package pack
  1252.           { import_it = TRUE;
  1253.             # Suche, ob es wenigstens accessible ist:
  1254.             { var reg1 object list = ThePackage(pack)->pack_use_list;
  1255.               while (consp(list))
  1256.                 { if (symtab_find(sym,ThePackage(Car(list))->pack_external_symbols))
  1257.                     goto found;
  1258.                   list = Cdr(list);
  1259.             }   }
  1260.             # Symbol sym ist nicht einmal accessible in der Package pack
  1261.             # Continuable Error melden:
  1262.             { pushSTACK(OL(export_string1)); # "Sie dⁿrfen ⁿber das weitere Vorgehen entscheiden."
  1263.               pushSTACK(OL(export_string2)); # "Symbol ~S mⁿ▀te erst in ~S importiert werden, bevor es exportiert werden kann."
  1264.               pushSTACK(sym); # Symbol
  1265.               pushSTACK(pack); # Package
  1266.               # vom Typ package_error??
  1267.               funcall(S(cerror),4); # (CERROR "Sie dⁿrfen aussuchen, ..." "..." Symbol Package)
  1268.             }
  1269.             # beim Benutzer nachfragen:
  1270.             { var reg1 object antwort = query_user(OL(export_list1));
  1271.               if (nullp(Car(Cdr(Cdr(antwort))))) # NIL-M÷glichkeit angewΣhlt?
  1272.                 { return; } # ja -> nicht exportieren, fertig
  1273.             }
  1274.             found: ;
  1275.           }
  1276.         # Nun auf Namensfonflikte testen:
  1277.         pushSTACK(NIL); # Conflict-Resolver:=NIL
  1278.         # Stackaufbau: Conflict-Resolver (eine Liste von Paaren (sym . pack),
  1279.         #              auf die shadowing_import angewandt werden mu▀).
  1280.         pushSTACK(ThePackage(*pack_)->pack_used_by_list); # Used-By-List wird abgesucht
  1281.         while (mconsp(STACK_0))
  1282.           { var reg1 object usingpack = Car(STACK_0); # USEnde Package
  1283.             STACK_0 = Cdr(STACK_0);
  1284.            {var object othersym;
  1285.             if (find_symbol(Symbol_name(*sym_),usingpack,&othersym) > 0)
  1286.               # othersym ist ein Symbol desselben Namens in usingpack
  1287.               if (!eq(othersym,*sym_))
  1288.                 # es ist nicht sym selbst -> es liegt ein Konflikt vor
  1289.                 { pushSTACK(othersym); pushSTACK(usingpack);
  1290.                   # Stackaufbau: Conflict-Resolver, Used-by-list-Rest,
  1291.                   #              anderes Symbol, USEnde Package.
  1292.                   # Continuable Error melden:
  1293.                   { pushSTACK(OL(export_string3)); # "Sie dⁿrfen aussuchen, welches Symbol Vorrang hat."
  1294.                     pushSTACK(OL(export_string4)); # "Durch Exportieren von ~S aus ~S ... Namenskonflikt mit ~S in ~S."
  1295.                     pushSTACK(*sym_); # Symbol
  1296.                     pushSTACK(*pack_); # Package
  1297.                     pushSTACK(othersym); # anderes Symbol
  1298.                     pushSTACK(usingpack); # USEnde Package
  1299.                     funcall(S(cerror),6); # (CERROR "..." "..." sym pack othersym usingpack)
  1300.                   }
  1301.                   # Einleitung ausgeben:
  1302.                   { var object stream = var_stream(S(query_io)); # Stream *QUERY-IO*
  1303.                     terpri(&stream); # Neue Zeile
  1304.                     write_sstring(&stream,OL(export_string5)); # "Welches Symbol soll in "
  1305.                     prin1(&stream,STACK_0); # usingpack ausgeben
  1306.                     write_sstring(&stream,OL(export_string6)); # " Vorrang haben?"
  1307.                   }
  1308.                   # M÷glichkeitenliste konstruieren:
  1309.                   { var reg1 object temp;
  1310.                      pushSTACK(O(export_string7)); # "1"
  1311.                       pushSTACK(OL(export_string9)); # "Das zu exportierende Symbol "
  1312.                        pushSTACK(*sym_); # Symbol
  1313.                        funcall(L(prin1_to_string),1); # (prin1-to-string Symbol)
  1314.                       pushSTACK(value1);
  1315.                       temp = string_concat(2); # (string-concat "Das zu exportierende Symbol " (prin1-to-string Symbol))
  1316.                      pushSTACK(temp);
  1317.                      pushSTACK(T);
  1318.                      temp = listof(3); # (list "1" (string-concat ...) 'T)
  1319.                     pushSTACK(temp);
  1320.                      pushSTACK(O(export_string8)); # "2"
  1321.                       pushSTACK(OL(export_string10)); # "Das alte Symbol "
  1322.                        pushSTACK(STACK_4); # anderes Symbol
  1323.                        funcall(L(prin1_to_string),1); # (prin1-to-string anderesSymbol)
  1324.                       pushSTACK(value1);
  1325.                       temp = string_concat(2); # (string-concat "Das alte Symbol " (prin1-to-string anderesSymbol))
  1326.                      pushSTACK(temp);
  1327.                      pushSTACK(NIL);
  1328.                      temp = listof(3); # (list "2" (string-concat ...) 'NIL)
  1329.                     pushSTACK(temp);
  1330.                     temp = listof(2); # (list (list "1" ... 'T) (list "2" ... 'NIL))
  1331.                   # Beim Benutzer nachfragen:
  1332.                     { var reg2 object antwort = query_user(temp);
  1333.                       var reg3 object solvingsym =
  1334.                           (!(nullp(Car(Cdr(Cdr(antwort))))) # NIL-M÷glichkeit angewΣhlt?
  1335.                            ? *sym_ # nein -> sym
  1336.                            : STACK_1 # ja -> othersym
  1337.                           );
  1338.                       pushSTACK(solvingsym); # ausgewΣhltes Symbol
  1339.                     }
  1340.                   # Conflict-Resolver um (solvingsym . usingpack) erweitern:
  1341.                     temp = allocate_cons();
  1342.                     Car(temp) = popSTACK(); # solvingsym
  1343.                     Cdr(temp) = popSTACK(); # usingpack
  1344.                     # temp = (cons solvingsym usingpack)
  1345.                     # vor Conflict-Resolver davorconsen:
  1346.                     STACK_0 = temp;
  1347.                     temp = allocate_cons();
  1348.                     Car(temp) = popSTACK(); # (solvingsym . usingpack)
  1349.                     Cdr(temp) = STACK_1;
  1350.                     STACK_1 = temp;
  1351.                   }
  1352.                   # Stackaufbau: Conflict-Resolver, Used-by-list-Rest.
  1353.           }}    }
  1354.         skipSTACK(1);
  1355.         # Stackaufbau: Conflict-Resolver.
  1356.         # Nun evtl. Symbol sym importieren:
  1357.         if (import_it)
  1358.           { # sym in pack importieren:
  1359.             import(&(*sym_),&(*pack_));
  1360.             # Dieses Importieren kann durch einen CERROR abgebrochen werden.
  1361.             # Ein Abbruch an dieser Stelle ist ungefΣhrlich, denn bis jetzt
  1362.             # ist das Symbol nur intern in der Package (au▀er falls es sich
  1363.             # um das KEYWORD-Package handelt, das nicht geUSEd werden kann).
  1364.           }
  1365.         set_break_sem_3(); # gegen Unterbrechungen schⁿtzen
  1366.         # Nun die Konflikte aufl÷sen:
  1367.         while (mconsp(STACK_0))
  1368.           { var reg1 object cons_sym_pack = Car(STACK_0);
  1369.             STACK_0 = Cdr(STACK_0);
  1370.             pushSTACK(Car(cons_sym_pack)); # solvingsym
  1371.             pushSTACK(Cdr(cons_sym_pack)); # usingpack
  1372.             shadowing_import(&STACK_1,&STACK_0); # importieren und shadowen
  1373.             skipSTACK(2);
  1374.           }
  1375.         skipSTACK(1);
  1376.         make_external(*sym_,*pack_); # sym in pack extern machen
  1377.         clr_break_sem_3(); # Unterbrechungen wieder freigeben
  1378.     } }
  1379.  
  1380. # UP: Wendet eine Funktion auf alle Symbole einer Symboltabelle an.
  1381. # (Diese Funktion darf im Extremfall das Symbol mittels symtab_delete
  1382. # aus der Tabelle herausnehmen.)
  1383. # map_symtab(fun,symtab);
  1384. # > fun: Funktion mit einem Argument
  1385. # > symtab: Symboltabelle
  1386. # kann GC ausl÷sen
  1387.   local void map_symtab (object fun, object symtab);
  1388.   local void map_symtab(fun,symtab)
  1389.     var reg5 object fun;
  1390.     var reg4 object symtab;
  1391.     { pushSTACK(fun); # Funktion
  1392.       pushSTACK(Symtab_table(symtab)); # Tabellenvektor
  1393.      {var uintL size = posfixnum_to_L(Symtab_size(symtab)); # Anzahl der EintrΣge
  1394.       var reg3 object* offset = 0; # offset = sizeof(object)*index
  1395.       var reg2 uintC count;
  1396.       dotimespC(count,size,
  1397.         { var reg1 object entry = # Eintrag mit Nummer index in table
  1398.               *(object*)(pointerplus(&TheSvector(STACK_0)->data[0],(aint)offset));
  1399.           if (atomp(entry))
  1400.             { if (!(nullp(entry)))
  1401.                 # entry ist ein Symbol /= NIL
  1402.                 { pushSTACK(entry); funcall(STACK_2,1); } # Funktion anwenden
  1403.             }
  1404.             else
  1405.             # nichtleere Symbolliste abarbeiten
  1406.             { pushSTACK(entry);
  1407.               do { var reg1 object listr = STACK_0;
  1408.                    STACK_0 = Cdr(listr);
  1409.                    pushSTACK(Car(listr)); funcall(STACK_3,1); # Funktion auf Symbol anwenden
  1410.                  }
  1411.                  until (matomp(STACK_0));
  1412.               skipSTACK(1);
  1413.             }
  1414.           offset++;
  1415.         });
  1416.       skipSTACK(2);
  1417.     }}
  1418.  
  1419. # UP: Bewirkt, da▀ alle externen Symbole einer gegebenen Liste von Packages
  1420. # implizit accessible in einer gegebenen Package werden.
  1421. # use_package(packlist,pack);
  1422. # > packlist: Liste von Packages, die zu USEn sind
  1423. # > pack: Package
  1424. # Die Liste packlist wird dabei zerst÷rt!
  1425. # kann GC ausl÷sen
  1426.   local void use_package (object packlist, object pack);
  1427.   local object* use_package_local; # Pointer auf drei lokale Variablen
  1428.   local void use_package(packlist,pack)
  1429.     var object packlist;
  1430.     var reg5 object pack;
  1431.     { # packlist := (delete-duplicates packlist :test #'eq) :
  1432.       { var reg4 object packlist1 = packlist;
  1433.         while (consp(packlist1))
  1434.           { var reg3 object to_delete = Car(packlist1);
  1435.             # Entferne to_delete destruktiv aus (cdr packlist1) :
  1436.             var reg2 object packlist2 = packlist1; # lΣuft ab packlist1
  1437.             var reg1 object packlist3; # stets = (cdr packlist2)
  1438.             while (consp(packlist3=Cdr(packlist2)))
  1439.               { if (eq(Car(packlist3),to_delete))
  1440.                   # streiche (car packlist3) destruktiv aus der Liste:
  1441.                   { Cdr(packlist2) = Cdr(packlist3); }
  1442.                   else
  1443.                   # weiterrⁿcken:
  1444.                   { packlist2 = packlist3; }
  1445.               }
  1446.             packlist1 = Cdr(packlist1);
  1447.       }   }
  1448.       # Entferne aus packlist alle die Packages, die gleich pack sind
  1449.       # oder bereits in der Use-List von pack vorkommen:
  1450.       { var reg4 object* packlistr_ = &packlist;
  1451.         var reg3 object packlistr = *packlistr_;
  1452.         # packlistr lΣuft durch packlist, packlistr = *packlistr_
  1453.         while (consp(packlistr))
  1454.           { # Teste, ob (car packlistr) gestrichen werden mu▀:
  1455.             var reg2 object pack_to_test = Car(packlistr);
  1456.             if (eq(pack_to_test,pack))
  1457.               goto delete_pack_to_test;
  1458.             { var reg1 object usedpacklistr = ThePackage(pack)->pack_use_list;
  1459.               while (consp(usedpacklistr))
  1460.                 { if (eq(pack_to_test,Car(usedpacklistr)))
  1461.                     goto delete_pack_to_test;
  1462.                   usedpacklistr = Cdr(usedpacklistr);
  1463.             }   }
  1464.             if (TRUE)
  1465.               # nichts streichen, weiterrⁿcken:
  1466.               { packlistr_ = &Cdr(packlistr); packlistr = *packlistr_; }
  1467.               else
  1468.               # streiche (car packlistr) :
  1469.               { delete_pack_to_test:
  1470.                 packlistr = *packlistr_ = Cdr(packlistr);
  1471.               }
  1472.       }   }
  1473.       # Konfliktliste aufbauen.
  1474.       # Dabei ist ein Konflikt eine mindestens zweielementige Liste
  1475.       # von Symbolen gleichen Printnamens, zusammen mit der Package,
  1476.       # aus der dieses Symbol genommen wird:
  1477.       # ((pack1 . sym1) ...) bedeutet, da▀ bei Ausfⁿhrung des USE-PACKAGE
  1478.       # die Symbole sym1,... (aus pack1 etc.) sich um die Sichtbarkeit in
  1479.       # Package pack streiten wⁿrden.
  1480.       # Die Konfliktliste ist die Liste aller auftretenden Konflikte.
  1481.       { pushSTACK(pack); # Package pack retten
  1482.         pushSTACK(packlist); # Liste zu USEnder Packages retten
  1483.         pushSTACK(NIL); # (bisher leere) Konfliktliste
  1484.         # Stackaufbau: pack, packlist, conflicts.
  1485.         use_package_local = &STACK_0; # zeigt auf die drei lokalen Variablen
  1486.         # Packageliste durchgehen:
  1487.         { pushSTACK(packlist);
  1488.           while (mconsp(STACK_0))
  1489.             { var reg1 object pack_to_use = Car(STACK_0);
  1490.               STACK_0 = Cdr(STACK_0);
  1491.               # #'use_package_aux auf alle externen Symbole von pack_to_use anwenden:
  1492.               map_symtab(L(use_package_aux),ThePackage(pack_to_use)->pack_external_symbols);
  1493.             }
  1494.           skipSTACK(1);
  1495.         }
  1496.         # Konfliktliste umbauen: Jeder Konflikt ((pack1 . sym1) ...) wird
  1497.         # umgeformt zu (("1" packname1 . sym1) ...).
  1498.         { pushSTACK(STACK_0); # Konfliktliste durchgehen
  1499.           while (mconsp(STACK_0))
  1500.             { var reg4 object conflict = Car(STACK_0);
  1501.               STACK_0 = Cdr(STACK_0);
  1502.               pushSTACK(conflict); # Konflikt durchgehen
  1503.               { var reg5 object counter = Fixnum_0; # ZΣhler := 0
  1504.                 while (mconsp(STACK_0))
  1505.                   {  counter = fixnum_inc(counter,1); # ZΣhler um 1 erh÷hen
  1506.                      pushSTACK(counter); funcall(L(prin1_to_string),1); # (prin1-to-string ZΣhler)
  1507.                      pushSTACK(value1); # ZΣhlerstring retten
  1508.                    { var reg2 object new_cons = allocate_cons(); # neues Cons
  1509.                      Car(new_cons) = popSTACK(); # ZΣhlerstring als CAR
  1510.                     {var reg1 object old_cons = Car(STACK_0); # Cons der Form (pack . sym)
  1511.                      Car(old_cons) = ThePackage(Car(old_cons))->pack_name; # pack durch seinen Namen ersetzen
  1512.                      Cdr(new_cons) = old_cons; Car(STACK_0) = new_cons; # ZΣhlerstring-Cons einfⁿgen
  1513.                    }}
  1514.                      STACK_0 = Cdr(STACK_0);
  1515.               }   }
  1516.               skipSTACK(1);
  1517.             }
  1518.           skipSTACK(1);
  1519.         }
  1520.         # Konflikt-Liste fertig.
  1521.         pushSTACK(NIL); # Conflict-Resolver := NIL
  1522.         # Stackaufbau: pack, packlist, conflicts, conflict-resolver.
  1523.         # Konflikte durch Benutzerfragen behandeln:
  1524.         if (!(nullp(STACK_1))) # nur bei conflicts/=NIL n÷tig
  1525.           { # Continuable Error melden:
  1526.             { pushSTACK(OL(usepack_string1)); # "Sie dⁿrfen bei jedem Konflikt ..."
  1527.               pushSTACK(OL(usepack_string2)); # "~S Namenskonflikte bei USE-PACKAGE von ~S in die Package ~S."
  1528.               pushSTACK(fixnum(llength(STACK_3))); # (length conflicts)
  1529.               pushSTACK(STACK_5); # packlist
  1530.               pushSTACK(STACK_7); # pack
  1531.               funcall(S(cerror),5); # (CERROR "..." "..." (length conflicts) usedpacks pack)
  1532.             }
  1533.             { pushSTACK(STACK_1); # conflicts durchgehen
  1534.               while (mconsp(STACK_0))
  1535.                 { pushSTACK(Car(STACK_0)); # conflict
  1536.                  {var object stream = var_stream(S(query_io)); # Stream *QUERY-IO*
  1537.                   terpri(&stream); # Neue Zeile
  1538.                   write_sstring(&stream,OL(usepack_string3)); # "Welches Symbol mit dem Namen "
  1539.                   # (cdr (cdr (car conflict))) = (cdr (cdr '("1" packname1 . sym1))) = sym1
  1540.                   prin1(&stream,Symbol_name(Cdr(Cdr(Car(STACK_0))))); # Name davon ausgeben
  1541.                   write_sstring(&stream,OL(usepack_string4)); # " soll in "
  1542.                   prin1(&stream,STACK_5); # pack ausgeben
  1543.                   write_sstring(&stream,OL(usepack_string5)); # " Vorrang haben?"
  1544.                  }
  1545.                   # Beim Benutzer nachfragen,
  1546.                   # mit conflict als M÷glichkeitenliste:
  1547.                  {var reg2 object antwort = query_user(popSTACK());
  1548.                   # Davon das Symbol nehmen und in den conflict-resolver stecken:
  1549.                   pushSTACK(Cdr(Cdr(antwort))); # sym
  1550.                  }
  1551.                  {var reg1 object new_cons = allocate_cons();
  1552.                   Car(new_cons) = popSTACK(); # sym
  1553.                   Cdr(new_cons) = STACK_1; # conflict-resolver
  1554.                   STACK_1 = new_cons; # conflict-resolver := (cons sym conflict-resolver)
  1555.                  }
  1556.                   STACK_0 = Cdr(STACK_0); # restliche Konfliktliste verkⁿrzen
  1557.                 }
  1558.               skipSTACK(1);
  1559.           } }
  1560.         # Stackaufbau: pack, packlist, conflicts, conflict-resolver.
  1561.         # Konflikte aufl÷sen:
  1562.         { set_break_sem_3();
  1563.           # conflict-resolver durchgehen:
  1564.           while (mconsp(STACK_0))
  1565.             { pushSTACK(Car(STACK_0)); # Symbol aus conflict-resolver
  1566.               shadowing_import(&STACK_0,&STACK_4); # in pack zum Shadowing-Symbol machen
  1567.               skipSTACK(1);
  1568.               STACK_0 = Cdr(STACK_0);
  1569.             }
  1570.           skipSTACK(2); # conflicts und conflict-resolver vergessen
  1571.           # Stackaufbau: pack, packlist.
  1572.           # packlist durchgehen:
  1573.           while (mconsp(STACK_0))
  1574.             { pushSTACK(Car(STACK_0)); # pack_to_use
  1575.               # pack_to_use auf die Use-List von pack setzen:
  1576.               # (push pack_to_use (package-use-list pack))
  1577.               { var reg1 object new_cons = allocate_cons();
  1578.                 var reg2 object pack = STACK_2;
  1579.                 Car(new_cons) = STACK_0; # pack_to_use
  1580.                 Cdr(new_cons) = ThePackage(pack)->pack_use_list;
  1581.                 ThePackage(pack)->pack_use_list = new_cons;
  1582.               }
  1583.               # pack auf die Used-By-List von pack_to_use setzen:
  1584.               # (push pack (package-used-by-list pack_to_use))
  1585.               { var reg1 object new_cons = allocate_cons();
  1586.                 var reg2 object pack_to_use = popSTACK();
  1587.                 Car(new_cons) = STACK_1; # pack
  1588.                 Cdr(new_cons) = ThePackage(pack_to_use)->pack_used_by_list;
  1589.                 ThePackage(pack_to_use)->pack_used_by_list = new_cons;
  1590.               }
  1591.               STACK_0 = Cdr(STACK_0);
  1592.             }
  1593.           skipSTACK(2); # pack und packlist vergessen
  1594.           clr_break_sem_3();
  1595.     } } }
  1596.  
  1597. # Hilfsfunktion fⁿr use_package:
  1598. # Teste das Argument (ein externes Symbol aus einer der Packages aus
  1599. # packlist), ob es einen Konflikt erzeugt. Wenn ja, erweitere conflicts.
  1600. LISPFUNN(use_package_aux,1)
  1601.   { var reg6 object* localptr = use_package_local;
  1602.     # Pointer auf lokale Variablen von use_package:
  1603.     #   *(localptr STACKop 2) = pack,
  1604.     #   *(localptr STACKop 1) = packlist,
  1605.     #   *(localptr STACKop 0) = conflicts.
  1606.     var reg7 object string = Symbol_name(popSTACK()); # Printname des ⁿbergebenen Symbols
  1607.     # Gibt es einen Konflikt zwischen den Symbolen mit Printname = string ?
  1608.     # Bisherige Konfliktliste (((pack1 . sym1) ...) ...) durchgehen:
  1609.     { var reg1 object conflictsr = *(localptr STACKop 0);
  1610.       while (consp(conflictsr))
  1611.         { # Konflikt schon behandelt?
  1612.           # (car conflictsr) = nΣchster Konflikt,
  1613.           # (car (car conflictsr)) = dessen erstes Cons,
  1614.           # (cdr (car (car conflictsr))) = darin das Symbol,
  1615.           # ist dessen Printname = string ?
  1616.           if (string_gleich(Symbol_name(Cdr(Car(Car(conflictsr)))),string))
  1617.             goto ok;
  1618.           conflictsr = Cdr(conflictsr);
  1619.     }   }
  1620.     pushSTACK(string); # string retten
  1621.     # neuen Konflikt aufbauen:
  1622.     pushSTACK(NIL); # neuer Konflikt (noch leer)
  1623.     # Testen, ob ein gleichnamiges Symbol bereits in pack accessible ist:
  1624.     { var object othersym;
  1625.       var reg2 sintBWL code = find_symbol(STACK_1,*(localptr STACKop 2),&othersym);
  1626.       if (code < 0)
  1627.         # Gleichnamiges Symbol in der Shadowing-Liste verhindert Konflikt.
  1628.         { skipSTACK(2); goto ok; }
  1629.       if (code > 0)
  1630.         # accessible, aber nicht shadowing -> Konflikt um (pack . othersym) erweitern:
  1631.         { pushSTACK(othersym);
  1632.          {var reg1 object temp = allocate_cons();
  1633.           Cdr(temp) = popSTACK(); # othersym
  1634.           Car(temp) = *(localptr STACKop 2); # pack
  1635.           pushSTACK(temp); # (pack . othersym)
  1636.          }
  1637.          {var reg1 object new_cons = allocate_cons();
  1638.           Car(new_cons) = popSTACK(); Cdr(new_cons) = STACK_0;
  1639.           STACK_0 = new_cons;
  1640.     }   }}
  1641.     # Testen, in welchen Packages aus packlist ein gleichnamiges Symbol
  1642.     # extern ist:
  1643.     { var reg3 object packlistr = *(localptr STACKop 1); # packlist durchgehen
  1644.       while (consp(packlistr))
  1645.         { var reg2 object pack_to_use = Car(packlistr);
  1646.           packlistr = Cdr(packlistr);
  1647.           { var object othersym;
  1648.             if (symtab_lookup(STACK_1,ThePackage(pack_to_use)->pack_external_symbols,&othersym))
  1649.               # othersym hat den Printnamen = string und ist extern in pack_to_use.
  1650.               # (pack_to_use . othersym) auf conflict pushen:
  1651.               { pushSTACK(packlistr); # packlistr retten
  1652.                 pushSTACK(pack_to_use);
  1653.                 pushSTACK(othersym);
  1654.                {var reg1 object new_cons = allocate_cons();
  1655.                 Cdr(new_cons) = popSTACK(); Car(new_cons) = popSTACK();
  1656.                 pushSTACK(new_cons); # (cons pack_to_use othersym)
  1657.                }
  1658.                {var reg1 object new_cons = allocate_cons();
  1659.                 Car(new_cons) = popSTACK();
  1660.                 packlistr = popSTACK();
  1661.                 Cdr(new_cons) = STACK_0;
  1662.                 STACK_0 = new_cons; # conflict := (cons (cons pack_to_use othersym) conflict)
  1663.     }   } }   }}
  1664.     { var reg5 object conflict = popSTACK(); # der fertige Konflikt
  1665.       # conflict := (delete-duplicates conflict :key #'cdr :test #'eq):
  1666.       { var reg4 object conflict1 = conflict;
  1667.         while (consp(conflict1))
  1668.           { var reg3 object to_delete = Cdr(Car(conflict1));
  1669.             # Entferne alle Elemente mit CDR=to_delete
  1670.             # destruktiv aus (cdr conflict1) :
  1671.             var reg2 object conflict2 = conflict1; # lΣuft ab conflict1
  1672.             var reg1 object conflict3; # stets = (cdr conflict2)
  1673.             while (consp(conflict3=Cdr(conflict2)))
  1674.               { if (eq(Cdr(Car(conflict3)),to_delete))
  1675.                   # streiche (car conflict3) destruktiv aus der Liste:
  1676.                   { Cdr(conflict2) = Cdr(conflict3); }
  1677.                   else
  1678.                   # weiterrⁿcken:
  1679.                   { conflict2 = conflict3; }
  1680.               }
  1681.             conflict1 = Cdr(conflict1);
  1682.       }   }
  1683.       # Falls conflict eine LΣnge >=2 hat, wird es zu conflicts geconst:
  1684.       if (consp(conflict) && mconsp(Cdr(conflict)))
  1685.         { pushSTACK(conflict);
  1686.          {var reg1 object new_cons = allocate_cons();
  1687.           Car(new_cons) = popSTACK(); # conflict
  1688.           Cdr(new_cons) = *(localptr STACKop 0); # conflicts
  1689.           *(localptr STACKop 0) = new_cons; # conflicts := (cons conflict conflicts)
  1690.         }}
  1691.     }
  1692.     skipSTACK(1); # string vergessen
  1693.     ok: value1 = NIL; mv_count=0; # keine Werte
  1694.   }
  1695.  
  1696. # UP: Bewirkt, da▀ eine gegebene Package nicht mehr von einer (anderen)
  1697. # gegebenen Package geUSEt wird.
  1698. # unuse_1package(pack,qpack);
  1699. # > pack: Package
  1700. # > qpack: Package
  1701. # Entfernt qpack von der Use-List von pack
  1702. # und pack von der Used-By-List von qpack.
  1703.   local void unuse_1package (object pack, object qpack);
  1704.   local void unuse_1package(pack,qpack)
  1705.     var reg1 object pack;
  1706.     var reg2 object qpack;
  1707.     { set_break_sem_2();
  1708.       # qpack aus der Use-List von pack entfernen:
  1709.       ThePackage(pack)->pack_use_list =
  1710.         deleteq(ThePackage(pack)->pack_use_list,qpack);
  1711.       # pack aus der Used-By-List von qpack entfernen:
  1712.       ThePackage(qpack)->pack_used_by_list =
  1713.         deleteq(ThePackage(qpack)->pack_used_by_list,pack);
  1714.       clr_break_sem_2();
  1715.     }
  1716.  
  1717. # UP: Bewirkt, da▀ eine Liste gegebener Packages nicht mehr von einer
  1718. # gegebenen Package geUSEt wird.
  1719. # unuse_package(packlist,pack);
  1720. # > packlist: Liste von Packages
  1721. # > pack: Package
  1722. # Entfernt alle Packages aus packlist von der Use-List von pack
  1723. # und pack von den Used-By-Listen aller Packages aus packlist.
  1724.   local void unuse_package (object packlist, object pack);
  1725.   local void unuse_package(packlist,pack)
  1726.     var reg1 object packlist;
  1727.     var reg2 object pack;
  1728.     { set_break_sem_3();
  1729.       # packlist durchgehen:
  1730.       while (consp(packlist))
  1731.         { unuse_1package(pack,Car(packlist));
  1732.           packlist = Cdr(packlist);
  1733.         }
  1734.       clr_break_sem_3();
  1735.     }
  1736.  
  1737. # UP: liefert die aktuelle Package
  1738. # get_current_package()
  1739. # < ergebnis: aktuelle Package
  1740.   global object get_current_package (void);
  1741.   global object get_current_package()
  1742.     { var reg1 object pack = Symbol_value(S(packagestern)); # Wert von *PACKAGE*
  1743.       if (packagep(pack))
  1744.         { return pack; }
  1745.         else
  1746.         { var reg1 object newpack =
  1747.               Symbol_value(S(packagestern)) = O(default_package); # *PACKAGE* zurⁿcksetzen
  1748.           pushSTACK(pack); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1749.           pushSTACK(S(package)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1750.           pushSTACK(newpack); pushSTACK(pack);
  1751.           fehler(type_error,
  1752.                  DEUTSCH ? "Der Wert von *PACKAGE* war keine Package. Alter Wert: ~. Neuer Wert: ~." :
  1753.                  ENGLISH ? "The value of *PACKAGE* was not a package. Old value ~. New value ~." :
  1754.                  FRANCAIS ? "La valeur de *PACKAGE* n'Θtait pas un paquetage. Ancienne valeur : ~. Nouvelle valeur : ~." :
  1755.                  ""
  1756.                 );
  1757.     }   }
  1758.  
  1759. # UP: ▄berprⁿft ein Package-Argument.
  1760. # Testet, ob es eine Package oder ein Packagename ist, und liefert es als
  1761. # Package zurⁿck. Sonst Fehlermeldung.
  1762. # test_package_arg(obj)
  1763. # > obj: Argument
  1764. # > subr_self: Aufrufer (ein SUBR)
  1765. # < ergebnis: in eine Package umgewandeltes Argument
  1766.   local object test_package_arg (object obj);
  1767.   local object test_package_arg(obj)
  1768.     var reg1 object obj;
  1769.     { if (packagep(obj)) { return obj; } # Package: OK
  1770.       if (stringp(obj))
  1771.         string: # String -> Package mit Namen obj suchen:
  1772.         { var reg2 object pack = find_package(obj);
  1773.           if (!(nullp(pack))) { return pack; }
  1774.           pushSTACK(obj); # Wert fⁿr Slot PACKAGE von PACKAGE-ERROR
  1775.           pushSTACK(obj);
  1776.           fehler(package_error,
  1777.                  DEUTSCH ? "Eine Package mit Namen ~ gibt es nicht." :
  1778.                  ENGLISH ? "There is no package with name ~" :
  1779.                  FRANCAIS ? "Il n'y a pas de paquetage de nom ~." :
  1780.                  ""
  1781.                 );
  1782.         }
  1783.       if (symbolp(obj)) # Symbol ->
  1784.         { obj = Symbol_name(obj); goto string; } # Printnamen verwenden
  1785.       pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1786.       pushSTACK(O(type_packname)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1787.       pushSTACK(obj); pushSTACK(TheSubr(subr_self)->name);
  1788.       fehler(type_error,
  1789.              DEUTSCH ? "Argument zu ~ mu▀ eine Package oder ein Packagename sein, nicht ~" :
  1790.              ENGLISH ? "~: argument should be a package or a package name, not ~" :
  1791.              FRANCAIS ? "L'argument de ~ doit Ωtre un paquetage ou un nom de paquetage et non ~." :
  1792.              ""
  1793.             );
  1794.     }
  1795.  
  1796. LISPFUNN(make_symbol,1) # (MAKE-SYMBOL printname), CLTL S. 168
  1797.   { var reg1 object arg = popSTACK();
  1798.     if (!(stringp(arg)))
  1799.       { pushSTACK(arg); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1800.         pushSTACK(S(string)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1801.         pushSTACK(arg); pushSTACK(TheSubr(subr_self)->name);
  1802.         fehler(type_error,
  1803.                DEUTSCH ? "~: Argument mu▀ ein String sein, nicht ~." :
  1804.                ENGLISH ? "~: argument should be a string, not ~" :
  1805.                FRANCAIS ? "~ : L'argument doit Ωtre une chaεne et non ~." :
  1806.                ""
  1807.               );
  1808.       }
  1809.     # Simple-String draus machen und Symbol bauen:
  1810.     value1 = make_symbol(coerce_imm_ss(arg)); mv_count=1;
  1811.   }
  1812.  
  1813. # UP: ▄berprⁿft ein String/Symbol-Argument
  1814. # > obj: Argument
  1815. # > subr_self: Aufrufer (ein SUBR)
  1816. # < ergebnis: Argument als String
  1817.   local object test_stringsym_arg (object obj);
  1818.   local object test_stringsym_arg(obj)
  1819.     var reg1 object obj;
  1820.     { if (stringp(obj)) return obj; # String: unverΣndert zurⁿck
  1821.       if (symbolp(obj)) return TheSymbol(obj)->pname; # Symbol: Printnamen verwenden
  1822.       pushSTACK(obj); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1823.       pushSTACK(O(type_stringsym)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1824.       pushSTACK(obj); pushSTACK(TheSubr(subr_self)->name);
  1825.       fehler(type_error,
  1826.              DEUTSCH ? "~: Argument mu▀ ein String oder Symbol sein, nicht ~." :
  1827.              ENGLISH ? "~: argument ~ should be a string or a symbol" :
  1828.              FRANCAIS ? "~ : L'argument doit Ωtre un symbole ou une chaεne et non ~." :
  1829.              ""
  1830.             );
  1831.     }
  1832.  
  1833. LISPFUNN(find_package,1) # (FIND-PACKAGE name), CLTL S. 183
  1834.   { var reg1 object name = test_stringsym_arg(popSTACK()); # Argument als String
  1835.     value1 = find_package(name); # Package suchen
  1836.     mv_count=1;
  1837.   }
  1838.  
  1839. LISPFUNN(pfind_package,1) # (SYSTEM::%FIND-PACKAGE name)
  1840.   { value1 = test_package_arg(popSTACK()); # Argument als Package
  1841.     mv_count=1;
  1842.   }
  1843.  
  1844. LISPFUNN(package_name,1) # (PACKAGE-NAME package), CLTL S. 184
  1845.   { var reg1 object pack = test_package_arg(popSTACK()); # Argument als Package
  1846.     value1 = ThePackage(pack)->pack_name; # der Name
  1847.     mv_count=1;
  1848.   }
  1849.  
  1850. LISPFUNN(package_nicknames,1) # (PACKAGE-NICKNAMES package), CLTL S. 184
  1851.   { var reg1 object pack = test_package_arg(popSTACK()); # Argument als Package
  1852.     value1 = copy_list(ThePackage(pack)->pack_nicknames); # Nicknameliste sicherheitshalber kopieren
  1853.     mv_count=1;
  1854.   }
  1855.  
  1856. # UP: ▄berprⁿft name und nicknames - Argumente von RENAME-PACKAGE und MAKE-PACKAGE.
  1857. # Testet, ob STACK_2 ein Name ist, und macht daraus einen Simple-String.
  1858. # Testet, ob STACK_1 ein Name oder eine Liste von Namen ist, und macht
  1859. # daraus eine neue Liste von Simple-Strings.
  1860. # > subr-self: Aufrufer (ein SUBR)
  1861. # kann GC ausl÷sen
  1862.   local void test_names_args (void);
  1863.   local void test_names_args()
  1864.     { # name auf String prⁿfen und zu einem Simple-String machen:
  1865.       STACK_2 = coerce_imm_ss(test_stringsym_arg(STACK_2));
  1866.       # Nickname-Argument in eine Liste umwandeln:
  1867.       { var reg2 object nicknames = STACK_1;
  1868.         if (eq(nicknames,unbound))
  1869.           { STACK_1 = NIL; } # keine Nicknames angegeben -> Default NIL
  1870.           else
  1871.           if (!(listp(nicknames)))
  1872.             { # nicknames keine Liste -> eine einelementige Liste daraus machen:
  1873.               nicknames = allocate_cons();
  1874.               Car(nicknames) = STACK_1;
  1875.               STACK_1 = nicknames;
  1876.       }     }
  1877.       # Nickname(s) auf String prⁿfen, zu Simple-Strings machen
  1878.       # und daraus eine neue Nicknameliste machen:
  1879.       { pushSTACK(NIL); # neue Nicknameliste := NIL
  1880.         while (mconsp(STACK_2))
  1881.           {{var reg1 object nickname = Car(STACK_2); # nΣchster Nickname
  1882.             STACK_2 = Cdr(STACK_2);
  1883.             nickname = coerce_imm_ss(test_stringsym_arg(nickname)); # als Simple-String
  1884.             # vor die neue Nicknameliste consen:
  1885.             pushSTACK(nickname);
  1886.            }
  1887.            {var reg1 object new_cons = allocate_cons();
  1888.             Car(new_cons) = popSTACK();
  1889.             Cdr(new_cons) = STACK_0;
  1890.             STACK_0 = new_cons;
  1891.           }}
  1892.        {var reg1 object nicknames = popSTACK();
  1893.         STACK_1 = nicknames; # neue Nicknameliste ersetzt die alte
  1894.       }}
  1895.     }
  1896.  
  1897. LISPFUN(rename_package,2,1,norest,nokey,0,NIL)
  1898. # (RENAME-PACKAGE pack name [nicknames]), CLTL S. 184
  1899.   { # Testen, ob pack eine Package ist:
  1900.     STACK_2 = test_package_arg(STACK_2);
  1901.     # name und nicknames ⁿberprⁿfen:
  1902.     pushSTACK(NIL); # Dummy auf den Stack
  1903.     test_names_args();
  1904.     skipSTACK(1);
  1905.    {var reg1 object pack = STACK_2;
  1906.     # Teste, ob ein Packagenamenkonflikt entsteht:
  1907.     { var reg3 object name = STACK_1;
  1908.       var reg2 object nicknamelistr = STACK_0;
  1909.       # name durchlΣuft den Namen und alle Nicknames
  1910.       loop
  1911.         { var reg1 object found = find_package(name); # Suche Package mit diesem Namen
  1912.           if (!(nullp(found) || eq(found,pack)))
  1913.             { # gefunden, aber eine andere als die gegebene Package:
  1914.               pushSTACK(pack); # Wert fⁿr Slot PACKAGE von PACKAGE-ERROR
  1915.               pushSTACK(name); pushSTACK(TheSubr(subr_self)->name);
  1916.               fehler(package_error,
  1917.                      DEUTSCH ? "~: Eine Package mit dem Namen ~ gibt es schon." :
  1918.                      ENGLISH ? "~: there is already a package named ~" :
  1919.                      FRANCAIS ? "~ : Il y a dΘjα un paquetage de nom ~." :
  1920.                      ""
  1921.                     );
  1922.             }
  1923.           # Keine oder nur die gegebene Package hat den Namen name ->
  1924.           # kein Konflikt mit diesem (Nick)name, weiter:
  1925.           if (atomp(nicknamelistr)) break;
  1926.           name = Car(nicknamelistr); # nΣchster Nickname
  1927.           nicknamelistr = Cdr(nicknamelistr); # restliche Nicknameliste verkⁿrzen
  1928.     }   }
  1929.     # Es gibt keine Konflikte.
  1930.     set_break_sem_2();
  1931.     ThePackage(pack)->pack_name = STACK_1;
  1932.     ThePackage(pack)->pack_nicknames = STACK_0;
  1933.     clr_break_sem_2();
  1934.     skipSTACK(3);
  1935.     value1 = pack; mv_count=1; # pack als Wert
  1936.   }}
  1937.  
  1938. LISPFUNN(package_use_list,1) # (PACKAGE-USE-LIST package), CLTL S. 184
  1939.   { var reg1 object pack = test_package_arg(popSTACK()); # Argument als Package
  1940.     value1 = copy_list(ThePackage(pack)->pack_use_list); # Use-List sicherheitshalber kopieren
  1941.     mv_count=1;
  1942.   }
  1943.  
  1944. LISPFUNN(package_used_by_list,1) # (PACKAGE-USED-BY-LIST package), CLTL S. 184
  1945.   { var reg1 object pack = test_package_arg(popSTACK()); # Argument als Package
  1946.     value1 = copy_list(ThePackage(pack)->pack_used_by_list); # Used-By-List sicherheitshalber kopieren
  1947.     mv_count=1;
  1948.   }
  1949.  
  1950. LISPFUNN(package_shadowing_symbols,1) # (PACKAGE-SHADOWING-SYMBOLS package), CLTL S. 184
  1951.   { var reg1 object pack = test_package_arg(popSTACK()); # Argument als Package
  1952.     value1 = copy_list(ThePackage(pack)->pack_shadowing_symbols); # Shadowing-Liste sicherheitshalber kopieren
  1953.     mv_count=1;
  1954.   }
  1955.  
  1956. LISPFUNN(list_all_packages,0)
  1957. # (LIST-ALL-PACKAGES) liefert eine Liste aller Packages, CLTL S. 184
  1958.   { value1 = reverse(O(all_packages)); # (Kopie der Liste, sicherheitshalber)
  1959.     mv_count=1;
  1960.   }
  1961.  
  1962. # UP: ▄berprⁿft das letzte Argument &optional (pack *package*) einer
  1963. # LISP-Funktion.
  1964. # test_optional_package_arg()
  1965. # > STACK_0: letztes Argument
  1966. # > subr_self: Aufrufer (ein SUBR)
  1967. # < STACK_0: in eine Package umgewandeltes Argument
  1968.   local void test_optional_package_arg (void);
  1969.   local void test_optional_package_arg()
  1970.     { var reg1 object pack = STACK_0;
  1971.       if (eq(pack,unbound))
  1972.         { STACK_0 = get_current_package(); } # Default ist Wert von *PACKAGE*
  1973.         else
  1974.         { STACK_0 = test_package_arg(pack); }
  1975.     }
  1976.  
  1977. # UP: ▄berprⁿfung der Argumente von INTERN und FIND-SYMBOL.
  1978. # test_intern_args()
  1979. # > subr_self: Aufrufer (ein SUBR)
  1980.   local void test_intern_args (void);
  1981.   local void test_intern_args()
  1982.     { # String ⁿberprⁿfen:
  1983.       if (!(stringp(STACK_1)))
  1984.         { pushSTACK(STACK_1); # Wert fⁿr Slot DATUM von TYPE-ERROR
  1985.           pushSTACK(S(string)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  1986.           pushSTACK(STACK_(1+2)); pushSTACK(TheSubr(subr_self)->name);
  1987.           fehler(type_error,
  1988.                  DEUTSCH ? "~: Argument ~ ist kein String." :
  1989.                  ENGLISH ? "~: argument ~ is not a string" :
  1990.                  FRANCAIS ? "~ : L'argument ~ n'est pas une chaεne." :
  1991.                  ""
  1992.                 );
  1993.         }
  1994.       # Package ⁿberprⁿfen:
  1995.       test_optional_package_arg();
  1996.     }
  1997.  
  1998. # UP: Wandelt ein INTERN/FIND-SYMBOL - Ergebnis in ein Keyword um.
  1999. # intern_result(code)
  2000. # > code : Flag wie bei intern und find_symbol
  2001. # < ergebnis : entsprechendes Keyword
  2002.   local object intern_result (uintBWL code);
  2003.   local object intern_result(code)
  2004.     var reg1 uintBWL code;
  2005.     { switch (code)
  2006.         { case 0: return NIL;           # 0 -> NIL
  2007.           case 1: return S(Kexternal);  # 1 -> :EXTERNAL
  2008.           case 2: return S(Kinherited); # 2 -> :INHERITED
  2009.           case 3: return S(Kinternal);  # 3 -> :INTERNAL
  2010.           default: NOTREACHED
  2011.     }   }
  2012.  
  2013. LISPFUN(intern,1,1,norest,nokey,0,NIL)
  2014. # (INTERN string [package]), CLTL S. 184
  2015.   { test_intern_args(); # Argumente ⁿberprⁿfen
  2016.    {var reg2 object pack = popSTACK();
  2017.     var reg1 object string = popSTACK();
  2018.     #if !defined(VALUE1_EXTRA)
  2019.     var reg3 uintBWL code = intern(string,pack,&value1); # Symbol nach value1
  2020.     #else
  2021.     var object value;
  2022.     var reg3 uintBWL code = intern(string,pack,&value); # Symbol nach value
  2023.     value1 = value;
  2024.     #endif
  2025.     value2 = intern_result(code); mv_count=2; # 2 Werte
  2026.   }}
  2027.  
  2028. LISPFUN(find_symbol,1,1,norest,nokey,0,NIL)
  2029. # (FIND-SYMBOL string [package]), CLTL S. 185
  2030.   { test_intern_args(); # Argumente ⁿberprⁿfen
  2031.    {var reg2 object pack = popSTACK();
  2032.     var reg1 object string = popSTACK();
  2033.     #if !defined(VALUE1_EXTRA)
  2034.     var reg3 uintBWL code = find_symbol(string,pack,&value1) & 3; # Symbol nach value1
  2035.     #else
  2036.     var object value;
  2037.     var reg3 uintBWL code = find_symbol(string,pack,&value) & 3; # Symbol nach value
  2038.     value1 = value;
  2039.     #endif
  2040.     value2 = intern_result(code); mv_count=2; # 2 Werte
  2041.   }}
  2042.  
  2043. LISPFUN(unintern,1,1,norest,nokey,0,NIL)
  2044. # (UNINTERN symbol [package]), CLTL S. 185
  2045.   { # Symbol ⁿberprⁿfen:
  2046.     if (!(msymbolp(STACK_1)))
  2047.       { pushSTACK(STACK_1); # Wert fⁿr Slot DATUM von TYPE-ERROR
  2048.         pushSTACK(S(symbol)); # Wert fⁿr Slot EXPECTED-TYPE von TYPE-ERROR
  2049.         pushSTACK(STACK_(1+2)); pushSTACK(TheSubr(subr_self)->name);
  2050.         fehler(type_error,
  2051.                DEUTSCH ? "~: Argument ~ ist kein Symbol." :
  2052.                ENGLISH ? "~: argument ~ is not a symbol" :
  2053.                FRANCAIS ? "~ : L'argument ~ n'est pas un symbole." :
  2054.                ""
  2055.               );
  2056.       }
  2057.     # Package ⁿberprⁿfen:
  2058.     test_optional_package_arg();
  2059.     # uninternieren:
  2060.     value1 = unintern(&STACK_1,&STACK_0); mv_count=1;
  2061.     skipSTACK(2);
  2062.   }
  2063.  
  2064. # Ausfⁿhrer einer Funktion wie EXPORT, UNEXPORT, IMPORT, SHADOWING-IMPORT
  2065. # oder SHADOW. ▄berprⁿft, ob das erste Argument eine Symbolliste ist, ob
  2066. # das zweite Argument (Default: *PACKAGE*) eine Package ist, und wendet das
  2067. # Unterprogramm auf jedes der Symbole an. Rⁿcksprung mit 1 Wert T.
  2068. # apply_symbols(&fun);
  2069. # Spezifikation des Unterprogrammes fun:
  2070. #   fun(&sym,&pack);
  2071. #   > sym: Symbol (im STACK)
  2072. #   > pack: Package (im STACK)
  2073. #   < pack: Package, EQ zur alten
  2074. #   kann GC ausl÷sen
  2075. # < STACK: aufgerΣumt
  2076. # kann GC ausl÷sen
  2077.   typedef void sym_pack_function (object* sym_, object* pack_);
  2078.   local Values apply_symbols (sym_pack_function* fun);
  2079.   local Values apply_symbols(fun)
  2080.     var reg2 sym_pack_function* fun;
  2081.     { # ▄berprⁿfe, ob das erste Argument eine Symbolliste oder ein Symbol ist:
  2082.       { var reg1 object symarg = STACK_1;
  2083.         # auf Symbol testen:
  2084.         if (symbolp(symarg)) goto ok;
  2085.         #ifdef X3J13_161
  2086.         if ((fun == &shadow) && stringp(symarg)) goto ok;
  2087.         #endif
  2088.         # auf Symbolliste testen:
  2089.         while (consp(symarg)) # symarg durchlΣuft STACK_1
  2090.           { if (!(msymbolp(Car(symarg))
  2091.                   #ifdef X3J13_161
  2092.                   || ((fun == &shadow) && mstringp(Car(symarg)))
  2093.                   #endif
  2094.                ) )
  2095.               goto not_ok;
  2096.             symarg = Cdr(symarg);
  2097.           }
  2098.         if (!(nullp(symarg))) goto not_ok; # Liste korrekt beendet?
  2099.         goto ok; # korrekte Symbolliste
  2100.         not_ok:
  2101.           pushSTACK(STACK_1); pushSTACK(TheSubr(subr_self)->name);
  2102.           fehler(error,
  2103.                  DEUTSCH ? "Argument zu ~ mu▀ ein Symbol oder eine Symbolliste sein, nicht ~" :
  2104.                  ENGLISH ? "~: argument should be a symbol or a list of symbols, not ~" :
  2105.                  FRANCAIS ? "~ : L'argument de ~ doit Ωtre un symbole ou une liste de symboles et non ~." :
  2106.                  ""
  2107.                 );
  2108.         ok: ;
  2109.       }
  2110.       # Package ⁿberprⁿfen:
  2111.       test_optional_package_arg();
  2112.       # Stackaufbau: symarg, pack.
  2113.       # fun auf alle Symbole anwenden:
  2114.       if (matomp(STACK_1))
  2115.         # einzelnes Symbol
  2116.         { # Stackaufbau: sym, pack.
  2117.           (*fun)(&STACK_1,&STACK_0);
  2118.           skipSTACK(2);
  2119.         }
  2120.         else
  2121.         # nichtleere Symbolliste
  2122.         { pushSTACK(NIL);
  2123.           do { var reg1 object symlistr = STACK_2;
  2124.                STACK_2 = Cdr(symlistr);
  2125.                STACK_0 = Car(symlistr); # Symbol
  2126.                # Stackaufbau: symlistr, pack, sym.
  2127.                (*fun)(&STACK_0,&STACK_1);
  2128.              }
  2129.              until (matomp(STACK_2));
  2130.           skipSTACK(3);
  2131.         }
  2132.       # beenden:
  2133.       value1 = T; mv_count=1;
  2134.     }
  2135.  
  2136. LISPFUN(export,1,1,norest,nokey,0,NIL)
  2137. # (EXPORT symbols [package]), CLTL S. 186
  2138.   { return_Values apply_symbols(&export); }
  2139.  
  2140. LISPFUN(unexport,1,1,norest,nokey,0,NIL)
  2141. # (UNEXPORT symbols [package]), CLTL S. 186
  2142.   { return_Values apply_symbols(&unexport); }
  2143.  
  2144. LISPFUN(import,1,1,norest,nokey,0,NIL)
  2145. # (IMPORT symbols [package]), CLTL S. 186
  2146.   { return_Values apply_symbols(&import); }
  2147.  
  2148. LISPFUN(shadowing_import,1,1,norest,nokey,0,NIL)
  2149. # (SHADOWING-IMPORT symbols [package]), CLTL S. 186
  2150.   { return_Values apply_symbols(&shadowing_import); }
  2151.  
  2152. LISPFUN(shadow,1,1,norest,nokey,0,NIL)
  2153. # (SHADOW symbols [package]), CLTL S. 186
  2154.   { return_Values apply_symbols(&shadow); }
  2155.  
  2156. # UP: Vorbereitung der Argumente bei USE-PACKAGE und UNUSE-PACKAGE.
  2157. # Das 1. Argument STACK_1 wird zu einer (neu erzeugten) Liste von Packages
  2158. # gemacht, das 2. Argument STACK_0 wird ⁿberprⁿft.
  2159. # > subr_self: Aufrufer (ein SUBR)
  2160. # kann GC ausl÷sen
  2161.   local void prepare_use_package (void);
  2162.   local void prepare_use_package()
  2163.     { # 2. Argument (Package) ⁿberprⁿfen:
  2164.       test_optional_package_arg();
  2165.       # 1. Argument (Package oder Packageliste) ⁿberprⁿfen:
  2166.       { var reg2 object packs_to_use = STACK_1;
  2167.         if (!(listp(packs_to_use)))
  2168.           # packs_to_use keine Liste -> einelementige Liste draus machen:
  2169.           { pushSTACK(test_package_arg(packs_to_use)); # einzelne Package
  2170.            {var reg1 object new_cons = allocate_cons();
  2171.             Car(new_cons) = popSTACK();
  2172.             STACK_1 = new_cons;
  2173.           }}
  2174.           else
  2175.           # packs_to_use eine Liste -> neue Packageliste aufbauen:
  2176.           { pushSTACK(NIL); # mit NIL anfangen
  2177.             while (mconsp(STACK_2))
  2178.               { var reg1 object packlistr = STACK_2;
  2179.                 STACK_2 = Cdr(packlistr);
  2180.                 pushSTACK(test_package_arg(Car(packlistr))); # nΣchste Package
  2181.                {var reg1 object new_cons = allocate_cons();
  2182.                 Car(new_cons) = popSTACK();
  2183.                 Cdr(new_cons) = STACK_0;
  2184.                 STACK_0 = new_cons;
  2185.               }}
  2186.            {var reg1 object packlist = popSTACK(); # neue Packageliste
  2187.             STACK_1 = packlist;
  2188.           }}
  2189.     } }
  2190.  
  2191. LISPFUN(use_package,1,1,norest,nokey,0,NIL)
  2192. # (USE-PACKAGE packs-to-use [package]), CLTL S. 187
  2193.   { prepare_use_package();
  2194.    {var reg2 object pack = popSTACK();
  2195.     var reg1 object packlist = popSTACK();
  2196.     use_package(packlist,pack);
  2197.     value1 = T; mv_count=1;
  2198.   }}
  2199.  
  2200. LISPFUN(unuse_package,1,1,norest,nokey,0,NIL)
  2201. # (UNUSE-PACKAGE packs-to-use [package]), CLTL S. 187
  2202.   { prepare_use_package();
  2203.    {var reg2 object pack = popSTACK();
  2204.     var reg1 object packlist = popSTACK();
  2205.     unuse_package(packlist,pack);
  2206.     value1 = T; mv_count=1;
  2207.   }}
  2208.  
  2209. # UP: Korrigiert einen Package(nick)name.
  2210. # > name: Gewⁿnschter Packagename (Simple-String)
  2211. # > STACK_1: "Sie dⁿrfen einen neuen (Nick)Name eingeben."
  2212. # > STACK_0: "Bitte neuen Package(nick)name eingeben:"
  2213. # < ergebnis: Noch nicht vorkommender Packagename
  2214. # kann GC ausl÷sen
  2215.   local object correct_packname (object name);
  2216.   local object correct_packname(name)
  2217.     var reg2 object name;
  2218.     { while (!(nullp(find_package(name))))
  2219.         { # Package mit diesem Namen existiert schon
  2220.           { pushSTACK(STACK_1); # "Sie dⁿrfen ... eingeben."
  2221.             pushSTACK(OL(makepack_string3)); # "Eine Package mit dem Namen ~S gibt es schon."
  2222.             pushSTACK(name);
  2223.             funcall(S(cerror),3); # (CERROR "Sie dⁿrfen ..." "Package ~S existiert" name)
  2224.           }
  2225.           { var object stream = var_stream(S(query_io)); # Stream *QUERY-IO*
  2226.             terpri(&stream); # neue Zeile
  2227.             write_sstring(&stream,STACK_0); # "Bitte ... eingeben:"
  2228.             pushSTACK(stream); funcall(L(read_line),1); # (READ-LINE stream)
  2229.             name = value1;
  2230.         } }
  2231.       return name;
  2232.     }
  2233.  
  2234. # UP fⁿr MAKE-PACKAGE und IN-PACKAGE:
  2235. # Bildet eine neue Package und liefert sie als Wert.
  2236. # > STACK_2: name-Argument
  2237. # > STACK_1: nicknames-Argument
  2238. # > STACK_0: uselist-Argument
  2239. # > subr_self: Aufrufer (ein SUBR)
  2240. # erh÷ht STACK um 3
  2241. # kann GC ausl÷sen
  2242.   local void in_make_package (void);
  2243.   local void in_make_package()
  2244.     { # name in Simple-String und nicknames in neue Simple-String-Liste umwandeln:
  2245.       test_names_args();
  2246.       # name ⁿberprⁿfen und evtl. korrigieren:
  2247.       { pushSTACK(OL(makepack_string1)); # "Sie dⁿrfen einen neuen Namen eingeben."
  2248.         pushSTACK(OL(makepack_string4)); # "Bitte neuen Packagenamen eingeben:"
  2249.         STACK_4 = correct_packname(STACK_4);
  2250.         skipSTACK(2);
  2251.       }
  2252.       # nicknames ⁿberprⁿfen und evtl. korrigieren:
  2253.       { pushSTACK(STACK_1); # nicknames durchgehen
  2254.         while (mconsp(STACK_0))
  2255.           { var reg1 object nickname = Car(STACK_0); # nickname herausgreifen
  2256.             pushSTACK(OL(makepack_string2)); # "Sie dⁿrfen einen neuen Nickname eingeben."
  2257.             pushSTACK(OL(makepack_string5)); # "Bitte neuen Packagenickname eingeben:"
  2258.             nickname = correct_packname(nickname); # korrigieren
  2259.             skipSTACK(2);
  2260.             Car(STACK_0) = nickname; # und wieder einsetzen
  2261.             STACK_0 = Cdr(STACK_0);
  2262.           }
  2263.         skipSTACK(1);
  2264.       }
  2265.       # Package erzeugen:
  2266.       {var reg1 object pack = make_package(STACK_2,STACK_1);
  2267.        STACK_2 = pack; # und retten
  2268.        # Stackaufbau: pack, nicknames, uselist-Argument.
  2269.        # Defaultwert fⁿr Use-Argument verwenden:
  2270.        if (eq(STACK_0,unbound)) { STACK_0 = O(use_default); }
  2271.        # (USE-PACKAGE UseList neuePackage) ausfⁿhren:
  2272.        { pushSTACK(STACK_0); # UseList
  2273.          pushSTACK(pack); # neue Package
  2274.          funcall(L(use_package),2);
  2275.       }}
  2276.       skipSTACK(2);
  2277.       value1 = popSTACK(); mv_count=1; # Package als Wert
  2278.     }
  2279.  
  2280. LISPFUN(make_package,1,0,norest,key,2, (kw(nicknames),kw(use)) )
  2281. # (MAKE-PACKAGE name [:NICKNAMES nicknames] [:USE uselist]), CLTL S. 183
  2282.   { in_make_package(); }
  2283.  
  2284. LISPFUN(pin_package,1,0,norest,key,2, (kw(nicknames),kw(use)) )
  2285. # (SYSTEM::%IN-PACKAGE name [:NICKNAMES nicknames] [:USE uselist]) ist
  2286. # wie (IN-PACKAGE name [:NICKNAMES nicknames] [:USE uselist]), CLTL S. 183,
  2287. # nur da▀ *PACKAGE* nicht modifiziert wird.
  2288.   { # name ⁿberprⁿfen und in String umwandeln:
  2289.     var reg3 object name = test_stringsym_arg(STACK_2);
  2290.     STACK_2 = name;
  2291.     # Package mit diesem Namen suchen:
  2292.    {var reg2 object pack = find_package(name);
  2293.     if (nullp(pack))
  2294.       # Package nicht gefunden, mu▀ eine neue erzeugen
  2295.       { in_make_package(); }
  2296.       else
  2297.       # Package gefunden
  2298.       { STACK_2 = pack; # pack retten
  2299.         # Stackaufbau: pack, nicknames, uselist.
  2300.         # Die Nicknames anpassen:
  2301.         if (!eq(STACK_1,unbound))
  2302.           # Nicknames installieren mit RENAME-PACKAGE:
  2303.           { pushSTACK(pack); # pack
  2304.             pushSTACK(ThePackage(pack)->pack_name); # (package-name pack)
  2305.             pushSTACK(STACK_3); # nicknames
  2306.             funcall(L(rename_package),3); # (RENAME-PACKAGE pack (package-name pack) nicknames)
  2307.           }
  2308.         # Die Use-List anpassen:
  2309.         if (!eq(STACK_0,unbound))
  2310.           { # Use-List erweitern mit USE-PACKAGE
  2311.             # und verkⁿrzen mit UNUSE-PACKAGE:
  2312.             pushSTACK(STACK_2); # pack als 2. Argument fⁿr USE-PACKAGE
  2313.             prepare_use_package(); # Argumente STACK_1, STACK_0 ⁿberprⁿfen
  2314.             skipSTACK(1);
  2315.             # Stackaufbau: pack, nicknames, neue Use-List.
  2316.             # USE-PACKAGE ausfⁿhren (mit kopierter Use-List):
  2317.             use_package(reverse(STACK_0),STACK_2);
  2318.             # Alle Packages, die jetzt noch in der Use-List von pack
  2319.             # aufgefⁿhrt sind, aber nicht in der in STACK_0 befindlichen
  2320.             # uselist vorkommen, werden mit unuse_1package entfernt:
  2321.             pack = STACK_2;
  2322.             { var reg3 object used_packs = ThePackage(pack)->pack_use_list; # Use-List von pack durchgehen
  2323.               while (consp(used_packs))
  2324.                 { var reg2 object qpack = Car(used_packs);
  2325.                   # in uselist suchen:
  2326.                   var reg1 object listr = STACK_0;
  2327.                   while (consp(listr))
  2328.                     { if (eq(qpack,Car(listr))) goto unuse_ok; # in uselist gefunden -> OK
  2329.                       listr = Cdr(listr);
  2330.                     }
  2331.                   # nicht in uselist gefunden
  2332.                   unuse_1package(pack,qpack);
  2333.                   unuse_ok: ;
  2334.                   used_packs = Cdr(used_packs);
  2335.           } }   }
  2336.         # Die Use-List ist korrekt angepa▀t.
  2337.         skipSTACK(2); # uselist und nicknames vergessen
  2338.         value1 = popSTACK(); mv_count=1; # pack als Wert
  2339.       }
  2340.   }}
  2341.  
  2342. LISPFUN(in_package,1,0,norest,key,2, (kw(nicknames),kw(use)) )
  2343. # (IN-PACKAGE name [:NICKNAMES nicknames] [:USE uselist]), CLTL S. 183
  2344.   { C_pin_package();
  2345.     # Ergebnis an *PACKAGE* zuweisen:
  2346.     Symbol_value(S(packagestern)) = value1;
  2347.   }
  2348.  
  2349. LISPFUNN(find_all_symbols,1)
  2350. # (FIND-ALL-SYMBOLS name), CLTL S. 187
  2351.   { STACK_0 = test_stringsym_arg(STACK_0); # name als String
  2352.     pushSTACK(NIL); # (bisher leere) Symbolliste
  2353.     pushSTACK(O(all_packages)); # Liste aller Packages durchgehen
  2354.     while (mconsp(STACK_0))
  2355.       { var reg2 object pack = Car(STACK_0); # nΣchste Package
  2356.         # in deren internen und externen Symbolen suchen:
  2357.         var object sym;
  2358.         if (symtab_lookup(STACK_2,ThePackage(pack)->pack_internal_symbols,&sym)
  2359.             || symtab_lookup(STACK_2,ThePackage(pack)->pack_external_symbols,&sym)
  2360.            )
  2361.           # gefunden: Symbol sym ist in Package pack prΣsent,
  2362.           # mit (pushnew sym STACK_1 :test #'eq) auf die Symbolliste consen:
  2363.           { # Suche, ob das gefundene Symbol sym in STACK_1 vorkommt:
  2364.             {var reg1 object symlistr = STACK_1;
  2365.              while (consp(symlistr))
  2366.                { if (eq(sym,Car(symlistr))) goto already_found; # gefunden -> nichts weiter zu tun
  2367.                  symlistr = Cdr(symlistr);
  2368.             }  }
  2369.             # nicht gefunden, mu▀ consen:
  2370.             pushSTACK(sym);
  2371.             {var reg1 object new_cons = allocate_cons();
  2372.              Car(new_cons) = popSTACK();
  2373.              Cdr(new_cons) = STACK_1;
  2374.              STACK_1 = new_cons;
  2375.             }
  2376.             already_found: ;
  2377.           }
  2378.         STACK_0 = Cdr(STACK_0);
  2379.       }
  2380.     skipSTACK(1);
  2381.     value1 = popSTACK(); mv_count=1; # Symbolliste als Wert
  2382.     skipSTACK(1);
  2383.   }
  2384.  
  2385. local object* map_symbols_local; # Pointer auf zwei lokale Variablen
  2386. LISPFUNN(map_symbols,2)
  2387. # (SYSTEM::MAP-SYMBOLS fun pack)
  2388. # wendet die Funktion fun auf alle in pack accessiblen Symbole an. Wert NIL.
  2389.   { # 2. Argument ⁿberprⁿfen:
  2390.     STACK_0 = test_package_arg(STACK_0);
  2391.     # fun auf alle internen Symbole loslassen:
  2392.     map_symtab(STACK_1,ThePackage(STACK_0)->pack_internal_symbols);
  2393.     # fun auf alle externen Symbole loslassen:
  2394.     map_symtab(STACK_1,ThePackage(STACK_0)->pack_external_symbols);
  2395.     # fun auf alle vererbten Symbole loslassen:
  2396.     map_symbols_local = &STACK_0; # zeigt auf die zwei lokalen Variablen
  2397.     pushSTACK(ThePackage(STACK_0)->pack_use_list); # Use-List durchgehen
  2398.     while (mconsp(STACK_0))
  2399.       { var reg1 object usedpack = Car(STACK_0); # nΣchste Package aus der Use-List
  2400.         STACK_0 = Cdr(STACK_0);
  2401.         map_symtab(L(map_symbols_aux),ThePackage(usedpack)->pack_external_symbols);
  2402.       }
  2403.     skipSTACK(3);
  2404.     value1 = NIL; mv_count=1; # NIL als Wert
  2405.   }
  2406.  
  2407. # Hilfsfunktion fⁿr map_symbols:
  2408. # Teste, ob das Argument nicht in der gegebenen Package verdeckt ist, und
  2409. # wende dann die gegebene Funktion an.
  2410. LISPFUNN(map_symbols_aux,1)
  2411.   { var reg1 object* localptr = map_symbols_local;
  2412.     # Pointer auf lokale Variablen von map_symbols:
  2413.     #   *(localptr STACKop 1) = fun,
  2414.     #   *(localptr STACKop 0) = pack.
  2415.     # Verdeckt ist das Symbol STACK_0 genau dann, wenn sich ein davon
  2416.     # verschiedenes Symbol desselben Namens in der Shadowing-Liste von pack
  2417.     # befindet.
  2418.     var object shadowingsym;
  2419.     if (!(shadowing_lookup(Symbol_name(STACK_0),*(localptr STACKop 0),&shadowingsym)
  2420.           && !eq(shadowingsym,STACK_0)
  2421.        ) )
  2422.       { funcall(*(localptr STACKop 1),1); }
  2423.       else
  2424.       # Symbol ist in pack verdeckt -> Funktion nicht aufrufen
  2425.       { skipSTACK(1); }
  2426.     map_symbols_local = localptr; # damit MAP-SYMBOLS reentrant ist
  2427.     value1 = NIL; mv_count=0; # keine Werte
  2428.   }
  2429.  
  2430. LISPFUNN(map_external_symbols,2)
  2431. # (SYSTEM::MAP-EXTERNAL-SYMBOLS fun pack)
  2432. # wendet die Funktion fun auf alle in pack externen Symbole an. Wert NIL.
  2433.   { # 2. Argument ⁿberprⁿfen:
  2434.     var reg1 object pack = test_package_arg(popSTACK());
  2435.     # fun auf alle externen Symbole loslassen:
  2436.     map_symtab(popSTACK(),ThePackage(pack)->pack_external_symbols);
  2437.     value1 = NIL; mv_count=1; # NIL als Wert
  2438.   }
  2439.  
  2440. LISPFUNN(map_all_symbols,1)
  2441. # (SYSTEM::MAP-ALL-SYMBOLS fun)
  2442. # wendet die Funktion fun auf alle in irgendeiner Package prΣsenten Symbole an.
  2443.   { pushSTACK(O(all_packages)); # Package-Liste durchgehen
  2444.     while (mconsp(STACK_0))
  2445.       { var reg1 object pack = Car(STACK_0); # nΣchste Package
  2446.         STACK_0 = Cdr(STACK_0);
  2447.         pushSTACK(pack); # retten
  2448.         # fun auf alle internen Symbole loslassen:
  2449.         map_symtab(STACK_2,ThePackage(pack)->pack_internal_symbols);
  2450.         pack = popSTACK();
  2451.         # fun auf alle externen Symbole loslassen:
  2452.         map_symtab(STACK_1,ThePackage(pack)->pack_external_symbols);
  2453.       }
  2454.     skipSTACK(2);
  2455.     value1 = NIL; mv_count=1; # NIL als Wert
  2456.   }
  2457.  
  2458. # Hilfsfunktionen fⁿr WITH-PACKAGE-ITERATOR, CLtL2 S. 275, und LOOP:
  2459. # (SYSTEM::PACKAGE-ITERATOR package flags) liefert einen internen Zustand
  2460. # fⁿr das Iterieren durch die Package.
  2461. # (SYSTEM::PACKAGE-ITERATE internal-state) iteriert durch eine Package um
  2462. # eins weiter, verΣndert dabei internal-state und liefert: 3 Werte
  2463. # T, symbol, accessibility des nΣchsten Symbols bzw. 1 Wert NIL am Schlu▀.
  2464.  
  2465. LISPFUNN(package_iterator,2)
  2466.   { STACK_1 = test_package_arg(STACK_1); # package-Argument ⁿberprⁿfen
  2467.     # Ein interner Zustand besteht aus einem Vektor
  2468.     # #(entry index symtab inh-packages package flags)
  2469.     # wobei flags eine Teilliste von (:INTERNAL :EXTERNAL :INHERITED) ist,
  2470.     #       package die ursprⁿngliche Package ist,
  2471.     #       inh-packages eine Teilliste von (package-use-list package) ist,
  2472.     #       symtab eine Symboltabelle oder NIL ist,
  2473.     #       index ein Index in symtab ist,
  2474.     #       entry der Rest eines Eintrags in symtab ist.
  2475.    {var reg1 object state = allocate_vector(6);
  2476.     # TheSvector(state)->data[2] = NIL; # unn÷tig
  2477.     TheSvector(state)->data[3] = ThePackage(STACK_1)->pack_use_list;
  2478.     TheSvector(state)->data[4] = STACK_1;
  2479.     TheSvector(state)->data[5] = STACK_0;
  2480.     value1 = state; mv_count=1; skipSTACK(2); # state als Wert
  2481.   }}
  2482.  
  2483. LISPFUNN(package_iterate,1)
  2484.   { var reg1 object state = popSTACK(); # interner Zustand
  2485.     if (simple_vector_p(state) && (TheSvector(state)->length == 6)) # hoffentlich ein 6er-Vektor
  2486.       { # state = #(entry index symtab inh-packages package flags)
  2487.         var reg2 object symtab = TheSvector(state)->data[2];
  2488.         if (simple_vector_p(symtab))
  2489.           { if (FALSE)
  2490.               { search1:
  2491.                 TheSvector(state)->data[2] = symtab;
  2492.                 TheSvector(state)->data[1] = Symtab_size(symtab);
  2493.                 TheSvector(state)->data[0] = NIL;
  2494.               }
  2495.             search2:
  2496.             { var reg3 object entry = TheSvector(state)->data[0];
  2497.               search3:
  2498.               # Innerhalb von entry weitersuchen:
  2499.               if (consp(entry))
  2500.                 { TheSvector(state)->data[0] = Cdr(entry);
  2501.                   value2 = Car(entry); goto found;
  2502.                 }
  2503.               elif (!nullp(entry))
  2504.                 { TheSvector(state)->data[0] = NIL;
  2505.                   value2 = entry; goto found;
  2506.                 }
  2507.               if (FALSE)
  2508.                 { found:
  2509.                   # Ein Symbol value2 gefunden.
  2510.                   # Stelle sicher, da▀ es in pack accessible und nicht verdeckt
  2511.                   # ist. Ansonsten befindet sich ein davon verschiedenes Symbol
  2512.                   # desselben Namens in der Shadowing-Liste von pack.
  2513.                  {var object shadowingsym;
  2514.                   if (!(eq(Car(TheSvector(state)->data[5]),S(Kinherited))
  2515.                         && shadowing_lookup(Symbol_name(value2),TheSvector(state)->data[4],&shadowingsym)
  2516.                         && !eq(shadowingsym,value2)
  2517.                      ) )
  2518.                     { # Symbol value2 ist wirklich accessible.
  2519.                       value1 = T; value3 = Car(TheSvector(state)->data[5]);
  2520.                       mv_count=3; return;
  2521.                     }
  2522.                   goto search2;
  2523.                 }}
  2524.               # entry = NIL geworden -> zum nΣchsten Index
  2525.              {var reg4 uintL index = posfixnum_to_L(TheSvector(state)->data[1]);
  2526.               if (index > 0)
  2527.                 { TheSvector(state)->data[1] = fixnum_inc(TheSvector(state)->data[1],-1);
  2528.                   index--;
  2529.                   entry = (index < posfixnum_to_L(Symtab_size(symtab)) # index sicherheitshalber ⁿberprⁿfen
  2530.                            ? TheSvector(Symtab_table(symtab))->data[index]
  2531.                            : NIL
  2532.                           );
  2533.                   goto search3;
  2534.                 }
  2535.             }}
  2536.             # index = 0 geworden -> zur nΣchsten Tabelle
  2537.             if (eq(Car(TheSvector(state)->data[5]),S(Kinherited)))
  2538.               { search4:
  2539.                 if (mconsp(TheSvector(state)->data[3]))
  2540.                   { # zum nΣchsten Element der Liste inh-packages
  2541.                     symtab = ThePackage(Car(TheSvector(state)->data[3]))->pack_external_symbols;
  2542.                     TheSvector(state)->data[3] = Cdr(TheSvector(state)->data[3]);
  2543.                     goto search1;
  2544.               }   }
  2545.             search5:
  2546.             # zum nΣchsten Element von flags
  2547.             TheSvector(state)->data[5] = Cdr(TheSvector(state)->data[5]);
  2548.           }
  2549.        {var reg4 object flags = TheSvector(state)->data[5];
  2550.         if (consp(flags))
  2551.           { var reg3 object flag = Car(flags);
  2552.             if (eq(flag,S(Kinternal))) # :INTERNAL
  2553.               { symtab = ThePackage(TheSvector(state)->data[4])->pack_internal_symbols;
  2554.                 goto search1;
  2555.               }
  2556.             elif (eq(flag,S(Kexternal))) # :EXTERNAL
  2557.               { symtab = ThePackage(TheSvector(state)->data[4])->pack_external_symbols;
  2558.                 goto search1;
  2559.               }
  2560.             elif (eq(flag,S(Kinherited))) # :INHERITED
  2561.               goto search4;
  2562.             goto search5; # unzulΣssiges Flag ⁿbergehen
  2563.       }}  }
  2564.     value1 = NIL; mv_count=1; return; # 1 Wert NIL
  2565.   }
  2566.  
  2567. # UP: Initialisiert die Packageverwaltung
  2568. # init_packages();
  2569.   global void init_packages (void);
  2570.   global void init_packages()
  2571.     { pushSTACK(make_imm_array(asciz_to_string("LISP")));
  2572.       pushSTACK(make_imm_array(asciz_to_string("USER")));
  2573.       pushSTACK(make_imm_array(asciz_to_string("SYSTEM")));
  2574.       pushSTACK(make_imm_array(asciz_to_string("SYS")));
  2575.       pushSTACK(make_imm_array(asciz_to_string("KEYWORD")));
  2576.       pushSTACK(make_imm_array(asciz_to_string("")));
  2577.       # Stackaufbau: "LISP", "USER", "SYSTEM", "SYS", "KEYWORD", "".
  2578.       O(all_packages) = NIL; # ALL_PACKAGES := NIL
  2579.       # #<PACKAGE KEYWORD> einrichten:
  2580.       {var reg1 object new_cons = allocate_cons();
  2581.        Car(new_cons) = popSTACK(); # ""
  2582.        O(keyword_package) = make_package(popSTACK(),new_cons); # "KEYWORD",("")
  2583.       }
  2584.       # #<PACKAGE SYSTEM> einrichten:
  2585.       {var reg1 object new_cons = allocate_cons();
  2586.        Car(new_cons) = STACK_0; # "SYS"
  2587.        STACK_0 = make_package(STACK_1,new_cons); # "SYSTEM",("SYS")
  2588.       }
  2589.       # #<PACKAGE USER> einrichten:
  2590.       O(default_package) = # und zur Default-Package machen
  2591.       STACK_2 = make_package(STACK_2,NIL); # "USER",()
  2592.       # #<PACKAGE LISP> einrichten:
  2593.       STACK_3 = STACK_1 = make_package(STACK_3,NIL); # "LISP",()
  2594.       # Stackaufbau: #<PACKAGE LISP>, #<PACKAGE USER>, #<PACKAGE LISP>, #<PACKAGE SYSTEM>.
  2595.       # (USE-PACKAGE '#<PACKAGE LISP> '#<PACKAGE SYSTEM>) :
  2596.       funcall(L(use_package),2);
  2597.       # (USE-PACKAGE '#<PACKAGE LISP> '#<PACKAGE USER>) :
  2598.       funcall(L(use_package),2);
  2599.       # Alle weiteren Packages einrichten, ans Ende der Liste ALL_PACKAGES hΣngen:
  2600.       nreverse(O(all_packages));
  2601.       #define LISPPACK  LISPPACK_B
  2602.       #include "constpack.c"
  2603.       #undef LISPPACK
  2604.       nreverse(O(all_packages));
  2605.     }
  2606.  
  2607.