Add a function for preparing for execution.

This commit is contained in:
Danila Fedorin 2018-05-01 21:48:15 -07:00
parent 51e9a11a1f
commit 1e215ecfa5
2 changed files with 124 additions and 7 deletions

View File

@ -31,6 +31,7 @@ struct libab_s {
* to run a tree. * to run a tree.
*/ */
libab_interpreter intr; libab_interpreter intr;
/** /**
* The table used to store top-level * The table used to store top-level
* things like functions and operators. * things like functions and operators.
@ -41,6 +42,22 @@ struct libab_s {
* The allocator used to construct number instances. * The allocator used to construct number instances.
*/ */
libab_impl impl; libab_impl impl;
/**
* The number type instance.
*/
libab_ref type_num;
/**
* The function list type instance.
*/
libab_ref type_function_list;
/**
* Internal; the number basetype. This cannot be a static
* variable like other built-in types because it has a free function
* specified by the user.
*/
libab_basetype basetype_num;
}; };
typedef struct libab_s libab; typedef struct libab_s libab;
@ -49,9 +66,12 @@ typedef struct libab_s libab;
* Initializes the libabacus struct as well * Initializes the libabacus struct as well
* as all its internal structures such as the lexer. * as all its internal structures such as the lexer.
* @param ab the libabacus instance used to keep state. * @param ab the libabacus instance used to keep state.
* @param parse_function function used to parse a number.
* @param free_function function used to free the parsed number.
* @return the result of the initialization. * @return the result of the initialization.
*/ */
libab_result libab_init(libab* ab); libab_result libab_init(libab* ab, void* (*parse_function)(const char*),
void (*free_function)(void*));
/** /**
* Registers an operator with libabacus. * Registers an operator with libabacus.
* @param ab the libabacus instance to reigster the operator with. * @param ab the libabacus instance to reigster the operator with.

View File

@ -4,27 +4,51 @@
#include "util.h" #include "util.h"
#include <stdlib.h> #include <stdlib.h>
libab_result libab_init(libab* ab) { libab_result _prepare_types(libab* ab, void (*free_function)(void*));
libab_result libab_init(libab* ab, void* (*parse_function)(const char*),
void (*free_function)(void*)) {
int parser_initialized = 0;
int lexer_initialized = 0;
libab_ref null_ref; libab_ref null_ref;
libab_result result; libab_result result;
libab_ref_null(&null_ref); libab_ref_null(&null_ref);
libab_ref_null(&ab->type_num);
libab_ref_null(&ab->type_function_list);
ab->impl.parse_num = parse_function;
result = libab_create_table(&ab->table, &null_ref); result = libab_create_table(&ab->table, &null_ref);
if (result == LIBAB_SUCCESS) {
result = _prepare_types(ab, free_function);
}
if(result == LIBAB_SUCCESS) { if(result == LIBAB_SUCCESS) {
parser_initialized = 1;
libab_parser_init(&ab->parser, &ab->table); libab_parser_init(&ab->parser, &ab->table);
libab_interpreter_init(&ab->intr, &ab->table, &ab->impl); libab_interpreter_init(&ab->intr, &ab->table, &ab->impl);
result = libab_lexer_init(&ab->lexer); result = libab_lexer_init(&ab->lexer);
} }
if (result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
lexer_initialized = 1;
result = libab_register_reserved_operators(&ab->lexer); result = libab_register_reserved_operators(&ab->lexer);
} }
if (result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_free(&ab->table); libab_ref_free(&ab->table);
libab_ref_free(&ab->type_num);
libab_ref_free(&ab->type_function_list);
if(parser_initialized) {
libab_parser_free(&ab->parser); libab_parser_free(&ab->parser);
libab_interpreter_free(&ab->intr);
}
if(lexer_initialized) {
libab_lexer_free(&ab->lexer); libab_lexer_free(&ab->lexer);
} }
}
libab_ref_free(&null_ref); libab_ref_free(&null_ref);
return result; return result;
@ -40,7 +64,7 @@ void _sanitize(char* to, const char* from, size_t buffer_size) {
to[index] = '\0'; to[index] = '\0';
} }
void _initialize_behavior(libab* ab, libab_behavior* behavior, libab_ref* type, void _initialize_behavior(libab_behavior* behavior, libab_ref* type,
libab_function_ptr func) { libab_function_ptr func) {
behavior->impl.variant = BIMPL_INTERNAL; behavior->impl.variant = BIMPL_INTERNAL;
behavior->impl.data_u.internal = func; behavior->impl.data_u.internal = func;
@ -59,7 +83,7 @@ libab_result _register_operator(libab* ab, const char* op,
new_entry->data_u.op.precedence = precedence; new_entry->data_u.op.precedence = precedence;
new_entry->data_u.op.associativity = associativity; new_entry->data_u.op.associativity = associativity;
new_entry->data_u.op.type = token_type; new_entry->data_u.op.type = token_type;
_initialize_behavior(ab, &(new_entry->data_u.op.behavior), type, func); _initialize_behavior(&(new_entry->data_u.op.behavior), type, func);
} else { } else {
result = LIBAB_MALLOC; result = LIBAB_MALLOC;
} }
@ -110,7 +134,7 @@ libab_result libab_register_function(libab* ab, const char* name,
libab_table_entry* new_entry; libab_table_entry* new_entry;
if ((new_entry = malloc(sizeof(*new_entry)))) { if ((new_entry = malloc(sizeof(*new_entry)))) {
new_entry->variant = ENTRY_FUN; new_entry->variant = ENTRY_FUN;
_initialize_behavior(ab, &(new_entry->data_u.function.behavior), type, _initialize_behavior(&(new_entry->data_u.function.behavior), type,
func); func);
} else { } else {
result = LIBAB_MALLOC; result = LIBAB_MALLOC;
@ -149,6 +173,77 @@ libab_result libab_register_basetype(libab* ab, const char* name,
return result; return result;
} }
void _free_function_list(void* function_list) {
libab_function_list_free(function_list);
free(function_list);
}
static libab_basetype _basetype_function_list = {
_free_function_list,
NULL,
0
};
void _free_function(void* function) {
libab_function_free(function);
free(function);
}
static libab_basetype_param _basetype_function_params[] = {
{ BT_LIST, NULL }
};
static libab_basetype _basetype_function = {
_free_function,
_basetype_function_params,
1
};
libab_result _prepare_types(libab* ab, void (*free_function)(void*)) {
libab_result result = LIBAB_SUCCESS;
ab->basetype_num.count = 0;
ab->basetype_num.params = NULL;
ab->basetype_num.free_function = free_function;
libab_ref_null(&ab->type_num);
libab_ref_null(&ab->type_function_list);
if (result == LIBAB_SUCCESS) {
libab_ref_free(&ab->type_num);
result = libab_instantiate_basetype(&ab->basetype_num,
&ab->type_num, 0);
}
if (result == LIBAB_SUCCESS) {
libab_ref_free(&ab->type_function_list);
result = libab_instantiate_basetype(&_basetype_function_list,
&ab->type_function_list, 0);
}
if (result == LIBAB_SUCCESS) {
result = libab_register_basetype(ab, "num", &ab->basetype_num);
}
if (result == LIBAB_SUCCESS) {
result = libab_register_basetype(ab, "function", &_basetype_function);
}
if (result == LIBAB_SUCCESS) {
result = libab_register_basetype(ab, "function_list",
&_basetype_function_list);
}
if(result != LIBAB_SUCCESS) {
libab_ref_free(&ab->type_num);
libab_ref_free(&ab->type_function_list);
libab_ref_null(&ab->type_num);
libab_ref_null(&ab->type_function_list);
}
return result;
}
libab_result libab_create_type(libab* ab, libab_ref* into, const char* type) { libab_result libab_create_type(libab* ab, libab_ref* into, const char* type) {
libab_result result; libab_result result;
ll tokens; ll tokens;
@ -164,6 +259,8 @@ 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_ref_free(&ab->table); libab_ref_free(&ab->table);
libab_ref_free(&ab->type_num);
libab_ref_free(&ab->type_function_list);
libab_parser_free(&ab->parser); libab_parser_free(&ab->parser);
libab_interpreter_free(&ab->intr); libab_interpreter_free(&ab->intr);
return libab_lexer_free(&ab->lexer); return libab_lexer_free(&ab->lexer);