mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-09 02:33:14 -08:00
+Deftype BIT-VECTOR would not expand to a vector type. +Each compiled file has an entry point whose name is either init_CODE() or another name based on the name of the source file. The algorithm for computing these names has been slightly changed so that the entry points of ECLS's own library do not conflict with user defined entry points. +A LET/LET* form in which the initializers for a variable have not the expected type produce a warning, but the code is accepted. For instance (LET (V) (DECLARE (TYPE FIXNUM V)) (SETQ V 1)) now compiles. +(SETF name), where name is a symbol, is now a valid function name in all contexts. It is accepted by DEFUN, FUNCTION, FBOUNDP, FMAKUNBOUND, etc, and it can be the on the function position in any form. +New specialized arrays for (UNSIGNED-BYTE 8) and (SIGNED-BYTE 8).
928 lines
20 KiB
D
928 lines
20 KiB
D
/*
|
|
package.d -- Packages.
|
|
*/
|
|
/*
|
|
Copyright (c) 1984, Taiichi Yuasa and Masami Hagiya.
|
|
Copyright (c) 1990, Giuseppe Attardi.
|
|
Copyright (c) 2001, Juan Jose Garcia Ripoll.
|
|
|
|
ECLS is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
See file '../Copyright' for full details.
|
|
*/
|
|
|
|
|
|
#include "ecls.h"
|
|
|
|
/******************************* EXPORTS ******************************/
|
|
|
|
bool lisp_package_locked = FALSE;
|
|
cl_object lisp_package;
|
|
cl_object user_package;
|
|
cl_object keyword_package;
|
|
cl_object system_package;
|
|
#ifdef CLOS
|
|
cl_object clos_package;
|
|
#endif
|
|
#ifdef TK
|
|
cl_object tk_package;
|
|
#endif
|
|
cl_object @'*package*'; /* *package* */
|
|
|
|
#ifndef THREADS
|
|
int intern_flag;
|
|
#endif
|
|
|
|
cl_object @':internal';
|
|
cl_object @':external';
|
|
cl_object @':inherited';
|
|
cl_object @':nicknames';
|
|
cl_object @':use';
|
|
|
|
/******************************* ------- ******************************/
|
|
|
|
#define INTERNAL 1
|
|
#define EXTERNAL 2
|
|
#define INHERITED 3
|
|
|
|
static cl_object package_list = Cnil;
|
|
static cl_object uninterned_list = Cnil;
|
|
|
|
static void no_package(cl_object n) __attribute__((noreturn));
|
|
static void package_already(cl_object n) __attribute__((noreturn));
|
|
|
|
static void
|
|
no_package(cl_object n)
|
|
{
|
|
FEerror("There is no package with the name ~A.", 1, n);
|
|
}
|
|
|
|
static void
|
|
package_already(cl_object n)
|
|
{
|
|
FEerror("A package with the name ~A already exists.", 1, n);
|
|
}
|
|
|
|
static bool
|
|
member_string_eq(cl_object x, cl_object l)
|
|
{
|
|
/* INV: l is a proper list */
|
|
for (; CONSP(l); l = CDR(l))
|
|
if (string_eq(x, CAR(l)))
|
|
return(TRUE);
|
|
return(FALSE);
|
|
}
|
|
|
|
/*
|
|
Make_package(n, ns, ul) makes a package with name n,
|
|
which must be a string or a symbol,
|
|
and nicknames ns, which must be a list of strings or symbols,
|
|
and uses packages in list ul, which must be a list of packages
|
|
or package names i.e. strings or symbols.
|
|
*/
|
|
static cl_object
|
|
make_package_hashtable()
|
|
{
|
|
cl_object h;
|
|
cl_index hsize = 128, i;
|
|
|
|
h = alloc_object(t_hashtable);
|
|
h->hash.test = htt_pack;
|
|
h->hash.size = hsize;
|
|
h->hash.rehash_size = make_shortfloat(1.5);
|
|
h->hash.threshold = make_shortfloat(0.7);
|
|
h->hash.entries = 0;
|
|
h->hash.data = alloc(hsize * sizeof(struct hashtable_entry));
|
|
for(i = 0; i < hsize; i++) {
|
|
h->hash.data[i].key = OBJNULL;
|
|
h->hash.data[i].value = OBJNULL;
|
|
}
|
|
return h;
|
|
}
|
|
|
|
cl_object
|
|
make_package(cl_object name, cl_object nicknames, cl_object use_list)
|
|
{
|
|
cl_object x, y;
|
|
cl_index i;
|
|
|
|
name = coerce_to_string(name);
|
|
assert_type_proper_list(nicknames);
|
|
assert_type_proper_list(use_list);
|
|
|
|
if (find_package(name) != Cnil)
|
|
package_already(name);
|
|
x = alloc_object(t_package);
|
|
x->pack.name = name;
|
|
x->pack.nicknames = Cnil;
|
|
x->pack.shadowings = Cnil;
|
|
x->pack.uses = Cnil;
|
|
x->pack.usedby = Cnil;
|
|
x->pack.locked = FALSE;
|
|
for (; !endp(nicknames); nicknames = CDR(nicknames)) {
|
|
cl_object nick = coerce_to_string(CAR(nicknames));
|
|
if (find_package(nick) != Cnil)
|
|
package_already(nick);
|
|
x->pack.nicknames = CONS(nick, x->pack.nicknames);
|
|
}
|
|
for (; !endp(use_list); use_list = CDR(use_list)) {
|
|
if (type_of(CAR(use_list)) == t_package)
|
|
y = CAR(use_list);
|
|
else {
|
|
y = find_package(CAR(use_list));
|
|
if (Null(y))
|
|
no_package(CAR(use_list));
|
|
}
|
|
x->pack.uses = CONS(y, x->pack.uses);
|
|
y->pack.usedby = CONS(x, y->pack.usedby);
|
|
}
|
|
x->pack.internal = make_package_hashtable();
|
|
x->pack.external = make_package_hashtable();
|
|
package_list = CONS(x, package_list);
|
|
return(x);
|
|
}
|
|
|
|
cl_object
|
|
rename_package(cl_object x, cl_object name, cl_object nicknames)
|
|
{
|
|
cl_object y;
|
|
|
|
/*
|
|
If we are trying to rename the package with either its name
|
|
or a nickname, then we are really trying to redefine the
|
|
package. Therefore, do not signal the error.
|
|
|
|
Marco Antoniotti 19951028
|
|
*/
|
|
x = coerce_to_package(x);
|
|
name = coerce_to_string(name);
|
|
y = find_package(name);
|
|
if ((y != Cnil) && (y != x))
|
|
package_already(name);
|
|
|
|
x->pack.name = name;
|
|
x->pack.nicknames = Cnil;
|
|
assert_type_proper_list(nicknames);
|
|
for (; !endp(nicknames); nicknames = CDR(nicknames)) {
|
|
cl_object nick = CAR(nicknames);
|
|
y = find_package(nick);
|
|
if (x == y)
|
|
continue;
|
|
if (y != Cnil)
|
|
package_already(nick);
|
|
x->pack.nicknames = CONS(coerce_to_string(nick), x->pack.nicknames);
|
|
}
|
|
return(x);
|
|
}
|
|
|
|
/*
|
|
Find_package(n) seaches for a package with name n, where n is
|
|
a valid string designator, or simply outputs n if it is a
|
|
package.
|
|
*/
|
|
cl_object
|
|
find_package(cl_object name)
|
|
{
|
|
cl_object l, p;
|
|
|
|
if (type_of(name) == t_package)
|
|
return name;
|
|
name = coerce_to_string_designator(name);
|
|
/* INV: package_list is a proper list */
|
|
for (l = package_list; CONSP(l); l = CDR(l)) {
|
|
p = CAR(l);
|
|
if (string_eq(name, p->pack.name))
|
|
return p;
|
|
if (member_string_eq(name, p->pack.nicknames))
|
|
return p;
|
|
}
|
|
return Cnil;
|
|
}
|
|
|
|
cl_object
|
|
coerce_to_package(cl_object p)
|
|
{
|
|
cl_object pp;
|
|
if (type_of(p) == t_package)
|
|
return(p);
|
|
pp = find_package(p);
|
|
if (!Null(pp))
|
|
return (pp);
|
|
FEwrong_type_argument(@'package', p);
|
|
}
|
|
|
|
cl_object
|
|
current_package(void)
|
|
{
|
|
cl_object x;
|
|
|
|
x = symbol_value(@'*package*');
|
|
if (type_of(x) != t_package) {
|
|
SYM_VAL(@'*package*') = user_package;
|
|
FEerror("The value of *PACKAGE*, ~S, was not a package.",
|
|
1, x);
|
|
}
|
|
return(x);
|
|
}
|
|
|
|
/*
|
|
Intern(st, p) interns string st in package p.
|
|
*/
|
|
cl_object
|
|
_intern(const char *s, cl_object p)
|
|
{
|
|
cl_object str = make_simple_string(s);
|
|
return intern(str, p);
|
|
}
|
|
|
|
cl_object
|
|
intern(cl_object name, cl_object p)
|
|
{
|
|
cl_object s, ul;
|
|
|
|
assert_type_string(name);
|
|
p = coerce_to_package(p);
|
|
s = gethash_safe(name, p->pack.external, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = EXTERNAL;
|
|
return s;
|
|
}
|
|
/* Keyword package has no intern section nor can it be used */
|
|
if (p == keyword_package) goto INTERN;
|
|
s = gethash_safe(name, p->pack.internal, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = INTERNAL;
|
|
return s;
|
|
}
|
|
for (ul=p->pack.uses; CONSP(ul); ul = CDR(ul)) {
|
|
s = gethash_safe(name, CAR(ul)->pack.external, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = INHERITED;
|
|
return s;
|
|
}
|
|
}
|
|
INTERN:
|
|
s = make_symbol(name);
|
|
s->symbol.hpack = p;
|
|
intern_flag = 0;
|
|
if (p == keyword_package) {
|
|
s->symbol.stype = stp_constant;
|
|
SYM_VAL(s) = s;
|
|
sethash(name, p->pack.external, s);
|
|
} else {
|
|
sethash(name, p->pack.internal, s);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/*
|
|
Find_symbol(st, len, p) searches for string st of length len in package p.
|
|
*/
|
|
cl_object
|
|
find_symbol(cl_object name, cl_object p)
|
|
{
|
|
cl_object s, ul;
|
|
|
|
name = coerce_to_string_designator(name);
|
|
p = coerce_to_package(p);
|
|
s = gethash_safe(name, p->pack.external, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = EXTERNAL;
|
|
return s;
|
|
}
|
|
if (p == keyword_package) goto RETURN;
|
|
s = gethash_safe(name, p->pack.internal, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = INTERNAL;
|
|
return s;
|
|
}
|
|
for (ul=p->pack.uses; CONSP(ul); ul = CDR(ul)) {
|
|
s = gethash_safe(name, CAR(ul)->pack.external, OBJNULL);
|
|
if (s != OBJNULL) {
|
|
intern_flag = INHERITED;
|
|
return s;
|
|
}
|
|
}
|
|
RETURN:
|
|
intern_flag = 0;
|
|
return(Cnil);
|
|
}
|
|
|
|
static void
|
|
delete_eq(cl_object x, cl_object *lp)
|
|
{
|
|
for (; CONSP(*lp); lp = &CDR((*lp)))
|
|
if (CAR((*lp)) == x) {
|
|
*lp = CDR((*lp));
|
|
return;
|
|
}
|
|
}
|
|
|
|
bool
|
|
unintern(cl_object s, cl_object p)
|
|
{
|
|
cl_object x, y, l, hash;
|
|
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
hash = p->pack.internal;
|
|
x = gethash_safe(s->symbol.name, hash, OBJNULL);
|
|
if (x == s) {
|
|
if (member_eq(s, p->pack.shadowings))
|
|
goto L;
|
|
goto UNINTERN;
|
|
}
|
|
hash = p->pack.external;
|
|
x = gethash_safe(s->symbol.name, hash, OBJNULL);
|
|
if (x == s) {
|
|
if (member_eq(s, p->pack.shadowings))
|
|
goto L;
|
|
goto UNINTERN;
|
|
}
|
|
return(FALSE);
|
|
|
|
L:
|
|
x = OBJNULL;
|
|
for (l = p->pack.uses; CONSP(l); l = CDR(l)) {
|
|
y = gethash_safe(s->symbol.name, CAR(l)->pack.external, OBJNULL);
|
|
if (y != OBJNULL) {
|
|
if (x == OBJNULL)
|
|
x = y;
|
|
else if (x != y)
|
|
FEerror("Cannot unintern the shadowing symbol ~S~%\
|
|
from ~S,~%\
|
|
because ~S and ~S will cause~%\
|
|
a name conflict.", 4, s, p, x, y);
|
|
}
|
|
}
|
|
delete_eq(s, &p->pack.shadowings);
|
|
|
|
UNINTERN:
|
|
remhash(s->symbol.name, hash);
|
|
if (s->symbol.hpack == p)
|
|
s->symbol.hpack = Cnil;
|
|
if (s->symbol.stype != stp_ordinary)
|
|
uninterned_list = CONS(s, uninterned_list);
|
|
return(TRUE);
|
|
}
|
|
|
|
void
|
|
export(cl_object s, cl_object p)
|
|
{
|
|
cl_object x, l, hash = OBJNULL;
|
|
BEGIN:
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
x = find_symbol(s, p);
|
|
if (!intern_flag)
|
|
FEerror("The symbol ~S is not accessible from ~S.", 2,
|
|
s, p);
|
|
if (x != s) {
|
|
import(s, p); /* signals an error */
|
|
goto BEGIN;
|
|
}
|
|
if (intern_flag == EXTERNAL)
|
|
return;
|
|
if (intern_flag == INTERNAL)
|
|
hash = p->pack.internal;
|
|
for (l = p->pack.usedby; CONSP(l); l = CDR(l)) {
|
|
x = find_symbol(s, CAR(l));
|
|
if (intern_flag && s != x &&
|
|
!member_eq(x, CAR(l)->pack.shadowings))
|
|
FEerror("Cannot export the symbol ~S~%\
|
|
from ~S,~%\
|
|
because it will cause a name conflict~%\
|
|
in ~S.", 3, s, p, CAR(l));
|
|
}
|
|
if (hash != OBJNULL)
|
|
remhash(s->symbol.name, hash);
|
|
sethash(s->symbol.name, p->pack.external, s);
|
|
}
|
|
|
|
void
|
|
delete_package(cl_object p)
|
|
{
|
|
cl_object hash, list;
|
|
cl_index i;
|
|
|
|
p = coerce_to_package(p);
|
|
if (p == lisp_package || p == keyword_package)
|
|
FEerror("Cannot remove package ~S", 1, p->pack.name);
|
|
for (list = p->pack.uses; !endp(list); list = CDR(list))
|
|
unuse_package(CAR(list), p);
|
|
for (list = p->pack.usedby; !endp(list); list = CDR(list))
|
|
unuse_package(p, CAR(list));
|
|
for (hash = p->pack.internal, i = 0; i < hash->hash.size; i++)
|
|
if (hash->hash.data[i].key != OBJNULL)
|
|
unintern(hash->hash.data[i].value, p);
|
|
for (hash = p->pack.external, i = 0; i < hash->hash.size; i++)
|
|
if (hash->hash.data[i].key != OBJNULL)
|
|
unintern(hash->hash.data[i].value, p);
|
|
delete_eq(p, &package_list);
|
|
p->pack.shadowings = Cnil;
|
|
p->pack.internal = OBJNULL;
|
|
p->pack.external = OBJNULL;
|
|
}
|
|
|
|
void
|
|
unexport(cl_object s, cl_object p)
|
|
{
|
|
cl_object x;
|
|
|
|
if (p == keyword_package)
|
|
FEerror("Cannot unexport a symbol from the keyword.", 0);
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
x = find_symbol(s, p);
|
|
if (intern_flag != EXTERNAL || x != s)
|
|
/* According to ANSI & Cltl, internal symbols are
|
|
ignored in unexport */
|
|
return;
|
|
remhash(s->symbol.name, p->pack.external);
|
|
sethash(s->symbol.name, p->pack.internal, s);
|
|
}
|
|
|
|
void
|
|
import(cl_object s, cl_object p)
|
|
{
|
|
cl_object x;
|
|
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
x = find_symbol(s, p);
|
|
if (intern_flag) {
|
|
if (x != s)
|
|
FEerror("Cannot import the symbol ~S~%\
|
|
from ~S,~%\
|
|
because there is already a symbol with the same name~%\
|
|
in the package.", 2, s, p);
|
|
if (intern_flag == INTERNAL || intern_flag == EXTERNAL)
|
|
return;
|
|
}
|
|
sethash(s->symbol.name, p->pack.internal, s);
|
|
if (Null(s->symbol.hpack))
|
|
s->symbol.hpack = p;
|
|
}
|
|
|
|
void
|
|
shadowing_import(cl_object s, cl_object p)
|
|
{
|
|
cl_object x;
|
|
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
x = find_symbol(s, p);
|
|
if (intern_flag && intern_flag != INHERITED) {
|
|
if (x == s) {
|
|
if (!member_eq(x, p->pack.shadowings))
|
|
p->pack.shadowings
|
|
= CONS(x, p->pack.shadowings);
|
|
return;
|
|
}
|
|
if(member_eq(x, p->pack.shadowings))
|
|
delete_eq(x, &p->pack.shadowings);
|
|
if (intern_flag == INTERNAL)
|
|
remhash(x->symbol.name, p->pack.internal);
|
|
else
|
|
remhash(x->symbol.name, p->pack.external);
|
|
if (x->symbol.hpack == p)
|
|
x->symbol.hpack = Cnil;
|
|
if (x->symbol.stype != stp_ordinary)
|
|
uninterned_list = CONS(x, uninterned_list);
|
|
}
|
|
p->pack.shadowings = CONS(s, p->pack.shadowings);
|
|
sethash(s->symbol.name, p->pack.internal, s);
|
|
}
|
|
|
|
void
|
|
shadow(cl_object s, cl_object p)
|
|
{
|
|
cl_object x;
|
|
|
|
assert_type_symbol(s);
|
|
p = coerce_to_package(p);
|
|
x = find_symbol(s, p);
|
|
if (intern_flag != INTERNAL && intern_flag != EXTERNAL) {
|
|
x = make_symbol(s);
|
|
sethash(x->symbol.name, p->pack.internal, x);
|
|
x->symbol.hpack = p;
|
|
}
|
|
p->pack.shadowings = CONS(x, p->pack.shadowings);
|
|
}
|
|
|
|
void
|
|
use_package(cl_object x, cl_object p)
|
|
{
|
|
struct hashtable_entry *hash_entries;
|
|
cl_index i, hash_length;
|
|
|
|
x = coerce_to_package(x);
|
|
if (x == keyword_package)
|
|
FEerror("Cannot use keyword package.", 0);
|
|
p = coerce_to_package(p);
|
|
if (p == keyword_package)
|
|
FEerror("Cannot use in keyword package.", 0);
|
|
if (p == x)
|
|
return;
|
|
if (member_eq(x, p->pack.uses))
|
|
return;
|
|
hash_entries = x->pack.external->hash.data;
|
|
hash_length = x->pack.external->hash.size;
|
|
for (i = 0; i < hash_length; i++)
|
|
if (hash_entries[i].key != OBJNULL) {
|
|
cl_object here = hash_entries[i].value;
|
|
cl_object there = find_symbol(here, p);
|
|
if (intern_flag && here != there
|
|
&& ! member_eq(there, p->pack.shadowings))
|
|
FEerror("Cannot use ~S~%\
|
|
from ~S,~%\
|
|
because ~S and ~S will cause~%\
|
|
a name conflict.", 4, x, p, here, there);
|
|
}
|
|
p->pack.uses = CONS(x, p->pack.uses);
|
|
x->pack.usedby = CONS(p, x->pack.usedby);
|
|
}
|
|
|
|
void
|
|
unuse_package(cl_object x, cl_object p)
|
|
{
|
|
x = coerce_to_package(x);
|
|
p = coerce_to_package(p);
|
|
delete_eq(x, &p->pack.uses);
|
|
delete_eq(p, &x->pack.usedby);
|
|
}
|
|
|
|
@(defun make_package (pack_name &key nicknames (use CONS(lisp_package, Cnil)))
|
|
@
|
|
/* INV: make_package() performs type checking */
|
|
@(return make_package(pack_name, nicknames, use))
|
|
@)
|
|
|
|
@(defun si::select_package (pack_name)
|
|
cl_object p;
|
|
@
|
|
/* INV: find_package()/in_package() perform type checks */
|
|
p = find_package(pack_name);
|
|
if (Null(p))
|
|
FEerror("Package ~s not found", 1, pack_name);
|
|
@(return (SYM_VAL(@'*package*') = p))
|
|
@)
|
|
|
|
@(defun find_package (p)
|
|
@
|
|
@(return find_package(p))
|
|
@)
|
|
|
|
@(defun package_name (p)
|
|
@
|
|
/* INV: coerce_to_package() performs type checks */
|
|
/* FIXME: name should be a fresh one */
|
|
p = coerce_to_package(p);
|
|
@(return p->pack.name)
|
|
@)
|
|
|
|
@(defun package_nicknames (p)
|
|
@
|
|
/* INV: coerce_to_package() type checks */
|
|
/* FIXME: list should be a fresh one */
|
|
p = coerce_to_package(p);
|
|
@(return p->pack.nicknames)
|
|
@)
|
|
|
|
@(defun rename_package (pack new_name &o new_nicknames)
|
|
@
|
|
/* INV: rename_package() type checks and coerces pack to package */
|
|
@(return rename_package(pack, new_name, new_nicknames))
|
|
@)
|
|
|
|
@(defun package_use_list (p)
|
|
@
|
|
/* INV: coerce_to_package() type checks */
|
|
/* FIXME: list should be a fresh one */
|
|
p = coerce_to_package(p);
|
|
@(return p->pack.uses)
|
|
@)
|
|
|
|
@(defun package_used_by_list (p)
|
|
@
|
|
/* INV: coerce_to_package() type checks */
|
|
/* FIXME: list should be a fresh one */
|
|
p = coerce_to_package(p);
|
|
@(return p->pack.usedby)
|
|
@)
|
|
|
|
@(defun package_shadowing_symbols (p)
|
|
@
|
|
/* INV: coerce_to_package() type checks */
|
|
/* FIXME: list should be a fresh one */
|
|
p = coerce_to_package(p);
|
|
@(return p->pack.shadowings)
|
|
@)
|
|
|
|
@(defun si::package_lock (p t)
|
|
@
|
|
/* INV: coerce_to_package() type checks */
|
|
p = coerce_to_package(p);
|
|
p->pack.locked = (t != Cnil);
|
|
@(return p)
|
|
@)
|
|
|
|
@(defun list_all_packages ()
|
|
@
|
|
@(return copy_list(package_list))
|
|
@)
|
|
|
|
@(defun intern (strng &optional (p current_package()) &aux sym)
|
|
@
|
|
sym = intern(strng, p);
|
|
if (intern_flag == INTERNAL)
|
|
@(return sym @':internal')
|
|
if (intern_flag == EXTERNAL)
|
|
@(return sym @':external')
|
|
if (intern_flag == INHERITED)
|
|
@(return sym @':inherited')
|
|
@(return sym Cnil)
|
|
@)
|
|
|
|
@(defun find_symbol (strng &optional (p current_package()))
|
|
cl_object x;
|
|
@
|
|
x = find_symbol(strng, p);
|
|
if (intern_flag == INTERNAL)
|
|
@(return x @':internal')
|
|
if (intern_flag == EXTERNAL)
|
|
@(return x @':external')
|
|
if (intern_flag == INHERITED)
|
|
@(return x @':inherited')
|
|
@(return Cnil Cnil)
|
|
@)
|
|
|
|
@(defun unintern (symbl &optional (p current_package()))
|
|
@
|
|
@(return (unintern(symbl, p) ? Ct : Cnil))
|
|
@)
|
|
|
|
@(defun export (symbols &o (pack current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(symbols)) {
|
|
case t_symbol:
|
|
if (Null(symbols))
|
|
break;
|
|
export(symbols, pack);
|
|
break;
|
|
|
|
case t_cons:
|
|
pack = coerce_to_package(pack); /* Saves time */
|
|
for (l = symbols; !endp(l); l = CDR(l))
|
|
export(CAR(l), pack);
|
|
break;
|
|
|
|
default:
|
|
assert_type_symbol(symbols);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun unexport (symbols &o (pack current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(symbols)) {
|
|
case t_symbol:
|
|
if (Null(symbols))
|
|
break;
|
|
unexport(symbols, pack);
|
|
break;
|
|
|
|
case t_cons:
|
|
pack = coerce_to_package(pack); /* Saves time */
|
|
for (l = symbols; !endp(l); l = CDR(l))
|
|
unexport(CAR(l), pack);
|
|
break;
|
|
|
|
default:
|
|
assert_type_symbol(symbols);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun import (symbols &o (pack current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(symbols)) {
|
|
case t_symbol:
|
|
if (Null(symbols))
|
|
break;
|
|
import(symbols, pack);
|
|
break;
|
|
|
|
case t_cons:
|
|
pack = coerce_to_package(pack); /* Saves time */
|
|
for (l = symbols; !endp(l); l = CDR(l))
|
|
import(CAR(l), pack);
|
|
break;
|
|
|
|
default:
|
|
assert_type_symbol(symbols);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun shadowing_import (symbols &o (pack current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(symbols)) {
|
|
case t_symbol:
|
|
if (Null(symbols))
|
|
break;
|
|
shadowing_import(symbols, pack);
|
|
break;
|
|
|
|
case t_cons:
|
|
pack = coerce_to_package(pack); /* Saves time */
|
|
for (l = symbols; !endp(l); l = CDR(l))
|
|
shadowing_import(CAR(l), pack);
|
|
break;
|
|
|
|
default:
|
|
assert_type_symbol(symbols);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun shadow (symbols &o (pack current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(symbols)) {
|
|
case t_symbol:
|
|
if (Null(symbols))
|
|
break;
|
|
shadow(symbols, pack);
|
|
break;
|
|
|
|
case t_cons:
|
|
pack = coerce_to_package(pack); /* Saves time */
|
|
for (l = symbols; !endp(l); l = CDR(l))
|
|
shadow(CAR(l), pack);
|
|
break;
|
|
|
|
default:
|
|
assert_type_symbol(symbols);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun use_package (pack &o (pa current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(pack)) {
|
|
case t_symbol:
|
|
if (Null(pack))
|
|
break;
|
|
case t_string:
|
|
case t_package:
|
|
use_package(pack, pa);
|
|
break;
|
|
|
|
case t_cons:
|
|
pa = coerce_to_package(pa); /* Saves time */
|
|
for (l = pack; !endp(l); l = CDR(l))
|
|
use_package(CAR(l), pa);
|
|
break;
|
|
|
|
default:
|
|
assert_type_package(pack);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun unuse_package (pack &o (pa current_package()))
|
|
cl_object l;
|
|
@
|
|
BEGIN:
|
|
switch (type_of(pack)) {
|
|
case t_symbol:
|
|
if (Null(pack))
|
|
break;
|
|
|
|
case t_string:
|
|
case t_package:
|
|
unuse_package(pack, pa);
|
|
break;
|
|
|
|
case t_cons:
|
|
pa = coerce_to_package(pa);
|
|
for (l = pack; !endp(l); l = CDR(l))
|
|
unuse_package(CAR(l), pa);
|
|
break;
|
|
|
|
default:
|
|
assert_type_package(pack);
|
|
goto BEGIN;
|
|
}
|
|
@(return Ct)
|
|
@)
|
|
|
|
@(defun si::package_internal (p index)
|
|
cl_fixnum j;
|
|
cl_object hash;
|
|
@
|
|
p = coerce_to_package(p);
|
|
hash = p->pack.internal;
|
|
if (!FIXNUMP(index) || (j = fix(index)) < 0 || j >= hash->hash.size)
|
|
FEerror("~S is an illegal index to a package hashtable.",
|
|
1, index);
|
|
@(return ((hash->hash.data[j].key != OBJNULL)?
|
|
hash->hash.data[j].value : MAKE_FIXNUM(1)))
|
|
@)
|
|
|
|
@(defun si::package_external (p index)
|
|
cl_fixnum j;
|
|
cl_object hash;
|
|
@
|
|
p = coerce_to_package(p);
|
|
hash = p->pack.external;
|
|
if (!FIXNUMP(index) || (j = fix(index)) < 0 || j >= hash->hash.size)
|
|
FEerror("~S is an illegal index to a package hashtable.",
|
|
1, index);
|
|
@(return ((hash->hash.data[j].key != OBJNULL)?
|
|
hash->hash.data[j].value : MAKE_FIXNUM(1)))
|
|
@)
|
|
|
|
@(defun si::package_size (p)
|
|
@
|
|
assert_type_package(p);
|
|
@(return MAKE_FIXNUM(p->pack.external->hash.size)
|
|
MAKE_FIXNUM(p->pack.internal->hash.size))
|
|
@)
|
|
|
|
@(defun delete_package (p)
|
|
@
|
|
delete_package(p);
|
|
@)
|
|
|
|
void
|
|
init_package(void)
|
|
{
|
|
register_root(&package_list);
|
|
register_root(&uninterned_list);
|
|
|
|
lisp_package = make_package(make_simple_string("COMMON-LISP"),
|
|
CONS(make_simple_string("CL"),
|
|
CONS(make_simple_string("LISP"),Cnil)),
|
|
Cnil);
|
|
register_root(&lisp_package);
|
|
user_package = make_package(make_simple_string("COMMON-LISP-USER"),
|
|
CONS(make_simple_string("CL-USER"),
|
|
CONS(make_simple_string("USER"),Cnil)),
|
|
CONS(lisp_package, Cnil));
|
|
register_root(&user_package);
|
|
keyword_package = make_package(make_simple_string("KEYWORD"),
|
|
Cnil, Cnil);
|
|
register_root(&keyword_package);
|
|
system_package = make_package(make_simple_string("SI"),
|
|
CONS(make_simple_string("SYSTEM"),
|
|
CONS(make_simple_string("SYS"),
|
|
Cnil)),
|
|
CONS(lisp_package, Cnil));
|
|
register_root(&system_package);
|
|
#ifdef CLOS
|
|
clos_package = make_package(make_simple_string("CLOS"),
|
|
Cnil,
|
|
CONS(lisp_package, Cnil));
|
|
register_root(&clos_package);
|
|
#endif
|
|
#ifdef TK
|
|
tk_package = make_package(make_simple_string("TK"),
|
|
Cnil,
|
|
CONS(lisp_package, Cnil));
|
|
register_root(&tk_package);
|
|
#endif
|
|
|
|
Cnil->symbol.hpack = lisp_package;
|
|
import(Cnil, lisp_package);
|
|
export(Cnil, lisp_package);
|
|
|
|
Ct->symbol.hpack = lisp_package;
|
|
import(Ct, lisp_package);
|
|
export(Ct, lisp_package);
|
|
|
|
/* There is no need to enter a package as a mark origin. */
|
|
|
|
@'*package*' = make_special("*PACKAGE*", lisp_package);
|
|
}
|