mirror of
https://github.com/ganelson/inform.git
synced 2024-07-05 16:44:21 +03:00
189 lines
6.4 KiB
OpenEdge ABL
189 lines
6.4 KiB
OpenEdge ABL
[Inter::Bookmarks::] Bookmarks.
|
|
|
|
Write positions for inter code being generated.
|
|
|
|
@
|
|
|
|
@e BEFORE_ICPLACEMENT from 0
|
|
@e AFTER_ICPLACEMENT
|
|
@e IMMEDIATELY_AFTER_ICPLACEMENT
|
|
@e AS_FIRST_CHILD_OF_ICPLACEMENT
|
|
@e AS_LAST_CHILD_OF_ICPLACEMENT
|
|
@e NOWHERE_ICPLACEMENT
|
|
|
|
=
|
|
typedef struct inter_bookmark {
|
|
struct inter_tree_node *R;
|
|
int placement_wrt_R;
|
|
} inter_bookmark;
|
|
|
|
inter_bookmark Inter::Bookmarks::at_start_of_this_repository(inter_tree *I) {
|
|
inter_bookmark IBM;
|
|
IBM.R = I->root_node;
|
|
IBM.placement_wrt_R = AFTER_ICPLACEMENT;
|
|
return IBM;
|
|
}
|
|
|
|
inter_bookmark Inter::Bookmarks::at_end_of_this_package(inter_package *pack) {
|
|
if (pack == NULL) internal_error("no package supplied");
|
|
inter_bookmark IBM;
|
|
IBM.R = Inter::Packages::definition(pack);
|
|
IBM.placement_wrt_R = AS_LAST_CHILD_OF_ICPLACEMENT;
|
|
return IBM;
|
|
}
|
|
|
|
inter_bookmark Inter::Bookmarks::after_this_node(inter_tree *I, inter_tree_node *D) {
|
|
if (D == NULL) internal_error("invalid frame supplied");
|
|
inter_bookmark IBM;
|
|
IBM.R = D;
|
|
IBM.placement_wrt_R = AFTER_ICPLACEMENT;
|
|
return IBM;
|
|
}
|
|
|
|
inter_bookmark Inter::Bookmarks::first_child_of_this_node(inter_tree *I, inter_tree_node *D) {
|
|
if (D == NULL) internal_error("invalid frame supplied");
|
|
inter_bookmark IBM;
|
|
IBM.R = D;
|
|
IBM.placement_wrt_R = AS_FIRST_CHILD_OF_ICPLACEMENT;
|
|
return IBM;
|
|
}
|
|
|
|
void Inter::Bookmarks::set_current_package(inter_bookmark *IBM, inter_package *P) {
|
|
if (IBM == NULL) internal_error("no bookmark supplied");
|
|
if (P == NULL) internal_error("invalid package supplied");
|
|
inter_tree_node *D = Inter::Packages::definition(P);
|
|
if (D == NULL) D = Inter::Packages::tree(P)->root_node;
|
|
IBM->R = InterTree::last_child(D);
|
|
IBM->placement_wrt_R = AFTER_ICPLACEMENT;
|
|
if (IBM->R == NULL) {
|
|
IBM->R = D;
|
|
IBM->placement_wrt_R = AS_FIRST_CHILD_OF_ICPLACEMENT;
|
|
}
|
|
}
|
|
|
|
inter_tree *Inter::Bookmarks::tree(inter_bookmark *IBM) {
|
|
if (IBM == NULL) return NULL;
|
|
return IBM->R->tree;
|
|
}
|
|
|
|
inter_warehouse *Inter::Bookmarks::warehouse(inter_bookmark *IBM) {
|
|
return InterTree::warehouse(Inter::Bookmarks::tree(IBM));
|
|
}
|
|
|
|
int Inter::Bookmarks::get_placement(inter_bookmark *IBM) {
|
|
if (IBM == NULL) internal_error("no bookmark supplied");
|
|
return IBM->placement_wrt_R;
|
|
}
|
|
|
|
void Inter::Bookmarks::set_placement(inter_bookmark *IBM, int p) {
|
|
if (IBM == NULL) internal_error("no bookmark supplied");
|
|
IBM->placement_wrt_R = p;
|
|
}
|
|
|
|
inter_tree_node *Inter::Bookmarks::get_ref(inter_bookmark *IBM) {
|
|
if (IBM == NULL) internal_error("no bookmark supplied");
|
|
return IBM->R;
|
|
}
|
|
|
|
void Inter::Bookmarks::set_ref(inter_bookmark *IBM, inter_tree_node *F) {
|
|
if (IBM == NULL) internal_error("no bookmark supplied");
|
|
IBM->R = F;
|
|
}
|
|
|
|
inter_bookmark Inter::Bookmarks::snapshot(inter_bookmark *IBM) {
|
|
return *IBM;
|
|
}
|
|
|
|
int Inter::Bookmarks::baseline(inter_bookmark *IBM) {
|
|
inter_package *pack = Inter::Bookmarks::package(IBM);
|
|
if (pack) return Inter::Packages::baseline(pack);
|
|
return 0;
|
|
}
|
|
|
|
void Inter::Bookmarks::log(OUTPUT_STREAM, void *virs) {
|
|
inter_bookmark *IBM = (inter_bookmark *) virs;
|
|
if (IBM == NULL) WRITE("<null-bookmark>");
|
|
else {
|
|
LOG("<");
|
|
switch (IBM->placement_wrt_R) {
|
|
case BEFORE_ICPLACEMENT: WRITE("before:"); break;
|
|
case AFTER_ICPLACEMENT: WRITE("after:"); break;
|
|
case IMMEDIATELY_AFTER_ICPLACEMENT: WRITE("immediately-after:"); break;
|
|
case AS_FIRST_CHILD_OF_ICPLACEMENT: WRITE("first-child:"); break;
|
|
case AS_LAST_CHILD_OF_ICPLACEMENT: WRITE("last-child:"); break;
|
|
case NOWHERE_ICPLACEMENT: WRITE("nowhere"); break;
|
|
default: WRITE("?:"); break;
|
|
}
|
|
if (IBM->placement_wrt_R != NOWHERE_ICPLACEMENT) {
|
|
if (IBM->R) WRITE("%d", IBM->R->W.index);
|
|
}
|
|
LOG("(%d)>", Inter::Bookmarks::baseline(IBM));
|
|
}
|
|
}
|
|
|
|
inter_symbols_table *Inter::Bookmarks::scope(inter_bookmark *IBM) {
|
|
inter_package *pack = Inter::Bookmarks::package(IBM);
|
|
if (pack) return Inter::Packages::scope(pack);
|
|
return InterTree::global_scope(Inter::Bookmarks::tree(IBM));
|
|
}
|
|
|
|
inter_package *Inter::Bookmarks::package(inter_bookmark *IBM) {
|
|
if (IBM == NULL) return NULL;
|
|
inter_package *pack = IBM->R->package;
|
|
if ((IBM->placement_wrt_R == AS_FIRST_CHILD_OF_ICPLACEMENT) ||
|
|
(IBM->placement_wrt_R == AS_LAST_CHILD_OF_ICPLACEMENT)) {
|
|
inter_package *R_defined = Inter::Package::defined_by_frame(IBM->R);
|
|
if (R_defined) pack = R_defined;
|
|
}
|
|
return pack;
|
|
}
|
|
|
|
void Inter::Bookmarks::insert(inter_bookmark *IBM, inter_tree_node *F) {
|
|
if (F == NULL) internal_error("no frame to insert");
|
|
if (IBM == NULL) internal_error("nowhere to insert");
|
|
inter_package *pack = Inter::Bookmarks::package(IBM);
|
|
inter_tree *I = Inter::Packages::tree(pack);
|
|
LOGIF(INTER_FRAMES, "Insert frame %F\n", *F);
|
|
inter_ti F_level = F->W.data[LEVEL_IFLD];
|
|
if (F_level == 0) {
|
|
if (InterTree::parent(Inter::Bookmarks::get_ref(IBM)) == NULL)
|
|
InterTree::place(F, AS_LAST_CHILD_OF_ICPLACEMENT, I->root_node);
|
|
else
|
|
InterTree::place(F, Inter::Bookmarks::get_placement(IBM), Inter::Bookmarks::get_ref(IBM));
|
|
if ((Inter::Bookmarks::get_placement(IBM) == AFTER_ICPLACEMENT) ||
|
|
(Inter::Bookmarks::get_placement(IBM) == IMMEDIATELY_AFTER_ICPLACEMENT)) {
|
|
Inter::Bookmarks::set_ref(IBM, F);
|
|
}
|
|
} else {
|
|
if (Inter::Bookmarks::get_placement(IBM) == NOWHERE_ICPLACEMENT) internal_error("bad wrt");
|
|
if ((Inter::Bookmarks::get_placement(IBM) == AFTER_ICPLACEMENT) ||
|
|
(Inter::Bookmarks::get_placement(IBM) == IMMEDIATELY_AFTER_ICPLACEMENT)) {
|
|
while (F_level < Inter::Bookmarks::get_ref(IBM)->W.data[LEVEL_IFLD]) {
|
|
inter_tree_node *R = Inter::Bookmarks::get_ref(IBM);
|
|
inter_tree_node *PR = InterTree::parent(R);
|
|
if (PR == NULL) internal_error("bubbled up out of tree");
|
|
Inter::Bookmarks::set_ref(IBM, PR);
|
|
}
|
|
if (F_level > Inter::Bookmarks::get_ref(IBM)->W.data[LEVEL_IFLD] + 1) internal_error("bubbled down off of tree");
|
|
if (F_level == Inter::Bookmarks::get_ref(IBM)->W.data[LEVEL_IFLD] + 1) {
|
|
if (Inter::Bookmarks::get_placement(IBM) == IMMEDIATELY_AFTER_ICPLACEMENT) {
|
|
InterTree::place(F, AS_FIRST_CHILD_OF_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
|
|
Inter::Bookmarks::set_placement(IBM, AFTER_ICPLACEMENT);
|
|
} else {
|
|
InterTree::place(F, AS_LAST_CHILD_OF_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
|
|
}
|
|
} else {
|
|
InterTree::place(F, AFTER_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
|
|
}
|
|
Inter::Bookmarks::set_ref(IBM, F);
|
|
return;
|
|
}
|
|
InterTree::place(F, Inter::Bookmarks::get_placement(IBM), Inter::Bookmarks::get_ref(IBM));
|
|
if (Inter::Bookmarks::get_placement(IBM) == AS_FIRST_CHILD_OF_ICPLACEMENT) {
|
|
Inter::Bookmarks::set_ref(IBM, F);
|
|
Inter::Bookmarks::set_placement(IBM, AFTER_ICPLACEMENT);
|
|
}
|
|
}
|
|
}
|
|
|