Use reference counted table in libab.
This commit is contained in:
parent
cea057aaa6
commit
a86938b574
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -5,20 +5,26 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
libab_result libab_init(libab* ab) {
|
||||
libab_ref null_ref;
|
||||
libab_result result;
|
||||
libab_table_init(&ab->table);
|
||||
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);
|
||||
}
|
||||
|
|
10
src/parser.c
10
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); }
|
||||
|
|
26
src/util.c
26
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user