Format code.

This commit is contained in:
Danila Fedorin 2018-05-26 21:55:30 -07:00
parent a6aaa22450
commit f4de244c41
10 changed files with 241 additions and 175 deletions

View File

@ -43,7 +43,8 @@ size_t libab_function_list_size(libab_function_list* list);
* @param index the index at which to get the value. * @param index the index at which to get the value.
* @param into the reference to store the function into. * @param into the reference to store the function into.
*/ */
void libab_function_list_index(libab_function_list* list, size_t index, libab_ref* into); void libab_function_list_index(libab_function_list* list, size_t index,
libab_ref* into);
/** /**
* Frees the given function list. * Frees the given function list.
* @param list the list to free. * @param list the list to free.

View File

@ -28,7 +28,8 @@ void libab_interpreter_init(libab_interpreter* intr, struct libab_s* ab);
* Uses the interpreter to run the given parse tree. * Uses the interpreter to run the given parse tree.
* @param intr the interpreter to use to run the code. * @param intr the interpreter to use to run the code.
* @param tree the tree to run. * @param tree the tree to run.
* @param into the reference into which the result of the execution will be stored. * @param into the reference into which the result of the execution will be
* stored.
* @return the result of the execution. * @return the result of the execution.
*/ */
libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree, libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree,

View File

@ -40,7 +40,8 @@ libab_result libab_ref_vec_init(libab_ref_vec* vec);
* @param copy_of the vector to make a copy of. * @param copy_of the vector to make a copy of.
* @return the result of the initialization. * @return the result of the initialization.
*/ */
libab_result libab_ref_vec_init_copy(libab_ref_vec* vec, libab_ref_vec* copy_of); libab_result libab_ref_vec_init_copy(libab_ref_vec* vec,
libab_ref_vec* copy_of);
/** /**
* Inserts an existing reference counted value into the vector. * Inserts an existing reference counted value into the vector.
* This bumps the reference's refcount, thereby preventing its * This bumps the reference's refcount, thereby preventing its

View File

@ -32,7 +32,7 @@ void libab_operator_free(libab_operator* op) {
libab_behavior_free(&op->behavior); libab_behavior_free(&op->behavior);
} }
libab_result _function_init(libab_function* function) { libab_result _function_init(libab_function* function) {
return libab_ref_vec_init(&function->params); return libab_ref_vec_init(&function->params);
} }
libab_result libab_function_init_internal(libab_function* function, libab_result libab_function_init_internal(libab_function* function,

View File

@ -13,7 +13,8 @@ size_t libab_function_list_size(libab_function_list* list) {
return list->functions.size; return list->functions.size;
} }
void libab_function_list_index(libab_function_list* list, size_t index, libab_ref* into) { void libab_function_list_index(libab_function_list* list, size_t index,
libab_ref* into) {
libab_ref_vec_index(&list->functions, index, into); libab_ref_vec_index(&list->functions, index, into);
} }

View File

@ -1,22 +1,22 @@
#include "libabacus.h" #include "libabacus.h"
#include <stdio.h>
#include "value.h"
#include "util.h" #include "util.h"
#include "value.h"
#include <stdio.h>
#define TRY(expression) if(result == LIBAB_SUCCESS) result = expression; #define TRY(expression) \
if (result == LIBAB_SUCCESS) \
result = expression;
#define INTERACTIONS 5 #define INTERACTIONS 5
void* impl_parse(const char* string) { void* impl_parse(const char* string) {
double* data = malloc(sizeof(*data)); double* data = malloc(sizeof(*data));
if(data) { if (data) {
*data = strtod(string, NULL); *data = strtod(string, NULL);
} }
return data; return data;
} }
void impl_free(void* data) { void impl_free(void* data) { free(data); }
free(data);
}
libab_result function_atan(libab_ref_vec* params, libab_ref* into) { libab_result function_atan(libab_ref_vec* params, libab_ref* into) {
printf("atan called\n"); printf("atan called\n");
@ -42,16 +42,16 @@ libab_result function_operator(libab_ref_vec* params, libab_ref* into) {
libab_ref_vec_index(params, 0, &left_ref); libab_ref_vec_index(params, 0, &left_ref);
left_value = libab_ref_get(&left_ref); left_value = libab_ref_get(&left_ref);
left = *((double*) libab_unwrap_param(params, 0)); left = *((double*)libab_unwrap_param(params, 0));
right = *((double*) libab_unwrap_param(params, 1)); right = *((double*)libab_unwrap_param(params, 1));
return_value = malloc(sizeof(*return_value)); return_value = malloc(sizeof(*return_value));
if(return_value == NULL) { if (return_value == NULL) {
result = LIBAB_MALLOC; result = LIBAB_MALLOC;
libab_ref_null(into); libab_ref_null(into);
} else { } else {
*return_value = left + right; *return_value = left + right;
result = libab_create_value_raw(into, return_value, &left_value->type); result = libab_create_value_raw(into, return_value, &left_value->type);
} }
libab_ref_free(&left_ref); libab_ref_free(&left_ref);
@ -71,10 +71,14 @@ libab_result register_functions(libab* ab) {
TRY(libab_register_function(ab, "atan", &trig_type, function_atan)); TRY(libab_register_function(ab, "atan", &trig_type, function_atan));
TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2)); TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2));
TRY(libab_register_operator_infix(ab, "+", 0, -1, &atan2_type, function_operator)); TRY(libab_register_operator_infix(ab, "+", 0, -1, &atan2_type,
TRY(libab_register_operator_infix(ab, "-", 0, -1, &atan2_type, function_operator)); function_operator));
TRY(libab_register_operator_infix(ab, "*", 1, -1, &atan2_type, function_operator)); TRY(libab_register_operator_infix(ab, "-", 0, -1, &atan2_type,
TRY(libab_register_operator_infix(ab, "/", 1, -1, &atan2_type, function_operator)); function_operator));
TRY(libab_register_operator_infix(ab, "*", 1, -1, &atan2_type,
function_operator));
TRY(libab_register_operator_infix(ab, "/", 1, -1, &atan2_type,
function_operator));
libab_ref_free(&trig_type); libab_ref_free(&trig_type);
libab_ref_free(&atan2_type); libab_ref_free(&atan2_type);
@ -91,18 +95,18 @@ int main() {
libab_result eval_result; libab_result eval_result;
libab ab; libab ab;
if(libab_init(&ab, impl_parse, impl_free) != LIBAB_SUCCESS) { if (libab_init(&ab, impl_parse, impl_free) != LIBAB_SUCCESS) {
fprintf(stderr, "Failed to initialize libab.\n"); fprintf(stderr, "Failed to initialize libab.\n");
exit(1); exit(1);
} }
result = register_functions(&ab); result = register_functions(&ab);
while(interaction_count-- && result == LIBAB_SUCCESS) { while (interaction_count-- && result == LIBAB_SUCCESS) {
printf("(%d) > ", INTERACTIONS - interaction_count); printf("(%d) > ", INTERACTIONS - interaction_count);
fgets(input_buffer, 2048, stdin); fgets(input_buffer, 2048, stdin);
eval_result = libab_run(&ab, input_buffer, &eval_into); eval_result = libab_run(&ab, input_buffer, &eval_into);
if(eval_result != LIBAB_SUCCESS) { if (eval_result != LIBAB_SUCCESS) {
printf("Invalid input.\n"); printf("Invalid input.\n");
} }
libab_ref_free(&eval_into); libab_ref_free(&eval_into);

View File

@ -48,8 +48,8 @@ int _interpreter_type_contains_placeholders(libab_ref* type) {
libab_ref temp_child; libab_ref temp_child;
libab_parsetype* parsetype = libab_ref_get(type); libab_parsetype* parsetype = libab_ref_get(type);
placeholder = (parsetype->variant & LIBABACUS_TYPE_F_PLACE) != 0; placeholder = (parsetype->variant & LIBABACUS_TYPE_F_PLACE) != 0;
if(parsetype->variant & LIBABACUS_TYPE_F_PARENT) { if (parsetype->variant & LIBABACUS_TYPE_F_PARENT) {
for(; index < parsetype->children.size && !placeholder; index++) { for (; index < parsetype->children.size && !placeholder; index++) {
libab_ref_vec_index(&parsetype->children, index, &temp_child); libab_ref_vec_index(&parsetype->children, index, &temp_child);
placeholder |= _interpreter_type_contains_placeholders(&temp_child); placeholder |= _interpreter_type_contains_placeholders(&temp_child);
libab_ref_free(&temp_child); libab_ref_free(&temp_child);
@ -58,8 +58,10 @@ int _interpreter_type_contains_placeholders(libab_ref* type) {
return placeholder; return placeholder;
} }
libab_result _interpreter_compare_types(libab_ref* left_type, libab_ref* right_type, libab_result _interpreter_compare_types(libab_ref* left_type,
libab_ref_trie* left_params, libab_ref_trie* right_params) { libab_ref* right_type,
libab_ref_trie* left_params,
libab_ref_trie* right_params) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
int left_placeholder; int left_placeholder;
int right_placeholder; int right_placeholder;
@ -69,28 +71,28 @@ libab_result _interpreter_compare_types(libab_ref* left_type, libab_ref* right_t
left_placeholder = left->variant & LIBABACUS_TYPE_F_PLACE; left_placeholder = left->variant & LIBABACUS_TYPE_F_PLACE;
right_placeholder = right->variant & LIBABACUS_TYPE_F_PLACE; right_placeholder = right->variant & LIBABACUS_TYPE_F_PLACE;
if(left_placeholder && right_placeholder) { if (left_placeholder && right_placeholder) {
result = LIBAB_AMBIGOUS_TYPE; result = LIBAB_AMBIGOUS_TYPE;
} else { } else {
if(left_placeholder) { if (left_placeholder) {
const char* name = left->data_u.name; const char* name = left->data_u.name;
libab_ref_trie_get(left_params, name, &param_type); libab_ref_trie_get(left_params, name, &param_type);
left = libab_ref_get(&param_type); left = libab_ref_get(&param_type);
libab_ref_free(&param_type); libab_ref_free(&param_type);
if(left == NULL) { if (left == NULL) {
if(!_interpreter_type_contains_placeholders(right_type)) { if (!_interpreter_type_contains_placeholders(right_type)) {
result = libab_ref_trie_put(left_params, name, right_type); result = libab_ref_trie_put(left_params, name, right_type);
} else { } else {
result = LIBAB_AMBIGOUS_TYPE; result = LIBAB_AMBIGOUS_TYPE;
} }
} }
} else if(right_placeholder) { } else if (right_placeholder) {
const char* name = right->data_u.name; const char* name = right->data_u.name;
libab_ref_trie_get(right_params, name, &param_type); libab_ref_trie_get(right_params, name, &param_type);
right = libab_ref_get(&param_type); right = libab_ref_get(&param_type);
libab_ref_free(&param_type); libab_ref_free(&param_type);
if(right == NULL) { if (right == NULL) {
if(!_interpreter_type_contains_placeholders(left_type)) { if (!_interpreter_type_contains_placeholders(left_type)) {
result = libab_ref_trie_put(right_params, name, left_type); result = libab_ref_trie_put(right_params, name, left_type);
} else { } else {
result = LIBAB_AMBIGOUS_TYPE; result = LIBAB_AMBIGOUS_TYPE;
@ -98,21 +100,31 @@ libab_result _interpreter_compare_types(libab_ref* left_type, libab_ref* right_t
} }
} }
if(left != NULL && right != NULL) { if (left != NULL && right != NULL) {
size_t index = 0; size_t index = 0;
libab_ref temp_left; libab_ref temp_left;
libab_ref temp_right; libab_ref temp_right;
result = (left->data_u.base == right->data_u.base) ? LIBAB_SUCCESS : LIBAB_MISMATCHED_TYPE; result = (left->data_u.base == right->data_u.base)
if(result == LIBAB_SUCCESS && ? LIBAB_SUCCESS
(left->variant & LIBABACUS_TYPE_F_PARENT || right->variant & LIBABACUS_TYPE_F_PARENT)) { : LIBAB_MISMATCHED_TYPE;
result = (left->variant & right->variant & LIBABACUS_TYPE_F_PARENT) ? LIBAB_SUCCESS : LIBAB_MISMATCHED_TYPE; if (result == LIBAB_SUCCESS &&
if(result == LIBAB_SUCCESS) { (left->variant & LIBABACUS_TYPE_F_PARENT ||
result = (left->children.size == right->children.size) ? LIBAB_SUCCESS : LIBAB_MISMATCHED_TYPE; right->variant & LIBABACUS_TYPE_F_PARENT)) {
result =
(left->variant & right->variant & LIBABACUS_TYPE_F_PARENT)
? LIBAB_SUCCESS
: LIBAB_MISMATCHED_TYPE;
if (result == LIBAB_SUCCESS) {
result = (left->children.size == right->children.size)
? LIBAB_SUCCESS
: LIBAB_MISMATCHED_TYPE;
} }
for(; index < left->children.size && result == LIBAB_SUCCESS; index++) { for (; index < left->children.size && result == LIBAB_SUCCESS;
index++) {
libab_ref_vec_index(&left->children, index, &temp_left); libab_ref_vec_index(&left->children, index, &temp_left);
libab_ref_vec_index(&right->children, index, &temp_right); libab_ref_vec_index(&right->children, index, &temp_right);
result = _interpreter_compare_types(&temp_left, &temp_right, left_params, right_params); result = _interpreter_compare_types(
&temp_left, &temp_right, left_params, right_params);
libab_ref_free(&temp_left); libab_ref_free(&temp_left);
libab_ref_free(&temp_right); libab_ref_free(&temp_right);
} }
@ -128,30 +140,34 @@ void _free_parsetype(void* parsetype) {
free(parsetype); free(parsetype);
} }
libab_result _interpreter_copy_resolved_type(libab_ref* type, libab_ref_trie* params, libab_ref* into) { libab_result _interpreter_copy_resolved_type(libab_ref* type,
libab_ref_trie* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_parsetype* copy; libab_parsetype* copy;
libab_parsetype* original; libab_parsetype* original;
original = libab_ref_get(type); original = libab_ref_get(type);
if(original->variant & LIBABACUS_TYPE_F_PLACE) { if (original->variant & LIBABACUS_TYPE_F_PLACE) {
libab_ref_trie_get(params, original->data_u.name, into); libab_ref_trie_get(params, original->data_u.name, into);
} else if((copy = malloc(sizeof(*copy)))) { } else if ((copy = malloc(sizeof(*copy)))) {
size_t index = 0; size_t index = 0;
copy->variant = original->variant; copy->variant = original->variant;
copy->data_u.base = original->data_u.base; copy->data_u.base = original->data_u.base;
if(copy->variant & LIBABACUS_TYPE_F_PARENT) { if (copy->variant & LIBABACUS_TYPE_F_PARENT) {
libab_ref child_copy; libab_ref child_copy;
libab_ref temp_child; libab_ref temp_child;
result = libab_ref_vec_init(&copy->children); result = libab_ref_vec_init(&copy->children);
for(; index < original->children.size && result == LIBAB_SUCCESS; index++) { for (; index < original->children.size && result == LIBAB_SUCCESS;
index++) {
libab_ref_vec_index(&original->children, index, &temp_child); libab_ref_vec_index(&original->children, index, &temp_child);
result = _interpreter_copy_resolved_type(&temp_child, params, &child_copy); result = _interpreter_copy_resolved_type(&temp_child, params,
if(result == LIBAB_SUCCESS) { &child_copy);
if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(&copy->children, &child_copy); result = libab_ref_vec_insert(&copy->children, &child_copy);
} }
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_parsetype_free(copy); libab_parsetype_free(copy);
} }
@ -159,9 +175,9 @@ libab_result _interpreter_copy_resolved_type(libab_ref* type, libab_ref_trie* pa
libab_ref_free(&temp_child); libab_ref_free(&temp_child);
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_new(into, copy, _free_parsetype); result = libab_ref_new(into, copy, _free_parsetype);
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
_free_parsetype(copy); _free_parsetype(copy);
} }
} }
@ -170,16 +186,18 @@ libab_result _interpreter_copy_resolved_type(libab_ref* type, libab_ref_trie* pa
result = LIBAB_MALLOC; result = LIBAB_MALLOC;
} }
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_null(into); libab_ref_null(into);
} }
return result; return result;
} }
libab_result _interpreter_resolve_type_params(libab_ref* type, libab_ref_trie* params, libab_ref* into) { libab_result _interpreter_resolve_type_params(libab_ref* type,
libab_ref_trie* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
if(_interpreter_type_contains_placeholders(type)) { if (_interpreter_type_contains_placeholders(type)) {
result = _interpreter_copy_resolved_type(type, params, into); result = _interpreter_copy_resolved_type(type, params, into);
} else { } else {
libab_ref_copy(type, into); libab_ref_copy(type, into);
@ -188,7 +206,8 @@ libab_result _interpreter_resolve_type_params(libab_ref* type, libab_ref_trie* p
} }
libab_result _interpreter_check_types(struct interpreter_state* state, libab_result _interpreter_check_types(struct interpreter_state* state,
libab_ref_vec* reference_types, libab_ref_vec* params, libab_ref_vec* reference_types,
libab_ref_vec* params,
libab_ref_vec* types) { libab_ref_vec* types) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref_trie function_params; libab_ref_trie function_params;
@ -204,23 +223,25 @@ libab_result _interpreter_check_types(struct interpreter_state* state,
libab_ref* right_temp; libab_ref* right_temp;
libab_ref produced_type; libab_ref produced_type;
size_t index = 0; size_t index = 0;
for(; index < params->size && result == LIBAB_SUCCESS; index++) { for (; index < params->size && result == LIBAB_SUCCESS; index++) {
libab_ref_trie_init(&child_params); libab_ref_trie_init(&child_params);
libab_ref_vec_index(reference_types, index, &left_temp); libab_ref_vec_index(reference_types, index, &left_temp);
libab_ref_vec_index(params, index, &right_value_temp); libab_ref_vec_index(params, index, &right_value_temp);
right_temp = &((libab_value*) libab_ref_get(&right_value_temp))->type; right_temp =
result = _interpreter_compare_types(&left_temp, &((libab_value*)libab_ref_get(&right_value_temp))->type;
right_temp, &function_params, &child_params); result = _interpreter_compare_types(
&left_temp, right_temp, &function_params, &child_params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_resolve_type_params(right_temp, &child_params, &produced_type); result = _interpreter_resolve_type_params(
if(result != LIBAB_SUCCESS) { right_temp, &child_params, &produced_type);
if (result != LIBAB_SUCCESS) {
libab_ref_free(&produced_type); libab_ref_free(&produced_type);
} }
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(types, &produced_type); result = libab_ref_vec_insert(types, &produced_type);
libab_ref_free(&produced_type); libab_ref_free(&produced_type);
} }
@ -232,7 +253,7 @@ libab_result _interpreter_check_types(struct interpreter_state* state,
} }
} }
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_vec_clear(types); libab_ref_vec_clear(types);
} }
@ -240,8 +261,10 @@ libab_result _interpreter_check_types(struct interpreter_state* state,
} }
libab_result _interpreter_find_match(struct interpreter_state* state, libab_result _interpreter_find_match(struct interpreter_state* state,
libab_function_list* function_values, libab_ref_vec* params, libab_function_list* function_values,
libab_ref_vec* new_types, libab_ref* match, int partial) { libab_ref_vec* params,
libab_ref_vec* new_types, libab_ref* match,
int partial) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
size_t index = 0; size_t index = 0;
size_t list_size = libab_function_list_size(function_values); size_t list_size = libab_function_list_size(function_values);
@ -253,34 +276,38 @@ libab_result _interpreter_find_match(struct interpreter_state* state,
libab_ref_null(match); libab_ref_null(match);
result = libab_ref_vec_init(&temp_new_types); result = libab_ref_vec_init(&temp_new_types);
for(; index < list_size && result == LIBAB_SUCCESS; index++) { for (; index < list_size && result == LIBAB_SUCCESS; index++) {
libab_function_list_index(function_values, index, &temp_function_value); libab_function_list_index(function_values, index, &temp_function_value);
temp_function_type = libab_ref_get(&((libab_value*) libab_ref_get(&temp_function_value))->type); temp_function_type = libab_ref_get(
&((libab_value*)libab_ref_get(&temp_function_value))->type);
if(((temp_function_type->children.size == params->size + 1) && !partial) || if (((temp_function_type->children.size == params->size + 1) &&
((temp_function_type->children.size > params->size + 1) && partial)) { !partial) ||
((temp_function_type->children.size > params->size + 1) &&
partial)) {
/* We found a function that has the correct number of parameters. */ /* We found a function that has the correct number of parameters. */
result = _interpreter_check_types(state, &temp_function_type->children, params, &temp_new_types); result = _interpreter_check_types(
if(result == LIBAB_MISMATCHED_TYPE) { state, &temp_function_type->children, params, &temp_new_types);
if (result == LIBAB_MISMATCHED_TYPE) {
/* Mismatch is OK. */ /* Mismatch is OK. */
result = LIBAB_SUCCESS; result = LIBAB_SUCCESS;
} else if(result == LIBAB_SUCCESS) { } else if (result == LIBAB_SUCCESS) {
/* Function matched; now, check for other matching calls. /* Function matched; now, check for other matching calls.
* More than one matching calls = ambigous call. */ * More than one matching calls = ambigous call. */
if(!found_match) { if (!found_match) {
/* We haven't found a match previously. Copy data into new_types, /* We haven't found a match previously. Copy data into
* and use new memory for temp list. */ * new_types, and use new memory for temp list. */
found_match = 1; found_match = 1;
*new_types = temp_new_types; *new_types = temp_new_types;
libab_ref_free(match); libab_ref_free(match);
libab_ref_copy(&temp_function_value, match); libab_ref_copy(&temp_function_value, match);
result = libab_ref_vec_init(&temp_new_types); result = libab_ref_vec_init(&temp_new_types);
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_vec_free(new_types); libab_ref_vec_free(new_types);
} }
} else { } else {
/* We've found a match previously. So, new_types are initialized, /* We've found a match previously. So, new_types are
* and the call is ambigous. Free all data. */ * initialized, and the call is ambigous. Free all data. */
libab_ref_vec_free(new_types); libab_ref_vec_free(new_types);
libab_ref_vec_free(&temp_new_types); libab_ref_vec_free(&temp_new_types);
result = LIBAB_AMBIGOUS_CALL; result = LIBAB_AMBIGOUS_CALL;
@ -288,16 +315,17 @@ libab_result _interpreter_find_match(struct interpreter_state* state,
} else { } else {
/* Something bad happened. Free data as best as we can. */ /* Something bad happened. Free data as best as we can. */
libab_ref_vec_free(&temp_new_types); libab_ref_vec_free(&temp_new_types);
if(found_match) libab_ref_vec_free(new_types); if (found_match)
libab_ref_vec_free(new_types);
} }
} }
libab_ref_free(&temp_function_value); libab_ref_free(&temp_function_value);
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
libab_ref_vec_free(&temp_new_types); libab_ref_vec_free(&temp_new_types);
if(!found_match) if (!found_match)
libab_ref_null(match); libab_ref_null(match);
} else { } else {
libab_ref_free(match); libab_ref_free(match);
@ -307,13 +335,14 @@ libab_result _interpreter_find_match(struct interpreter_state* state,
return result; return result;
} }
libab_result _interpreter_cast_param(libab_ref* param, libab_ref* type, libab_ref_vec* into) { libab_result _interpreter_cast_param(libab_ref* param, libab_ref* type,
libab_ref_vec* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_value* old_value = libab_ref_get(param); libab_value* old_value = libab_ref_get(param);
libab_ref new_value; libab_ref new_value;
result = libab_create_value_ref(&new_value, &old_value->data, type); result = libab_create_value_ref(&new_value, &old_value->data, type);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(into, &new_value); result = libab_ref_vec_insert(into, &new_value);
} }
libab_ref_free(&new_value); libab_ref_free(&new_value);
@ -321,13 +350,15 @@ libab_result _interpreter_cast_param(libab_ref* param, libab_ref* type, libab_re
return result; return result;
} }
libab_result _interpreter_cast_params(libab_ref_vec* params, libab_ref_vec* new_types, libab_ref_vec* into) { libab_result _interpreter_cast_params(libab_ref_vec* params,
libab_ref_vec* new_types,
libab_ref_vec* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
size_t index = 0; size_t index = 0;
libab_ref temp_param; libab_ref temp_param;
libab_ref temp_type; libab_ref temp_type;
for(; index < params->size && result == LIBAB_SUCCESS; index++) { for (; index < params->size && result == LIBAB_SUCCESS; index++) {
libab_ref_vec_index(params, index, &temp_param); libab_ref_vec_index(params, index, &temp_param);
libab_ref_vec_index(new_types, index, &temp_type); libab_ref_vec_index(new_types, index, &temp_type);
@ -340,14 +371,17 @@ libab_result _interpreter_cast_params(libab_ref_vec* params, libab_ref_vec* new_
return result; return result;
} }
libab_result _interpreter_call_tree(libab_tree* tree, libab_ref_vec* params, libab_ref* into) { libab_result _interpreter_call_tree(libab_tree* tree, libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
return result; return result;
} }
libab_result _interpreter_call_behavior(libab_behavior* behavior, libab_ref_vec* params, libab_ref* into) { libab_result _interpreter_call_behavior(libab_behavior* behavior,
libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
if(behavior->variant == BIMPL_INTERNAL) { if (behavior->variant == BIMPL_INTERNAL) {
result = behavior->data_u.internal(params, into); result = behavior->data_u.internal(params, into);
} else { } else {
result = _interpreter_call_tree(behavior->data_u.tree, params, into); result = _interpreter_call_tree(behavior->data_u.tree, params, into);
@ -355,7 +389,9 @@ libab_result _interpreter_call_behavior(libab_behavior* behavior, libab_ref_vec*
return result; return result;
} }
libab_result _interpreter_perform_function_call(libab_value* to_call, libab_ref_vec* params, libab_ref* into) { libab_result _interpreter_perform_function_call(libab_value* to_call,
libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_function* function; libab_function* function;
libab_parsetype* function_type; libab_parsetype* function_type;
@ -363,16 +399,15 @@ libab_result _interpreter_perform_function_call(libab_value* to_call, libab_ref_
function = libab_ref_get(&to_call->data); function = libab_ref_get(&to_call->data);
function_type = libab_ref_get(&to_call->type); function_type = libab_ref_get(&to_call->type);
new_params = params->size - function->params.size; new_params = params->size - function->params.size;
if(function_type->children.size - new_params == 1) { if (function_type->children.size - new_params == 1) {
_interpreter_call_behavior(&function->behavior, params, into); _interpreter_call_behavior(&function->behavior, params, into);
} }
return result; return result;
} }
libab_result _interpreter_cast_and_perform_function_call(libab_ref* to_call, libab_result _interpreter_cast_and_perform_function_call(
libab_ref_vec* params, libab_ref* to_call, libab_ref_vec* params, libab_ref_vec* new_types,
libab_ref_vec* new_types, libab_ref* into) {
libab_ref* into) {
libab_result result; libab_result result;
libab_ref_vec new_params; libab_ref_vec new_params;
libab_value* function_value; libab_value* function_value;
@ -381,11 +416,12 @@ libab_result _interpreter_cast_and_perform_function_call(libab_ref* to_call,
function_value = libab_ref_get(to_call); function_value = libab_ref_get(to_call);
function = libab_ref_get(&function_value->data); function = libab_ref_get(&function_value->data);
result = libab_ref_vec_init_copy(&new_params, &function->params); result = libab_ref_vec_init_copy(&new_params, &function->params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_cast_params(params, new_types, &new_params); result = _interpreter_cast_params(params, new_types, &new_params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_perform_function_call(function_value, &new_params, into); result = _interpreter_perform_function_call(function_value,
&new_params, into);
} }
libab_ref_vec_free(&new_params); libab_ref_vec_free(&new_params);
@ -394,26 +430,31 @@ libab_result _interpreter_cast_and_perform_function_call(libab_ref* to_call,
} }
libab_result _interpreter_call_function_list(struct interpreter_state* state, libab_result _interpreter_call_function_list(struct interpreter_state* state,
libab_function_list* list, libab_ref_vec* params, libab_ref* into) { libab_function_list* list,
libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref_vec new_types; libab_ref_vec new_types;
libab_ref to_call; libab_ref to_call;
libab_ref_null(into); libab_ref_null(into);
result = _interpreter_find_match(state, list, params, &new_types, &to_call, 0); result =
if(result == LIBAB_SUCCESS) { _interpreter_find_match(state, list, params, &new_types, &to_call, 0);
if(libab_ref_get(&to_call) == NULL) { if (result == LIBAB_SUCCESS) {
result = _interpreter_find_match(state, list, params, &new_types, &to_call, 1); if (libab_ref_get(&to_call) == NULL) {
result = _interpreter_find_match(state, list, params, &new_types,
&to_call, 1);
} }
} }
if(result == LIBAB_SUCCESS && libab_ref_get(&to_call) == NULL) { if (result == LIBAB_SUCCESS && libab_ref_get(&to_call) == NULL) {
result = LIBAB_BAD_CALL; result = LIBAB_BAD_CALL;
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
libab_ref_free(into); libab_ref_free(into);
result = _interpreter_cast_and_perform_function_call(&to_call, params, &new_types, into); result = _interpreter_cast_and_perform_function_call(&to_call, params,
&new_types, into);
libab_ref_vec_free(&new_types); libab_ref_vec_free(&new_types);
} }
@ -422,7 +463,10 @@ libab_result _interpreter_call_function_list(struct interpreter_state* state,
return result; return result;
} }
libab_result _interpreter_call_function(struct interpreter_state* state, libab_ref* function, libab_ref_vec* params, libab_ref* into) { libab_result _interpreter_call_function(struct interpreter_state* state,
libab_ref* function,
libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref_vec temp_new_types; libab_ref_vec temp_new_types;
libab_value* function_value; libab_value* function_value;
@ -433,12 +477,14 @@ libab_result _interpreter_call_function(struct interpreter_state* state, libab_r
libab_ref_null(into); libab_ref_null(into);
result = libab_ref_vec_init(&temp_new_types); result = libab_ref_vec_init(&temp_new_types);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_check_types(state, &function_type->children, params, &temp_new_types); result = _interpreter_check_types(state, &function_type->children,
params, &temp_new_types);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
libab_ref_free(into); libab_ref_free(into);
result = _interpreter_cast_and_perform_function_call(function, params, &temp_new_types, into); result = _interpreter_cast_and_perform_function_call(
function, params, &temp_new_types, into);
} }
libab_ref_vec_free(&temp_new_types); libab_ref_vec_free(&temp_new_types);
@ -447,8 +493,9 @@ libab_result _interpreter_call_function(struct interpreter_state* state, libab_r
return result; return result;
} }
libab_result _interpreter_try_call(struct interpreter_state* state, libab_ref* value, libab_result _interpreter_try_call(struct interpreter_state* state,
libab_ref_vec* params, libab_ref* into) { libab_ref* value, libab_ref_vec* params,
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_value* callee_value; libab_value* callee_value;
libab_parsetype* callee_type; libab_parsetype* callee_type;
@ -457,12 +504,11 @@ libab_result _interpreter_try_call(struct interpreter_state* state, libab_ref* v
callee_type = libab_ref_get(&callee_value->type); callee_type = libab_ref_get(&callee_value->type);
callee_basetype = callee_type->data_u.base; callee_basetype = callee_type->data_u.base;
if(callee_basetype == libab_get_basetype_function_list(state->ab)) { if (callee_basetype == libab_get_basetype_function_list(state->ab)) {
result = _interpreter_call_function_list(state, result = _interpreter_call_function_list(
libab_ref_get(&callee_value->data), params, into); state, libab_ref_get(&callee_value->data), params, into);
} else if(callee_basetype == libab_get_basetype_function(state->ab)) { } else if (callee_basetype == libab_get_basetype_function(state->ab)) {
result = _interpreter_call_function(state, result = _interpreter_call_function(state, value, params, into);
value, params, into);
} else { } else {
libab_ref_null(into); libab_ref_null(into);
result = LIBAB_BAD_CALL; result = LIBAB_BAD_CALL;
@ -471,21 +517,21 @@ libab_result _interpreter_try_call(struct interpreter_state* state, libab_ref* v
return result; return result;
} }
libab_result _interpreter_cast_and_perform_operator_call(libab_operator* to_call, libab_result _interpreter_cast_and_perform_operator_call(
libab_ref_vec* params, libab_operator* to_call, libab_ref_vec* params, libab_ref_vec* new_types,
libab_ref_vec* new_types, libab_ref* into) {
libab_ref* into) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref_vec new_params; libab_ref_vec new_params;
libab_ref_null(into); libab_ref_null(into);
result = libab_ref_vec_init(&new_params); result = libab_ref_vec_init(&new_params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_cast_params(params, new_types, &new_params); result = _interpreter_cast_params(params, new_types, &new_params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
libab_ref_free(into); libab_ref_free(into);
result = _interpreter_call_behavior(&to_call->behavior, params, into); result =
_interpreter_call_behavior(&to_call->behavior, params, into);
} }
libab_ref_vec_free(&new_params); libab_ref_vec_free(&new_params);
@ -499,7 +545,9 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
int force_scope); int force_scope);
libab_result _interpreter_call_operator(struct interpreter_state* state, libab_result _interpreter_call_operator(struct interpreter_state* state,
libab_operator* to_call, libab_ref* into, libab_ref* scope, ...) { libab_operator* to_call,
libab_ref* into, libab_ref* scope,
...) {
va_list args; va_list args;
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref_vec params; libab_ref_vec params;
@ -511,38 +559,42 @@ libab_result _interpreter_call_operator(struct interpreter_state* state,
operator_type = libab_ref_get(&to_call->type); operator_type = libab_ref_get(&to_call->type);
result = libab_ref_vec_init(&params); result = libab_ref_vec_init(&params);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_init(&new_types); result = libab_ref_vec_init(&new_types);
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_vec_free(&params); libab_ref_vec_free(&params);
} }
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_run(state, va_arg(args, libab_tree*), &temp, scope, 0); result =
_interpreter_run(state, va_arg(args, libab_tree*), &temp, scope, 0);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(&params, &temp); result = libab_ref_vec_insert(&params, &temp);
} }
libab_ref_free(&temp); libab_ref_free(&temp);
if(result == LIBAB_SUCCESS && to_call->variant == OPERATOR_INFIX) { if (result == LIBAB_SUCCESS && to_call->variant == OPERATOR_INFIX) {
result = _interpreter_run(state, va_arg(args, libab_tree*), &temp, scope, 0); result = _interpreter_run(state, va_arg(args, libab_tree*), &temp,
scope, 0);
if(result == LIBAB_SUCCESS) {
if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(&params, &temp); result = libab_ref_vec_insert(&params, &temp);
} }
libab_ref_free(&temp); libab_ref_free(&temp);
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_check_types(state, &operator_type->children, &params, &new_types); result = _interpreter_check_types(state, &operator_type->children,
&params, &new_types);
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_cast_and_perform_operator_call(to_call, &params, &new_types, into); result = _interpreter_cast_and_perform_operator_call(
to_call, &params, &new_types, into);
} }
libab_ref_vec_free(&params); libab_ref_vec_free(&params);
@ -554,8 +606,8 @@ libab_result _interpreter_call_operator(struct interpreter_state* state,
} }
libab_result _interpreter_run_function_node(struct interpreter_state* state, libab_result _interpreter_run_function_node(struct interpreter_state* state,
libab_tree* tree, libab_tree* tree, libab_ref* into,
libab_ref* into, libab_ref* scope) { libab_ref* scope) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_ref param; libab_ref param;
libab_ref callee; libab_ref callee;
@ -565,32 +617,32 @@ libab_result _interpreter_run_function_node(struct interpreter_state* state,
libab_ref_null(&param); libab_ref_null(&param);
result = libab_ref_vec_init(&params); result = libab_ref_vec_init(&params);
for(; count < tree->children.size - 1 && result == LIBAB_SUCCESS; count++) { for (; count < tree->children.size - 1 && result == LIBAB_SUCCESS;
count++) {
libab_ref_free(&param); libab_ref_free(&param);
child = vec_index(&tree->children, count); child = vec_index(&tree->children, count);
result = _interpreter_run(state, child, &param, scope, 0); result = _interpreter_run(state, child, &param, scope, 0);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_ref_vec_insert(&params, &param); result = libab_ref_vec_insert(&params, &param);
} }
if(result != LIBAB_SUCCESS) { if (result != LIBAB_SUCCESS) {
libab_ref_vec_free(&params); libab_ref_vec_free(&params);
} }
} }
libab_ref_free(&param); libab_ref_free(&param);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_run(state, result = _interpreter_run(
vec_index(&tree->children, state, vec_index(&tree->children, tree->children.size - 1), &callee,
tree->children.size - 1), scope, 0);
&callee, scope, 0); if (result != LIBAB_SUCCESS) {
if(result != LIBAB_SUCCESS) {
libab_ref_vec_free(&params); libab_ref_vec_free(&params);
} }
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = _interpreter_try_call(state, &callee, &params, into); result = _interpreter_try_call(state, &callee, &params, into);
libab_ref_free(&callee); libab_ref_free(&callee);
libab_ref_vec_free(&params); libab_ref_vec_free(&params);
@ -629,25 +681,29 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
} else if (tree->variant == TREE_VOID) { } else if (tree->variant == TREE_VOID) {
libab_ref_null(into); libab_ref_null(into);
} else if (tree->variant == TREE_ID) { } else if (tree->variant == TREE_ID) {
libab_table_search_value(libab_ref_get(scope), tree->string_value, into); libab_table_search_value(libab_ref_get(scope), tree->string_value,
if(libab_ref_get(into) == NULL) { into);
if (libab_ref_get(into) == NULL) {
result = LIBAB_UNEXPECTED; result = LIBAB_UNEXPECTED;
} }
} else if (tree->variant == TREE_CALL) { } else if (tree->variant == TREE_CALL) {
result = _interpreter_run_function_node(state, tree, into, scope); result = _interpreter_run_function_node(state, tree, into, scope);
} else if (tree->variant == TREE_OP) { } else if (tree->variant == TREE_OP) {
libab_operator* to_call = libab_table_search_operator(libab_ref_get(scope), tree->string_value, OPERATOR_INFIX); libab_operator* to_call = libab_table_search_operator(
result = _interpreter_call_operator(state, to_call, into, scope, libab_ref_get(scope), tree->string_value, OPERATOR_INFIX);
vec_index(&tree->children, 0), result = _interpreter_call_operator(state, to_call, into, scope,
vec_index(&tree->children, 1)); vec_index(&tree->children, 0),
vec_index(&tree->children, 1));
} else if (tree->variant == TREE_PREFIX_OP) { } else if (tree->variant == TREE_PREFIX_OP) {
libab_operator* to_call = libab_table_search_operator(libab_ref_get(scope), tree->string_value, OPERATOR_PREFIX); libab_operator* to_call = libab_table_search_operator(
result = _interpreter_call_operator(state, to_call, into, scope, libab_ref_get(scope), tree->string_value, OPERATOR_PREFIX);
vec_index(&tree->children, 0)); result = _interpreter_call_operator(state, to_call, into, scope,
vec_index(&tree->children, 0));
} else if (tree->variant == TREE_POSTFIX_OP) { } else if (tree->variant == TREE_POSTFIX_OP) {
libab_operator* to_call = libab_table_search_operator(libab_ref_get(scope), tree->string_value, OPERATOR_POSTFIX); libab_operator* to_call = libab_table_search_operator(
result = _interpreter_call_operator(state, to_call, into, scope, libab_ref_get(scope), tree->string_value, OPERATOR_POSTFIX);
vec_index(&tree->children, 0)); result = _interpreter_call_operator(state, to_call, into, scope,
vec_index(&tree->children, 0));
} }
if (needs_scope) { if (needs_scope) {

View File

@ -1,10 +1,10 @@
#include "libabacus.h" #include "libabacus.h"
#include "debug.h"
#include "lexer.h" #include "lexer.h"
#include "reserved.h" #include "reserved.h"
#include "util.h" #include "util.h"
#include "value.h" #include "value.h"
#include <stdlib.h> #include <stdlib.h>
#include "debug.h"
void _free_function_list(void* function_list) { void _free_function_list(void* function_list) {
libab_function_list_free(function_list); libab_function_list_free(function_list);
@ -346,17 +346,17 @@ libab_result libab_run(libab* ab, const char* string, libab_ref* value) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
ll tokens; ll tokens;
libab_tree* root; libab_tree* root;
ll_init(&tokens); ll_init(&tokens);
libab_ref_null(value); libab_ref_null(value);
result = libab_lexer_lex(&ab->lexer, string, &tokens); result = libab_lexer_lex(&ab->lexer, string, &tokens);
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
result = libab_parser_parse(&ab->parser, &tokens, string, &root); result = libab_parser_parse(&ab->parser, &tokens, string, &root);
} }
if(result == LIBAB_SUCCESS) { if (result == LIBAB_SUCCESS) {
libab_debug_print_tree(root); libab_debug_print_tree(root);
libab_ref_free(value); libab_ref_free(value);
result = libab_interpreter_run(&ab->intr, root, value); result = libab_interpreter_run(&ab->intr, root, value);

View File

@ -12,13 +12,14 @@ libab_result libab_ref_vec_init(libab_ref_vec* vec) {
return result; return result;
} }
libab_result libab_ref_vec_init_copy(libab_ref_vec* vec, libab_ref_vec* copy_of) { libab_result libab_ref_vec_init_copy(libab_ref_vec* vec,
libab_ref_vec* copy_of) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
if((vec->data = malloc(sizeof(*vec->data) * copy_of->capacity))) { if ((vec->data = malloc(sizeof(*vec->data) * copy_of->capacity))) {
size_t index = 0; size_t index = 0;
vec->size = copy_of->size; vec->size = copy_of->size;
vec->capacity = copy_of->capacity; vec->capacity = copy_of->capacity;
for(; index < copy_of->size; index++) { for (; index < copy_of->size; index++) {
libab_ref_copy(&copy_of->data[index], &vec->data[index]); libab_ref_copy(&copy_of->data[index], &vec->data[index]);
} }
} else { } else {
@ -75,7 +76,7 @@ void libab_ref_vec_index(libab_ref_vec* vec, size_t index, libab_ref* into) {
void libab_ref_vec_clear(libab_ref_vec* vec) { void libab_ref_vec_clear(libab_ref_vec* vec) {
size_t i = 0; size_t i = 0;
for(; i < vec->size; i++) { for (; i < vec->size; i++) {
libab_ref_free(&vec->data[i]); libab_ref_free(&vec->data[i]);
} }
vec->size = 0; vec->size = 0;

View File

@ -53,7 +53,8 @@ libab_result libab_resolve_parsetype(libab_parsetype* to_resolve,
(LIBABACUS_TYPE_F_RESOLVED | LIBABACUS_TYPE_F_PLACE)); (LIBABACUS_TYPE_F_RESOLVED | LIBABACUS_TYPE_F_PLACE));
check_parents = !(to_resolve->variant & LIBABACUS_TYPE_F_PLACE); check_parents = !(to_resolve->variant & LIBABACUS_TYPE_F_PLACE);
if ((to_resolve->variant & LIBABACUS_TYPE_F_PLACE) && (to_resolve->variant & LIBABACUS_TYPE_F_PARENT)) { if ((to_resolve->variant & LIBABACUS_TYPE_F_PLACE) &&
(to_resolve->variant & LIBABACUS_TYPE_F_PARENT)) {
result = LIBAB_UNEXPECTED; result = LIBAB_UNEXPECTED;
} }