home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-1.LHA / CLISP960530-sr.lha / src / package.d < prev    next >
Encoding:
Text File  |  1996-04-15  |  116.2 KB  |  2,665 lines

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