Use reference counted table in libab.

This commit is contained in:
Danila Fedorin 2018-04-24 11:32:57 -07:00
parent cea057aaa6
commit a86938b574
8 changed files with 63 additions and 52 deletions

View File

@ -6,14 +6,14 @@
#include "tree.h" #include "tree.h"
struct libab_interpreter_s { struct libab_interpreter_s {
libab_table* base_table; libab_ref base_table;
libab_number_impl* impl; libab_number_impl* impl;
}; };
typedef struct libab_interpreter_s libab_interpreter; typedef struct libab_interpreter_s libab_interpreter;
void libab_interpreter_init(libab_interpreter* intr, 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_result libab_interpreter_run(libab_interpreter* intr,
libab_tree* tree, libab_ref* into); libab_tree* tree, libab_ref* into);
void libab_interpreter_free(libab_interpreter* intr); void libab_interpreter_free(libab_interpreter* intr);

View File

@ -29,7 +29,7 @@ struct libab_s {
* The table used to store top-level * The table used to store top-level
* things like functions and operators. * things like functions and operators.
*/ */
libab_table table; libab_ref table;
/** /**
* The number implementation used by this instance. * The number implementation used by this instance.
*/ */

View File

@ -12,7 +12,7 @@
* tokens into trees. * tokens into trees.
*/ */
struct libab_parser_s { struct libab_parser_s {
libab_table* base_table; libab_ref base_table;
}; };
typedef struct libab_parser_s libab_parser; 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 parser the parser to intialize.
* @param table the table of "reserved" entries like operators. * @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. * Parses the given list of tokens into the given tree pointer.
* @param parser the parser to use for parsing text. * @param parser the parser to use for parsing text.

View File

@ -65,5 +65,12 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
*/ */
libab_result libab_instantiate_basetype(libab_basetype* to_instantiate, libab_result libab_instantiate_basetype(libab_basetype* to_instantiate,
libab_ref* into, size_t n, ...); 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 #endif

View File

@ -2,13 +2,12 @@
#include "util.h" #include "util.h"
void libab_interpreter_init(libab_interpreter* intr, void libab_interpreter_init(libab_interpreter* intr,
libab_table* table, libab_number_impl* impl) { libab_ref* table, libab_number_impl* impl) {
intr->base_table = table; libab_ref_copy(table, &intr->base_table);
intr->impl = impl; intr->impl = impl;
} }
struct interpreter_state { struct interpreter_state {
libab_table* base_table;
libab_number_impl* impl; libab_number_impl* impl;
libab_ref num_ref; libab_ref num_ref;
}; };
@ -16,11 +15,10 @@ struct interpreter_state {
libab_result _interpreter_init(struct interpreter_state* state, libab_interpreter* intr) { libab_result _interpreter_init(struct interpreter_state* state, libab_interpreter* intr) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_basetype* num_type; libab_basetype* num_type;
state->base_table = intr->base_table;
state->impl = intr->impl; state->impl = intr->impl;
libab_ref_null(&state->num_ref); 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) { if(num_type != NULL) {
libab_ref_free(&state->num_ref); libab_ref_free(&state->num_ref);
result = libab_instantiate_basetype(num_type, &state->num_ref, 0); 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); 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_result _interpreter_run(struct interpreter_state* state,
libab_tree* tree, libab_ref* into, libab_tree* tree, libab_ref* into,
libab_ref* scope, int force_scope) { 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; int needs_scope = libab_tree_has_scope(tree->variant) || force_scope;
if(needs_scope) { if(needs_scope) {
result = _make_scope(&new_scope, scope); result = libab_create_table(&new_scope, scope);
scope = &new_scope; scope = &new_scope;
} }
@ -99,7 +71,7 @@ libab_result libab_interpreter_run(libab_interpreter* intr,
libab_result result = _interpreter_init(&state, intr); libab_result result = _interpreter_init(&state, intr);
if(result == LIBAB_SUCCESS) { 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) { if(result != LIBAB_SUCCESS) {
_interpreter_free(&state); _interpreter_free(&state);
} }
@ -111,5 +83,5 @@ libab_result libab_interpreter_run(libab_interpreter* intr,
} }
void libab_interpreter_free(libab_interpreter* intr) { void libab_interpreter_free(libab_interpreter* intr) {
libab_ref_free(&intr->base_table);
} }

View File

@ -5,20 +5,26 @@
#include <stdlib.h> #include <stdlib.h>
libab_result libab_init(libab* ab) { libab_result libab_init(libab* ab) {
libab_ref null_ref;
libab_result result; libab_result result;
libab_table_init(&ab->table); libab_ref_null(&null_ref);
libab_parser_init(&ab->parser, &ab->table); result = libab_create_table(&ab->table, &null_ref);
result = libab_lexer_init(&ab->lexer);
if(result == LIBAB_SUCCESS) {
libab_parser_init(&ab->parser, &ab->table);
result = libab_lexer_init(&ab->lexer);
}
if (result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_register_reserved_operators(&ab->lexer); result = libab_register_reserved_operators(&ab->lexer);
} }
if (result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_table_free(&ab->table); libab_ref_free(&ab->table);
libab_parser_free(&ab->parser); libab_parser_free(&ab->parser);
libab_lexer_free(&ab->lexer); libab_lexer_free(&ab->lexer);
} }
libab_ref_free(&null_ref);
return result; return result;
} }
@ -64,7 +70,7 @@ libab_result _register_operator(libab* ab, const char* op,
} }
if (result == LIBAB_SUCCESS) { 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) { if (result != LIBAB_SUCCESS) {
@ -110,7 +116,7 @@ libab_result libab_register_function(libab* ab, const char* name,
} }
if (result == LIBAB_SUCCESS) { 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) { if (result != LIBAB_SUCCESS) {
@ -132,7 +138,7 @@ libab_result libab_register_basetype(libab* ab, const char* name,
} }
if (result == LIBAB_SUCCESS) { 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) { 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_result libab_free(libab* ab) {
libab_table_free(&ab->table); libab_ref_free(&ab->table);
libab_parser_free(&ab->parser); libab_parser_free(&ab->parser);
return libab_lexer_free(&ab->lexer); return libab_lexer_free(&ab->lexer);
} }

View File

@ -1162,14 +1162,14 @@ libab_result _parse_block(struct parser_state* state, libab_tree** store_into,
return result; return result;
} }
void libab_parser_init(libab_parser* parser, libab_table* table) { void libab_parser_init(libab_parser* parser, libab_ref* table) {
parser->base_table = table; libab_ref_copy(table, &parser->base_table);
} }
libab_result libab_parser_parse(libab_parser* parser, ll* tokens, libab_result libab_parser_parse(libab_parser* parser, ll* tokens,
const char* string, libab_tree** store_into) { const char* string, libab_tree** store_into) {
libab_result result; libab_result result;
struct parser_state state; 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); result = _parse_block(&state, store_into, 0);
if (result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
@ -1182,8 +1182,8 @@ libab_result libab_parser_parse_type(libab_parser* parser, ll* tokens,
const char* string, const char* string,
libab_ref* store_into) { libab_ref* store_into) {
struct parser_state state; 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); 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); }

View File

@ -122,3 +122,29 @@ libab_result libab_instantiate_basetype(libab_basetype* to_instantiate,
return result; 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;
}