1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-05 16:44:21 +03:00
inform7/inter/bytecode-module/Chapter 2/Bookmarks.w

189 lines
6.4 KiB
OpenEdge ABL
Raw Normal View History

2019-02-05 02:44:07 +02:00
[Inter::Bookmarks::] Bookmarks.
Write positions for inter code being generated.
2019-07-24 22:29:29 +03:00
@
@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
=
2019-07-14 12:44:07 +03:00
typedef struct inter_bookmark {
2019-07-24 20:15:07 +03:00
struct inter_tree_node *R;
int placement_wrt_R;
2019-07-14 12:44:07 +03:00
} inter_bookmark;
2019-02-05 02:44:07 +02:00
inter_bookmark Inter::Bookmarks::at_start_of_this_repository(inter_tree *I) {
2019-07-14 12:44:07 +03:00
inter_bookmark IBM;
2019-07-24 20:15:07 +03:00
IBM.R = I->root_node;
2019-07-14 12:44:07 +03:00
IBM.placement_wrt_R = AFTER_ICPLACEMENT;
return IBM;
2019-02-05 02:44:07 +02:00
}
2019-07-14 12:44:07 +03:00
inter_bookmark Inter::Bookmarks::at_end_of_this_package(inter_package *pack) {
if (pack == NULL) internal_error("no package supplied");
inter_bookmark IBM;
2019-07-26 21:20:27 +03:00
IBM.R = Inter::Packages::definition(pack);
2019-07-14 12:44:07 +03:00
IBM.placement_wrt_R = AS_LAST_CHILD_OF_ICPLACEMENT;
return IBM;
2019-02-05 02:44:07 +02:00
}
2019-08-02 20:51:21 +03:00
inter_bookmark Inter::Bookmarks::after_this_node(inter_tree *I, inter_tree_node *D) {
if (D == NULL) internal_error("invalid frame supplied");
2019-07-14 12:44:07 +03:00
inter_bookmark IBM;
IBM.R = D;
IBM.placement_wrt_R = AFTER_ICPLACEMENT;
return IBM;
2019-02-05 02:44:07 +02:00
}
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;
}
2019-07-14 12:44:07 +03:00
void Inter::Bookmarks::set_current_package(inter_bookmark *IBM, inter_package *P) {
if (IBM == NULL) internal_error("no bookmark supplied");
2019-07-23 01:34:28 +03:00
if (P == NULL) internal_error("invalid package supplied");
2019-07-26 21:20:27 +03:00
inter_tree_node *D = Inter::Packages::definition(P);
2019-07-26 12:14:17 +03:00
if (D == NULL) D = Inter::Packages::tree(P)->root_node;
2021-04-16 00:42:28 +03:00
IBM->R = InterTree::last_child(D);
2019-07-24 22:29:29 +03:00
IBM->placement_wrt_R = AFTER_ICPLACEMENT;
if (IBM->R == NULL) {
IBM->R = D;
2019-07-24 22:29:29 +03:00
IBM->placement_wrt_R = AS_FIRST_CHILD_OF_ICPLACEMENT;
2019-07-23 01:34:28 +03:00
}
2019-07-14 12:44:07 +03:00
}
2019-07-24 22:29:29 +03:00
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) {
2021-04-16 00:42:28 +03:00
return InterTree::warehouse(Inter::Bookmarks::tree(IBM));
2019-07-24 22:29:29 +03:00
}
2019-07-14 12:44:07 +03:00
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;
2019-07-14 02:33:50 +03:00
}
2019-07-24 20:15:07 +03:00
inter_tree_node *Inter::Bookmarks::get_ref(inter_bookmark *IBM) {
2019-07-14 12:44:07 +03:00
if (IBM == NULL) internal_error("no bookmark supplied");
return IBM->R;
2019-07-14 02:33:50 +03:00
}
2019-07-24 20:15:07 +03:00
void Inter::Bookmarks::set_ref(inter_bookmark *IBM, inter_tree_node *F) {
2019-07-14 12:44:07 +03:00
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) {
2019-07-24 22:29:29 +03:00
inter_package *pack = Inter::Bookmarks::package(IBM);
if (pack) return Inter::Packages::baseline(pack);
2019-07-14 12:44:07 +03:00
return 0;
2019-02-05 02:44:07 +02:00
}
void Inter::Bookmarks::log(OUTPUT_STREAM, void *virs) {
2019-07-14 12:44:07 +03:00
inter_bookmark *IBM = (inter_bookmark *) virs;
if (IBM == NULL) WRITE("<null-bookmark>");
2019-02-05 02:44:07 +02:00
else {
2019-07-24 22:29:29 +03:00
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);
}
2019-07-14 12:44:07 +03:00
LOG("(%d)>", Inter::Bookmarks::baseline(IBM));
2019-02-05 02:44:07 +02:00
}
}
2019-07-14 12:44:07 +03:00
inter_symbols_table *Inter::Bookmarks::scope(inter_bookmark *IBM) {
2019-07-24 22:29:29 +03:00
inter_package *pack = Inter::Bookmarks::package(IBM);
if (pack) return Inter::Packages::scope(pack);
2021-04-16 00:42:28 +03:00
return InterTree::global_scope(Inter::Bookmarks::tree(IBM));
2019-02-05 02:44:07 +02:00
}
2019-07-14 12:44:07 +03:00
inter_package *Inter::Bookmarks::package(inter_bookmark *IBM) {
2019-07-24 22:29:29 +03:00
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;
2019-02-05 02:44:07 +02:00
}
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);
2019-07-26 12:14:17 +03:00
inter_tree *I = Inter::Packages::tree(pack);
LOGIF(INTER_FRAMES, "Insert frame %F\n", *F);
2020-07-01 02:58:55 +03:00
inter_ti F_level = F->W.data[LEVEL_IFLD];
if (F_level == 0) {
2021-04-16 00:42:28 +03:00
if (InterTree::parent(Inter::Bookmarks::get_ref(IBM)) == NULL)
InterTree::place(F, AS_LAST_CHILD_OF_ICPLACEMENT, I->root_node);
else
2021-04-16 00:42:28 +03:00
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);
2021-04-16 00:42:28 +03:00
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) {
2021-04-16 00:42:28 +03:00
InterTree::place(F, AS_FIRST_CHILD_OF_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
Inter::Bookmarks::set_placement(IBM, AFTER_ICPLACEMENT);
} else {
2021-04-16 00:42:28 +03:00
InterTree::place(F, AS_LAST_CHILD_OF_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
}
} else {
2021-04-16 00:42:28 +03:00
InterTree::place(F, AFTER_ICPLACEMENT, Inter::Bookmarks::get_ref(IBM));
}
Inter::Bookmarks::set_ref(IBM, F);
return;
}
2021-04-16 00:42:28 +03:00
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);
}
}
}