diff --git a/include/interpreter.h b/include/interpreter.h index 299deb6..a6a0ca8 100644 --- a/include/interpreter.h +++ b/include/interpreter.h @@ -6,14 +6,14 @@ #include "tree.h" struct libab_interpreter_s { - libab_table* base_table; + libab_ref base_table; libab_number_impl* impl; }; typedef struct libab_interpreter_s libab_interpreter; void libab_interpreter_init(libab_interpreter* intr, - libab_table* table, libab_number_impl* impl); + libab_ref* table, libab_number_impl* impl); libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree, libab_ref* into); void libab_interpreter_free(libab_interpreter* intr); diff --git a/include/libabacus.h b/include/libabacus.h index beb4ce9..451d317 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -29,7 +29,7 @@ struct libab_s { * The table used to store top-level * things like functions and operators. */ - libab_table table; + libab_ref table; /** * The number implementation used by this instance. */ diff --git a/include/parser.h b/include/parser.h index 4810aac..268a90f 100644 --- a/include/parser.h +++ b/include/parser.h @@ -12,7 +12,7 @@ * tokens into trees. */ struct libab_parser_s { - libab_table* base_table; + libab_ref base_table; }; typedef struct libab_parser_s libab_parser; @@ -22,7 +22,7 @@ typedef struct libab_parser_s libab_parser; * @param parser the parser to intialize. * @param table the table of "reserved" entries like operators. */ -void libab_parser_init(libab_parser* parser, libab_table* table); +void libab_parser_init(libab_parser* parser, libab_ref* table); /** * Parses the given list of tokens into the given tree pointer. * @param parser the parser to use for parsing text. diff --git a/include/util.h b/include/util.h index c1b1a30..036c925 100644 --- a/include/util.h +++ b/include/util.h @@ -65,5 +65,12 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve, */ libab_result libab_instantiate_basetype(libab_basetype* to_instantiate, libab_ref* into, size_t n, ...); +/** + * Creates a new libab_table, and stores it into the given reference. + * @param into the reference to store the table into. + * @param parent the parent reference to store. + * @return the result of the instantiation. + */ +libab_result libab_create_table(libab_ref* into, libab_ref* parent); #endif diff --git a/src/interpreter.c b/src/interpreter.c index 41f7660..1d79830 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -2,13 +2,12 @@ #include "util.h" void libab_interpreter_init(libab_interpreter* intr, - libab_table* table, libab_number_impl* impl) { - intr->base_table = table; + libab_ref* table, libab_number_impl* impl) { + libab_ref_copy(table, &intr->base_table); intr->impl = impl; } struct interpreter_state { - libab_table* base_table; libab_number_impl* impl; libab_ref num_ref; }; @@ -16,11 +15,10 @@ struct interpreter_state { libab_result _interpreter_init(struct interpreter_state* state, libab_interpreter* intr) { libab_result result = LIBAB_SUCCESS; libab_basetype* num_type; - state->base_table = intr->base_table; state->impl = intr->impl; libab_ref_null(&state->num_ref); - num_type = libab_table_search_basetype(state->base_table, "num"); + num_type = libab_table_search_basetype(libab_ref_get(&intr->base_table), "num"); if(num_type != NULL) { libab_ref_free(&state->num_ref); result = libab_instantiate_basetype(num_type, &state->num_ref, 0); @@ -37,32 +35,6 @@ void _interpreter_free(struct interpreter_state* state) { libab_ref_free(&state->num_ref); } -void _free_table(void* data) { - libab_table_free(data); - free(data); -} - -libab_result _make_scope(libab_ref* into, libab_ref* parent) { - libab_table* table; - libab_result result = LIBAB_SUCCESS; - if((table = malloc(sizeof(*table)))) { - libab_table_init(table); - result = libab_ref_new(into, table, _free_table); - - if(result != LIBAB_SUCCESS) { - _free_table(table); - } - } else { - result = LIBAB_MALLOC; - } - - if(result != LIBAB_SUCCESS) { - libab_ref_null(into); - } - - return result; -} - libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, libab_ref* into, libab_ref* scope, int force_scope) { @@ -71,7 +43,7 @@ libab_result _interpreter_run(struct interpreter_state* state, int needs_scope = libab_tree_has_scope(tree->variant) || force_scope; if(needs_scope) { - result = _make_scope(&new_scope, scope); + result = libab_create_table(&new_scope, scope); scope = &new_scope; } @@ -99,7 +71,7 @@ libab_result libab_interpreter_run(libab_interpreter* intr, libab_result result = _interpreter_init(&state, intr); if(result == LIBAB_SUCCESS) { - result = _interpreter_run(&state, tree, into, NULL, 1); + result = _interpreter_run(&state, tree, into, &intr->base_table, 1); if(result != LIBAB_SUCCESS) { _interpreter_free(&state); } @@ -111,5 +83,5 @@ libab_result libab_interpreter_run(libab_interpreter* intr, } void libab_interpreter_free(libab_interpreter* intr) { - + libab_ref_free(&intr->base_table); } diff --git a/src/libabacus.c b/src/libabacus.c index 315d2e2..965ed9e 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -5,20 +5,26 @@ #include libab_result libab_init(libab* ab) { + libab_ref null_ref; libab_result result; - libab_table_init(&ab->table); - libab_parser_init(&ab->parser, &ab->table); - result = libab_lexer_init(&ab->lexer); + libab_ref_null(&null_ref); + result = libab_create_table(&ab->table, &null_ref); + + if(result == LIBAB_SUCCESS) { + libab_parser_init(&ab->parser, &ab->table); + result = libab_lexer_init(&ab->lexer); + } if (result == LIBAB_SUCCESS) { result = libab_register_reserved_operators(&ab->lexer); } if (result != LIBAB_SUCCESS) { - libab_table_free(&ab->table); + libab_ref_free(&ab->table); libab_parser_free(&ab->parser); libab_lexer_free(&ab->lexer); } + libab_ref_free(&null_ref); return result; } @@ -64,7 +70,7 @@ libab_result _register_operator(libab* ab, const char* op, } if (result == LIBAB_SUCCESS) { - result = libab_table_put(&ab->table, op, new_entry); + result = libab_table_put(libab_ref_get(&ab->table), op, new_entry); } if (result != LIBAB_SUCCESS) { @@ -110,7 +116,7 @@ libab_result libab_register_function(libab* ab, const char* name, } if (result == LIBAB_SUCCESS) { - result = libab_table_put(&ab->table, name, new_entry); + result = libab_table_put(libab_ref_get(&ab->table), name, new_entry); } if (result != LIBAB_SUCCESS) { @@ -132,7 +138,7 @@ libab_result libab_register_basetype(libab* ab, const char* name, } if (result == LIBAB_SUCCESS) { - result = libab_table_put(&ab->table, name, new_entry); + result = libab_table_put(libab_ref_get(&ab->table), name, new_entry); } if (result != LIBAB_SUCCESS) { @@ -156,7 +162,7 @@ libab_result libab_create_type(libab* ab, libab_ref* into, const char* type) { } libab_result libab_free(libab* ab) { - libab_table_free(&ab->table); + libab_ref_free(&ab->table); libab_parser_free(&ab->parser); return libab_lexer_free(&ab->lexer); } diff --git a/src/parser.c b/src/parser.c index 8d1c5ac..6379252 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1162,14 +1162,14 @@ libab_result _parse_block(struct parser_state* state, libab_tree** store_into, return result; } -void libab_parser_init(libab_parser* parser, libab_table* table) { - parser->base_table = table; +void libab_parser_init(libab_parser* parser, libab_ref* table) { + libab_ref_copy(table, &parser->base_table); } libab_result libab_parser_parse(libab_parser* parser, ll* tokens, const char* string, libab_tree** store_into) { libab_result result; struct parser_state state; - _parser_state_init(&state, tokens, string, parser->base_table); + _parser_state_init(&state, tokens, string, libab_ref_get(&parser->base_table)); result = _parse_block(&state, store_into, 0); if (result == LIBAB_SUCCESS) { @@ -1182,8 +1182,8 @@ libab_result libab_parser_parse_type(libab_parser* parser, ll* tokens, const char* string, libab_ref* store_into) { struct parser_state state; - _parser_state_init(&state, tokens, string, parser->base_table); + _parser_state_init(&state, tokens, string, libab_ref_get(&parser->base_table)); return _parse_type(&state, store_into); } -void libab_parser_free(libab_parser* parser) { parser->base_table = NULL; } +void libab_parser_free(libab_parser* parser) { libab_ref_free(&parser->base_table); } diff --git a/src/util.c b/src/util.c index 4048b26..062902e 100644 --- a/src/util.c +++ b/src/util.c @@ -122,3 +122,29 @@ libab_result libab_instantiate_basetype(libab_basetype* to_instantiate, return result; } + +void _free_table(void* data) { + libab_table_free(data); + free(data); +} + +libab_result libab_create_table(libab_ref* into, libab_ref* parent) { + libab_table* table; + libab_result result = LIBAB_SUCCESS; + if((table = malloc(sizeof(*table)))) { + libab_table_init(table); + libab_table_set_parent(table, parent); + result = libab_ref_new(into, table, _free_table); + + if(result != LIBAB_SUCCESS) { + _free_table(table); + } + } else { + result = LIBAB_MALLOC; + } + + if(result != LIBAB_SUCCESS) { + libab_ref_null(into); + } + return result; +}