diff --git a/method_dispatcher/method_dispatcher.c b/method_dispatcher/method_dispatcher.c index 90e4fed..e26c553 100644 --- a/method_dispatcher/method_dispatcher.c +++ b/method_dispatcher/method_dispatcher.c @@ -118,3 +118,41 @@ bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree return NULL; } +dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree) +{ + dispatch_tree_autoinserter_t autoinserter = malloc( + sizeof(struct dispatch_tree_autoinserter_s)); + if(!autoinserter) + { + return NULL; + } + autoinserter->mayor = 2; + autoinserter->minor = 1; + autoinserter->tree = tree; + return autoinserter; +} + +void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter) +{ + free(autoinserter); +} + + +uint16_t dispatch_tree_autoinserter_t_insert( + dispatch_tree_autoinserter_t autoinserter + , bci_core_method_t method) +{ + uint16_t opcode = 0b1111111111; + opcode *= autoinserter->minor; + opcode /= autoinserter->mayor; + opcode <<= 6; + + dispatch_tree_t_insert(autoinserter->tree, opcode, method); + + autoinserter->minor = (autoinserter->minor + 2) % autoinserter->mayor; + if(autoinserter->minor == 1) + { + autoinserter->mayor *= 2; + } + return opcode; +} diff --git a/method_dispatcher/method_dispatcher.h b/method_dispatcher/method_dispatcher.h index fb40436..6b6dac9 100644 --- a/method_dispatcher/method_dispatcher.h +++ b/method_dispatcher/method_dispatcher.h @@ -49,13 +49,39 @@ char dispatch_tree_t_insert(dispatch_tree_t tree , uint16_t word , bci_core_method_t method); -// TODO: -// Figure out if that function is actually useful. -// Maybe manually inserting the methods in a good order -// is better. -// -//dispatch_tree_t optimize(dispatch_tree_t tree); bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree , uint16_t word); + + + +typedef struct dispatch_tree_autoinserter_s +{ + uint16_t mayor; + uint16_t minor; + dispatch_tree_t tree; +} * dispatch_tree_autoinserter_t; + +dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree); +void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter); + +/* + * This function inserts a new method into the tree and automatically + * chooses the optimal word to prevent degeneration. + * + * NOTE: + * When inserting mutliple methods this function acts deterministic, + * IF AND ONLY IF the order of the methods is not changed. + * + * The assembler will bring an analogous function that allows one + * to determine the opcodes of the methods. + * + * NOTE: + * This algorithm will not work for more that 1023 registered opcodes. + * This limit is however considered acceptable. + * + * */ +uint16_t dispatch_tree_autoinserter_t_insert( + dispatch_tree_autoinserter_t autoinserter + , bci_core_method_t method); #endif diff --git a/method_dispatcher/test/test_method_dispatcher.c b/method_dispatcher/test/test_method_dispatcher.c index ae1fff0..917e901 100644 --- a/method_dispatcher/test/test_method_dispatcher.c +++ b/method_dispatcher/test/test_method_dispatcher.c @@ -24,6 +24,18 @@ int main(void) dispatch_tree_t_dispatch(tree, i << 6)(i, NULL); } dispatch_tree_t_del(tree); + + + bci_core_method_t methods[5] = {m1, m2, m3, m4, m5}; + tree = dispatch_tree_t_new(); + dispatch_tree_autoinserter_t inserter = dispatch_tree_autoinserter_t_new(tree); + for(i = 0; i < 5; i++) + { + printf("%u\n", dispatch_tree_autoinserter_t_insert(inserter, methods[i])); + } + dispatch_tree_autoinserter_t_del(inserter); + dispatch_tree_t_del(tree); + return 0; }