2019-02-05 02:44:07 +02:00
|
|
|
[Inter::] Inter in Memory.
|
|
|
|
|
|
|
|
To store bytecode-like intermediate code in memory.
|
|
|
|
|
|
|
|
@h Bytecode definition.
|
|
|
|
|
|
|
|
@d inter_t unsigned int
|
|
|
|
@d signed_inter_t int
|
|
|
|
|
|
|
|
@h Chunks.
|
|
|
|
|
|
|
|
@d IST_SIZE 100
|
|
|
|
|
|
|
|
@d SYMBOL_BASE_VAL 0x40000000
|
|
|
|
|
|
|
|
@d PREFRAME_SKIP_AMOUNT 0
|
|
|
|
@d PREFRAME_VERIFICATION_COUNT 1
|
|
|
|
@d PREFRAME_ORIGIN 2
|
|
|
|
@d PREFRAME_COMMENT 3
|
|
|
|
@d PREFRAME_PACKAGE 4
|
2019-07-09 12:32:05 +03:00
|
|
|
@d PREFRAME_PARENT 5
|
2019-07-11 11:15:57 +03:00
|
|
|
@d PREFRAME_FIRST_CHILD 6
|
|
|
|
@d PREFRAME_LAST_CHILD 7
|
|
|
|
@d PREFRAME_PREVIOUS 8
|
|
|
|
@d PREFRAME_NEXT 9
|
2019-07-22 02:01:18 +03:00
|
|
|
@d PREFRAME_GLOBALS 10
|
|
|
|
@d PREFRAME_SIZE 11
|
2019-02-05 02:44:07 +02:00
|
|
|
|
|
|
|
=
|
2019-07-22 02:01:18 +03:00
|
|
|
typedef struct inter_tree {
|
2019-07-22 12:05:02 +03:00
|
|
|
struct inter_frame root_definition_frame;
|
|
|
|
struct inter_package *root_package;
|
2019-02-05 02:44:07 +02:00
|
|
|
struct inter_package *main_package;
|
|
|
|
MEMORY_MANAGEMENT
|
2019-07-22 02:01:18 +03:00
|
|
|
} inter_tree;
|
2019-02-05 02:44:07 +02:00
|
|
|
|
|
|
|
@ =
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_tree *Inter::create(void) {
|
|
|
|
inter_tree *I = CREATE(inter_tree);
|
2019-02-05 02:44:07 +02:00
|
|
|
I->main_package = NULL;
|
|
|
|
|
2019-07-23 22:07:01 +03:00
|
|
|
inter_warehouse *warehouse = Inter::Warehouse::new();
|
|
|
|
inter_t N = Inter::Warehouse::create_symbols_table(warehouse);
|
|
|
|
inter_symbols_table *globals = Inter::Warehouse::get_symbols_table(warehouse, N);
|
|
|
|
I->root_package = Inter::Warehouse::get_package(warehouse, Inter::Warehouse::create_package(warehouse, I));
|
|
|
|
I->root_definition_frame = Inter::Frame::root_frame(warehouse, globals);
|
2019-07-22 12:05:02 +03:00
|
|
|
Inter::Packages::make_rootlike(I->root_package);
|
2019-07-23 22:07:01 +03:00
|
|
|
Inter::Packages::set_scope(I->root_package, globals);
|
|
|
|
Inter::Warehouse::attribute_resource(warehouse, N, I->root_package);
|
2019-07-22 02:01:18 +03:00
|
|
|
return I;
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_warehouse *Inter::warehouse(inter_tree *I) {
|
2019-07-23 22:07:01 +03:00
|
|
|
return Inter::Frame::warehouse(&(I->root_definition_frame));
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_symbols_table *Inter::get_global_symbols(inter_tree *I) {
|
2019-07-22 12:05:02 +03:00
|
|
|
return Inter::Packages::scope(I->root_package);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_symbols_table *Inter::get_symbols_table(inter_tree *I, inter_t n) {
|
2019-07-23 02:13:47 +03:00
|
|
|
return Inter::Warehouse::get_symbols_table(Inter::warehouse(I), n);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_package *Inter::get_package(inter_tree *I, inter_t n) {
|
2019-07-23 02:13:47 +03:00
|
|
|
return Inter::Warehouse::get_package(Inter::warehouse(I), n);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_t Inter::create_text(inter_tree *I) {
|
2019-07-23 22:07:01 +03:00
|
|
|
return Inter::Warehouse::create_text(Inter::warehouse(I), NULL);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
text_stream *Inter::get_text(inter_tree *I, inter_t n) {
|
2019-07-23 02:13:47 +03:00
|
|
|
return Inter::Warehouse::get_text(Inter::warehouse(I), n);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
void *Inter::get_ref(inter_tree *I, inter_t n) {
|
2019-07-23 02:13:47 +03:00
|
|
|
return Inter::Warehouse::get_ref(Inter::warehouse(I), n);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
void Inter::set_ref(inter_tree *I, inter_t n, void *ref) {
|
|
|
|
inter_warehouse *warehouse = Inter::warehouse(I);
|
|
|
|
if (n >= (inter_t) warehouse->size) return;
|
|
|
|
warehouse->stored_resources[n].stored_ref = ref;
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_frame_list *Inter::new_frame_list(void) {
|
|
|
|
inter_frame_list *ifl = CREATE(inter_frame_list);
|
|
|
|
ifl->spare_storage = NULL;
|
|
|
|
ifl->storage_used = 0;
|
|
|
|
ifl->storage_capacity = 0;
|
|
|
|
ifl->first_in_ifl = NULL;
|
|
|
|
ifl->last_in_ifl = NULL;
|
|
|
|
return ifl;
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
typedef struct inter_frame_list {
|
|
|
|
int storage_used;
|
|
|
|
int storage_capacity;
|
|
|
|
struct inter_frame_list_entry *spare_storage;
|
|
|
|
struct inter_frame_list_entry *first_in_ifl;
|
|
|
|
struct inter_frame_list_entry *last_in_ifl;
|
|
|
|
MEMORY_MANAGEMENT
|
|
|
|
} inter_frame_list;
|
|
|
|
|
|
|
|
typedef struct inter_frame_list_entry {
|
|
|
|
struct inter_frame listed_frame;
|
|
|
|
struct inter_frame_list_entry *next_in_ifl;
|
|
|
|
struct inter_frame_list_entry *prev_in_ifl;
|
|
|
|
MEMORY_MANAGEMENT
|
|
|
|
} inter_frame_list_entry;
|
2019-02-05 02:44:07 +02:00
|
|
|
|
|
|
|
@
|
|
|
|
|
|
|
|
@d LOOP_THROUGH_INTER_FRAME_LIST(F, ifl)
|
2019-07-10 12:27:52 +03:00
|
|
|
for (inter_frame_list_entry *F##_entry = (ifl)?(ifl->first_in_ifl):NULL; F##_entry; F##_entry = F##_entry->next_in_ifl)
|
2019-07-11 22:38:01 +03:00
|
|
|
if (Inter::Frame::valid(((F = F##_entry->listed_frame), &F)))
|
2019-02-05 02:44:07 +02:00
|
|
|
|
|
|
|
=
|
2019-07-22 02:01:18 +03:00
|
|
|
inter_frame_list *Inter::find_frame_list(inter_tree *I, inter_t N) {
|
2019-02-05 02:44:07 +02:00
|
|
|
if (I == NULL) return NULL;
|
2019-07-23 02:13:47 +03:00
|
|
|
return Inter::Warehouse::get_frame_list(Inter::warehouse(I), N);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::first_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::second_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
int c = 0;
|
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
if (++c == 2)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::third_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
int c = 0;
|
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
if (++c == 3)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::fourth_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
int c = 0;
|
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
if (++c == 4)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::fifth_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
int c = 0;
|
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
if (++c == 5)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-10 12:27:52 +03:00
|
|
|
inter_frame Inter::sixth_child(inter_frame P) {
|
2019-07-11 11:15:57 +03:00
|
|
|
int c = 0;
|
|
|
|
LOOP_THROUGH_INTER_CHILDREN(F, P)
|
|
|
|
if (++c == 6)
|
|
|
|
return F;
|
|
|
|
return Inter::Frame::around(NULL, -1);
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
2019-07-11 11:15:57 +03:00
|
|
|
void Inter::add_to_frame_list(inter_frame_list *FL, inter_frame F) {
|
2019-02-05 02:44:07 +02:00
|
|
|
if (Inter::Frame::valid(&F) == FALSE) internal_error("linked imvalid frame");
|
|
|
|
if (FL == NULL) internal_error("bad frame list");
|
|
|
|
if (FL->storage_used >= FL->storage_capacity) {
|
|
|
|
int new_size = 128;
|
|
|
|
while (new_size < 2*FL->storage_capacity) new_size = 2*new_size;
|
|
|
|
|
|
|
|
inter_frame_list_entry *storage = (inter_frame_list_entry *) Memory::I7_calloc(new_size, sizeof(inter_frame_list_entry), INTER_LINKS_MREASON);
|
|
|
|
FL->spare_storage = storage;
|
|
|
|
FL->storage_used = 0;
|
|
|
|
FL->storage_capacity = new_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
inter_frame_list_entry *entry = &(FL->spare_storage[FL->storage_used ++]);
|
|
|
|
entry->listed_frame = F;
|
|
|
|
entry->next_in_ifl = NULL;
|
2019-07-11 11:15:57 +03:00
|
|
|
entry->prev_in_ifl = FL->last_in_ifl;
|
|
|
|
if (FL->last_in_ifl) FL->last_in_ifl->next_in_ifl = entry;
|
|
|
|
FL->last_in_ifl = entry;
|
|
|
|
if (FL->first_in_ifl == NULL) FL->first_in_ifl = entry;
|
2019-02-05 02:44:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct inter_error_stash {
|
|
|
|
struct inter_error_location stashed_eloc;
|
|
|
|
struct text_file_position stashed_tfp;
|
|
|
|
MEMORY_MANAGEMENT
|
|
|
|
} inter_error_stash;
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
void Inter::traverse_global_list(inter_tree *from, void (*visitor)(inter_tree *, inter_frame, void *), void *state, int filter) {
|
2019-07-22 12:05:02 +03:00
|
|
|
PROTECTED_LOOP_THROUGH_INTER_CHILDREN(P, (from->root_definition_frame)) {
|
2019-07-13 19:15:26 +03:00
|
|
|
if ((filter == 0) ||
|
|
|
|
((filter > 0) && (P.data[ID_IFLD] == (inter_t) filter)) ||
|
|
|
|
((filter < 0) && (P.data[ID_IFLD] != (inter_t) -filter)))
|
|
|
|
(*visitor)(from, P, state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-22 02:01:18 +03:00
|
|
|
void Inter::set_mask(inter_tree *I, inter_package *mp) {
|
|
|
|
if (mp) {
|
|
|
|
while (mp) {
|
|
|
|
inter_package *par = Inter::Packages::parent(mp);
|
|
|
|
if (par) par->mask_down = mp;
|
|
|
|
mp = par;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mp = Inter::Packages::main(I);
|
|
|
|
while (mp->mask_down) {
|
|
|
|
inter_package *ch = mp->mask_down;
|
|
|
|
mp->mask_down = NULL;
|
|
|
|
mp = ch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Inter::traverse_tree(inter_tree *from, void (*visitor)(inter_tree *, inter_frame, void *), void *state, inter_package *mp, int filter) {
|
2019-07-13 19:15:26 +03:00
|
|
|
if (mp == NULL) mp = Inter::Packages::main(from);
|
|
|
|
if (mp) {
|
2019-07-22 02:01:18 +03:00
|
|
|
while (mp->mask_down) {
|
|
|
|
inter_frame D = Inter::Symbols::defining_frame(mp->package_name);
|
|
|
|
mp = mp->mask_down;
|
|
|
|
if ((filter == 0) ||
|
|
|
|
((filter > 0) && (D.data[ID_IFLD] == (inter_t) filter)) ||
|
|
|
|
((filter < 0) && (D.data[ID_IFLD] != (inter_t) -filter)))
|
|
|
|
(*visitor)(from, D, state);
|
|
|
|
Inter::traverse_tree_r(from, D, visitor, state, filter);
|
|
|
|
}
|
2019-07-13 19:15:26 +03:00
|
|
|
inter_frame D = Inter::Symbols::defining_frame(mp->package_name);
|
|
|
|
if ((filter == 0) ||
|
|
|
|
((filter > 0) && (D.data[ID_IFLD] == (inter_t) filter)) ||
|
|
|
|
((filter < 0) && (D.data[ID_IFLD] != (inter_t) -filter)))
|
|
|
|
(*visitor)(from, D, state);
|
|
|
|
Inter::traverse_tree_r(from, D, visitor, state, filter);
|
|
|
|
}
|
|
|
|
}
|
2019-07-22 02:01:18 +03:00
|
|
|
void Inter::traverse_tree_r(inter_tree *from, inter_frame P, void (*visitor)(inter_tree *, inter_frame, void *), void *state, int filter) {
|
2019-07-13 19:15:26 +03:00
|
|
|
PROTECTED_LOOP_THROUGH_INTER_CHILDREN(C, P) {
|
|
|
|
if ((filter == 0) ||
|
|
|
|
((filter > 0) && (C.data[ID_IFLD] == (inter_t) filter)) ||
|
|
|
|
((filter < 0) && (C.data[ID_IFLD] != (inter_t) -filter)))
|
|
|
|
(*visitor)(from, C, state);
|
|
|
|
Inter::traverse_tree_r(from, C, visitor, state, filter);
|
|
|
|
}
|
|
|
|
}
|