2019-02-05 02:44:07 +02:00
|
|
|
[Inter::Packages::] Packages.
|
|
|
|
|
|
|
|
To manage packages of inter code.
|
|
|
|
|
|
|
|
@h Symbols tables.
|
|
|
|
|
|
|
|
=
|
|
|
|
typedef struct inter_package {
|
2019-07-26 12:14:17 +03:00
|
|
|
struct inter_tree_node *package_head;
|
2019-02-05 02:44:07 +02:00
|
|
|
inter_t index_n;
|
2019-07-27 17:01:50 +03:00
|
|
|
struct text_stream *package_name_t;
|
2019-02-05 02:44:07 +02:00
|
|
|
struct inter_symbols_table *package_scope;
|
2019-06-10 10:30:20 +03:00
|
|
|
int package_flags;
|
2019-07-27 17:01:50 +03:00
|
|
|
struct dictionary *name_lookup;
|
2020-05-09 15:07:39 +03:00
|
|
|
CLASS_DEFINITION
|
2019-02-05 02:44:07 +02:00
|
|
|
} inter_package;
|
|
|
|
|
2019-06-10 10:30:20 +03:00
|
|
|
@
|
|
|
|
|
2019-07-13 16:48:27 +03:00
|
|
|
@d CODELIKE_PACKAGE_FLAG 1
|
2019-07-20 09:18:40 +03:00
|
|
|
@d LINKAGE_PACKAGE_FLAG 2
|
|
|
|
@d USED_PACKAGE_FLAG 4
|
2019-07-22 12:05:02 +03:00
|
|
|
@d ROOT_PACKAGE_FLAG 8
|
2019-07-26 21:20:27 +03:00
|
|
|
@d MARK_PACKAGE_FLAG 16
|
2019-06-10 10:30:20 +03:00
|
|
|
|
2019-02-05 02:44:07 +02:00
|
|
|
@ =
|
2019-07-26 12:14:17 +03:00
|
|
|
inter_tree *default_ptree = NULL;
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_package *Inter::Packages::new(inter_tree *I, inter_t n) {
|
2019-02-05 02:44:07 +02:00
|
|
|
inter_package *pack = CREATE(inter_package);
|
2019-07-26 12:14:17 +03:00
|
|
|
pack->package_head = NULL;
|
2019-02-05 02:44:07 +02:00
|
|
|
pack->package_scope = NULL;
|
2019-06-10 10:30:20 +03:00
|
|
|
pack->package_flags = 0;
|
2019-07-27 17:01:50 +03:00
|
|
|
pack->package_name_t = NULL;
|
2019-02-05 02:44:07 +02:00
|
|
|
pack->index_n = n;
|
2019-07-27 17:01:50 +03:00
|
|
|
pack->name_lookup = Dictionaries::new(INITIAL_INTER_SYMBOLS_ID_RANGE, FALSE);
|
2019-02-05 02:44:07 +02:00
|
|
|
return pack;
|
|
|
|
}
|
|
|
|
|
2019-07-26 21:20:27 +03:00
|
|
|
inter_tree_node *Inter::Packages::definition(inter_package *pack) {
|
|
|
|
if (pack == NULL) return NULL;
|
2019-07-27 13:16:22 +03:00
|
|
|
if (Inter::Packages::is_rootlike(pack)) return NULL;
|
|
|
|
return pack->package_head;
|
2019-07-26 21:20:27 +03:00
|
|
|
}
|
|
|
|
|
2019-07-26 12:14:17 +03:00
|
|
|
inter_tree *Inter::Packages::tree(inter_package *pack) {
|
|
|
|
if (default_ptree) return default_ptree;
|
2019-08-04 15:04:42 +03:00
|
|
|
if (pack == NULL) return NULL;
|
2019-07-26 12:14:17 +03:00
|
|
|
return pack->package_head->tree;
|
|
|
|
}
|
|
|
|
|
|
|
|
text_stream *Inter::Packages::name(inter_package *pack) {
|
|
|
|
if (pack == NULL) return NULL;
|
2019-07-27 17:01:50 +03:00
|
|
|
return pack->package_name_t;
|
2019-07-26 12:14:17 +03:00
|
|
|
}
|
|
|
|
|
2019-07-13 16:48:27 +03:00
|
|
|
int Inter::Packages::is_codelike(inter_package *pack) {
|
|
|
|
if ((pack) && (pack->package_flags & CODELIKE_PACKAGE_FLAG)) return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::make_codelike(inter_package *pack) {
|
|
|
|
if (pack) {
|
|
|
|
pack->package_flags |= CODELIKE_PACKAGE_FLAG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-20 09:18:40 +03:00
|
|
|
int Inter::Packages::is_linklike(inter_package *pack) {
|
|
|
|
if ((pack) && (pack->package_flags & LINKAGE_PACKAGE_FLAG)) return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::make_linklike(inter_package *pack) {
|
|
|
|
if (pack) {
|
|
|
|
pack->package_flags |= LINKAGE_PACKAGE_FLAG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-22 12:05:02 +03:00
|
|
|
int Inter::Packages::is_rootlike(inter_package *pack) {
|
|
|
|
if ((pack) && (pack->package_flags & ROOT_PACKAGE_FLAG)) return TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::make_rootlike(inter_package *pack) {
|
|
|
|
if (pack) {
|
|
|
|
pack->package_flags |= ROOT_PACKAGE_FLAG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:48:27 +03:00
|
|
|
inter_package *Inter::Packages::parent(inter_package *pack) {
|
|
|
|
if (pack) {
|
2019-07-22 12:05:02 +03:00
|
|
|
if (Inter::Packages::is_rootlike(pack)) return NULL;
|
2019-07-26 21:20:27 +03:00
|
|
|
inter_tree_node *D = Inter::Packages::definition(pack);
|
2019-07-24 22:29:29 +03:00
|
|
|
inter_tree_node *P = Inter::Tree::parent(D);
|
2019-07-24 17:19:38 +03:00
|
|
|
if (P == NULL) return NULL;
|
2019-07-13 16:48:27 +03:00
|
|
|
return Inter::Package::defined_by_frame(P);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:17:48 +03:00
|
|
|
void Inter::Packages::unmark_all(void) {
|
|
|
|
inter_package *pack;
|
|
|
|
LOOP_OVER(pack, inter_package)
|
2019-07-26 21:20:27 +03:00
|
|
|
Inter::Packages::clear_flag(pack, MARK_PACKAGE_FLAG);
|
2019-07-13 16:17:48 +03:00
|
|
|
}
|
|
|
|
|
2019-02-05 02:44:07 +02:00
|
|
|
void Inter::Packages::set_scope(inter_package *P, inter_symbols_table *T) {
|
|
|
|
if (P == NULL) internal_error("null package");
|
|
|
|
P->package_scope = T;
|
|
|
|
if (T) T->owning_package = P;
|
|
|
|
}
|
|
|
|
|
2019-07-27 17:01:50 +03:00
|
|
|
void Inter::Packages::set_name(inter_package *Q, inter_package *P, text_stream *N) {
|
2019-02-05 02:44:07 +02:00
|
|
|
if (P == NULL) internal_error("null package");
|
|
|
|
if (N == NULL) internal_error("null package name");
|
2019-07-27 17:01:50 +03:00
|
|
|
P->package_name_t = Str::duplicate(N);
|
|
|
|
if ((N) && (Str::eq(P->package_name_t, I"main")))
|
2019-08-31 15:56:36 +03:00
|
|
|
Site::set_main_package(Inter::Packages::tree(P), P);
|
2019-07-27 17:01:50 +03:00
|
|
|
|
2019-08-02 20:51:21 +03:00
|
|
|
if (Str::len(N) > 0) Inter::Packages::add_subpackage_name(Q, P);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::add_subpackage_name(inter_package *Q, inter_package *P) {
|
|
|
|
if (Q == NULL) internal_error("no parent supplied");
|
|
|
|
text_stream *N = P->package_name_t;
|
|
|
|
dict_entry *de = Dictionaries::find(Q->name_lookup, N);
|
2019-09-01 13:50:12 +03:00
|
|
|
if (de) {
|
|
|
|
LOG("This would be the second '%S' in $6\n", N, Q);
|
|
|
|
internal_error("duplicated package name");
|
|
|
|
}
|
2019-08-02 20:51:21 +03:00
|
|
|
Dictionaries::create(Q->name_lookup, N);
|
|
|
|
Dictionaries::write_value(Q->name_lookup, N, (void *) P);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::remove_subpackage_name(inter_package *Q, inter_package *P) {
|
|
|
|
if (Q == NULL) internal_error("no parent supplied");
|
|
|
|
text_stream *N = P->package_name_t;
|
|
|
|
dict_entry *de = Dictionaries::find(Q->name_lookup, N);
|
|
|
|
if (de) {
|
|
|
|
Dictionaries::write_value(Q->name_lookup, N, NULL);
|
2019-07-27 17:01:50 +03:00
|
|
|
}
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::log(OUTPUT_STREAM, void *vp) {
|
|
|
|
inter_package *pack = (inter_package *) vp;
|
2019-07-26 21:20:27 +03:00
|
|
|
Inter::Packages::write_url_name(OUT, pack);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_package *Inter::Packages::basics(inter_tree *I) {
|
2019-07-27 17:01:50 +03:00
|
|
|
return Inter::Packages::by_url(I, I"/main/generic/basics");
|
2019-04-07 12:54:25 +03:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_package *Inter::Packages::veneer(inter_tree *I) {
|
2019-07-27 17:01:50 +03:00
|
|
|
return Inter::Packages::by_url(I, I"/main/veneer");
|
2019-06-10 10:30:20 +03:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_package *Inter::Packages::template(inter_tree *I) {
|
2019-07-27 17:01:50 +03:00
|
|
|
return Inter::Packages::by_url(I, I"/main/template");
|
2019-06-10 10:30:20 +03:00
|
|
|
}
|
|
|
|
|
2019-02-05 02:44:07 +02:00
|
|
|
inter_symbol *Inter::Packages::search_exhaustively(inter_package *P, text_stream *S) {
|
|
|
|
inter_symbol *found = Inter::SymbolsTables::symbol_from_name(Inter::Packages::scope(P), S);
|
|
|
|
if (found) return found;
|
2019-07-26 21:20:27 +03:00
|
|
|
inter_tree_node *D = Inter::Packages::definition(P);
|
2019-07-13 16:17:48 +03:00
|
|
|
LOOP_THROUGH_INTER_CHILDREN(C, D) {
|
2019-07-24 20:15:07 +03:00
|
|
|
if (C->W.data[ID_IFLD] == PACKAGE_IST) {
|
2019-07-13 16:17:48 +03:00
|
|
|
inter_package *Q = Inter::Package::defined_by_frame(C);
|
|
|
|
found = Inter::Packages::search_exhaustively(Q, S);
|
|
|
|
if (found) return found;
|
|
|
|
}
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_symbol *Inter::Packages::search_main_exhaustively(inter_tree *I, text_stream *S) {
|
2019-08-31 15:56:36 +03:00
|
|
|
return Inter::Packages::search_exhaustively(Site::main_package(I), S);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_symbol *Inter::Packages::search_resources_exhaustively(inter_tree *I, text_stream *S) {
|
2019-08-31 15:56:36 +03:00
|
|
|
inter_package *main_package = Site::main_package_if_it_exists(I);
|
2019-07-13 16:17:48 +03:00
|
|
|
if (main_package) {
|
2019-07-26 21:20:27 +03:00
|
|
|
inter_tree_node *D = Inter::Packages::definition(main_package);
|
2019-07-13 16:17:48 +03:00
|
|
|
LOOP_THROUGH_INTER_CHILDREN(C, D) {
|
2019-07-24 20:15:07 +03:00
|
|
|
if (C->W.data[ID_IFLD] == PACKAGE_IST) {
|
2019-07-13 16:17:48 +03:00
|
|
|
inter_package *Q = Inter::Package::defined_by_frame(C);
|
|
|
|
inter_symbol *found = Inter::Packages::search_exhaustively(Q, S);
|
|
|
|
if (found) return found;
|
|
|
|
}
|
|
|
|
}
|
2019-04-23 01:29:02 +03:00
|
|
|
}
|
2019-04-08 11:03:53 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2019-02-05 02:44:07 +02:00
|
|
|
inter_t Inter::Packages::to_PID(inter_package *P) {
|
|
|
|
if (P == NULL) return 0;
|
|
|
|
return P->index_n;
|
|
|
|
}
|
|
|
|
|
2019-07-24 20:15:07 +03:00
|
|
|
inter_package *Inter::Packages::container(inter_tree_node *P) {
|
2019-07-24 17:19:38 +03:00
|
|
|
if (P == NULL) return NULL;
|
2020-05-11 17:21:29 +03:00
|
|
|
inter_package *pack = Inode::get_package(P);
|
2019-07-23 01:34:28 +03:00
|
|
|
if (Inter::Packages::is_rootlike(pack)) return NULL;
|
|
|
|
return pack;
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inter_symbols_table *Inter::Packages::scope(inter_package *pack) {
|
|
|
|
if (pack == NULL) return NULL;
|
|
|
|
return pack->package_scope;
|
|
|
|
}
|
|
|
|
|
2019-07-24 20:15:07 +03:00
|
|
|
inter_symbols_table *Inter::Packages::scope_of(inter_tree_node *P) {
|
2019-02-05 02:44:07 +02:00
|
|
|
inter_package *pack = Inter::Packages::container(P);
|
|
|
|
if (pack) return pack->package_scope;
|
2020-05-11 17:21:29 +03:00
|
|
|
return Inode::globals(P);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
inter_symbol *Inter::Packages::type(inter_package *P) {
|
|
|
|
if (P == NULL) return NULL;
|
2019-07-27 13:16:22 +03:00
|
|
|
return Inter::Package::type(P);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int Inter::Packages::baseline(inter_package *P) {
|
|
|
|
if (P == NULL) return 0;
|
2019-07-23 01:34:28 +03:00
|
|
|
if (Inter::Packages::is_rootlike(P)) return 0;
|
2019-07-26 21:20:27 +03:00
|
|
|
return Inter::Defn::get_level(Inter::Packages::definition(P));
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
2019-07-13 16:17:48 +03:00
|
|
|
|
|
|
|
text_stream *Inter::Packages::read_metadata(inter_package *P, text_stream *key) {
|
|
|
|
if (P == NULL) return NULL;
|
|
|
|
inter_symbol *found = Inter::SymbolsTables::symbol_from_name(Inter::Packages::scope(P), key);
|
|
|
|
if ((found) && (Inter::Symbols::is_defined(found))) {
|
2019-07-24 20:15:07 +03:00
|
|
|
inter_tree_node *D = Inter::Symbols::definition(found);
|
|
|
|
inter_t val2 = D->W.data[VAL1_MD_IFLD + 1];
|
2019-07-26 12:14:17 +03:00
|
|
|
return Inter::Warehouse::get_text(Inter::Tree::warehouse(Inter::Packages::tree(P)), val2);
|
2019-07-13 16:17:48 +03:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-07-26 21:20:27 +03:00
|
|
|
|
|
|
|
void Inter::Packages::write_url_name(OUTPUT_STREAM, inter_package *P) {
|
|
|
|
if (P == NULL) { WRITE("<none>"); return; }
|
|
|
|
inter_package *chain[MAX_URL_SYMBOL_NAME_DEPTH];
|
|
|
|
int chain_length = 0;
|
|
|
|
while (P) {
|
|
|
|
if (chain_length >= MAX_URL_SYMBOL_NAME_DEPTH) internal_error("package nesting too deep");
|
|
|
|
chain[chain_length++] = P;
|
|
|
|
P = Inter::Packages::parent(P);
|
|
|
|
}
|
|
|
|
for (int i=chain_length-1; i>=0; i--) WRITE("/%S", Inter::Packages::name(chain[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
int Inter::Packages::get_flag(inter_package *P, int f) {
|
|
|
|
if (P == NULL) internal_error("no package");
|
|
|
|
return (P->package_flags & f)?TRUE:FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::set_flag(inter_package *P, int f) {
|
|
|
|
if (P == NULL) internal_error("no package");
|
|
|
|
P->package_flags = P->package_flags | f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::Packages::clear_flag(inter_package *P, int f) {
|
|
|
|
if (P == NULL) internal_error("no package");
|
|
|
|
if (P->package_flags & f) P->package_flags = P->package_flags - f;
|
|
|
|
}
|
2019-07-27 13:16:22 +03:00
|
|
|
|
|
|
|
inter_package *Inter::Packages::by_name(inter_package *P, text_stream *name) {
|
|
|
|
if (P == NULL) return NULL;
|
2019-07-27 17:01:50 +03:00
|
|
|
dict_entry *de = Dictionaries::find(P->name_lookup, name);
|
|
|
|
if (de) return (inter_package *) Dictionaries::read_value(P->name_lookup, name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
inter_package *Inter::Packages::by_url(inter_tree *I, text_stream *S) {
|
|
|
|
if (Str::get_first_char(S) == '/') {
|
|
|
|
inter_package *at_P = I->root_package;
|
|
|
|
TEMPORARY_TEXT(C);
|
|
|
|
LOOP_THROUGH_TEXT(P, S) {
|
|
|
|
wchar_t c = Str::get(P);
|
|
|
|
if (c == '/') {
|
|
|
|
if (Str::len(C) > 0) {
|
|
|
|
at_P = Inter::Packages::by_name(at_P, C);
|
|
|
|
if (at_P == NULL) return NULL;
|
|
|
|
}
|
|
|
|
Str::clear(C);
|
|
|
|
} else {
|
|
|
|
PUT_TO(C, c);
|
|
|
|
}
|
|
|
|
}
|
2019-09-22 18:43:06 +03:00
|
|
|
inter_package *pack = Inter::Packages::by_name(at_P, C);
|
|
|
|
DISCARD_TEXT(C);
|
|
|
|
return pack;
|
2019-07-27 17:01:50 +03:00
|
|
|
}
|
|
|
|
return Inter::Packages::by_name(I->root_package, S);
|
2019-07-27 13:16:22 +03:00
|
|
|
}
|