Compare commits
7 Commits
6822c97750
...
4540559097
Author | SHA1 | Date |
---|---|---|
Danila Fedorin | 4540559097 | |
Danila Fedorin | 48300cd86e | |
Danila Fedorin | a5429ae2c8 | |
Danila Fedorin | 03577269f2 | |
Danila Fedorin | 7dfc55154e | |
Danila Fedorin | 13ccea10e4 | |
Danila Fedorin | 82747eae6a |
|
@ -11,7 +11,7 @@ struct libab_s;
|
||||||
* A function pointer that is called
|
* A function pointer that is called
|
||||||
* to execute a certain type of function.
|
* to execute a certain type of function.
|
||||||
*/
|
*/
|
||||||
typedef libab_result (*libab_function_ptr)(struct libab_s*, libab_ref_vec*, libab_ref*);
|
typedef libab_result (*libab_function_ptr)(struct libab_s*, libab_ref*, libab_ref_vec*, libab_ref*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The variant of the operator that
|
* The variant of the operator that
|
||||||
|
|
|
@ -43,23 +43,27 @@ libab_result 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 scope the parent scope to use for running the tree.
|
||||||
* @param mode the scope mode to use.
|
* @param mode the scope mode to use.
|
||||||
* @param into the reference into which the result of the execution will be
|
* @param into the reference into which the result of the execution will be
|
||||||
* stored.
|
* 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,
|
||||||
|
libab_ref* scope,
|
||||||
libab_interpreter_scope_mode mode,
|
libab_interpreter_scope_mode mode,
|
||||||
libab_ref* into);
|
libab_ref* into);
|
||||||
/**
|
/**
|
||||||
* Calls a function with the given parameters.
|
* Calls a function with the given parameters.
|
||||||
* @param intr the interpreter to use to call the function.
|
* @param intr the interpreter to use to call the function.
|
||||||
|
* @param scope the scope in which the function should be searched for.
|
||||||
* @param function the function to call.
|
* @param function the function to call.
|
||||||
* @param params the parameters to pass to the function.
|
* @param params the parameters to pass to the function.
|
||||||
* @param into the reference to store the result into.
|
* @param into the reference to store the result into.
|
||||||
* @return the result of the call.
|
* @return the result of the call.
|
||||||
*/
|
*/
|
||||||
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||||
|
libab_ref* scope,
|
||||||
const char* function,
|
const char* function,
|
||||||
libab_ref_vec* params,
|
libab_ref_vec* params,
|
||||||
libab_ref* into);
|
libab_ref* into);
|
||||||
|
|
|
@ -197,17 +197,55 @@ void libab_get_unit_value(libab* ab, libab_ref* into);
|
||||||
* @return the result of the computation.
|
* @return the result of the computation.
|
||||||
*/
|
*/
|
||||||
libab_result libab_run(libab* ab, const char* string, libab_ref* value);
|
libab_result libab_run(libab* ab, const char* string, libab_ref* value);
|
||||||
|
/**
|
||||||
|
* Runs an already-compiled tree.
|
||||||
|
* @param ab the libabacus instance to use for executing code.
|
||||||
|
* @param tree the tree the run.
|
||||||
|
* @param value the reference into which to store the output.
|
||||||
|
* @return the result of the computation.
|
||||||
|
*/
|
||||||
|
libab_result libab_run_tree(libab* ab, libab_tree* tree, libab_ref* value);
|
||||||
/**
|
/**
|
||||||
* Calls a function with the given name and parameters.
|
* Calls a function with the given name and parameters.
|
||||||
* @param ab the libabacus instance to use to call the function.
|
* @param ab the libabacus instance to use to call the function.
|
||||||
* @param function the name of the function to call.
|
* @param function the name of the function to call.
|
||||||
* @param iunto the reference into which to store the result.
|
* @param into the reference into which to store the result.
|
||||||
* @param param_count the number of parameters given to this function.
|
* @param param_count the number of parameters given to this function.
|
||||||
* @return the result of the call.
|
* @return the result of the call.
|
||||||
*/
|
*/
|
||||||
libab_result libab_run_function(libab* ab, const char* function,
|
libab_result libab_run_function(libab* ab, const char* function,
|
||||||
libab_ref* into,
|
libab_ref* into,
|
||||||
size_t param_count, ...);
|
size_t param_count, ...);
|
||||||
|
/**
|
||||||
|
* Calls a string in a given surrounding scope.
|
||||||
|
* @param ab the libabacus instance to use to call the function.
|
||||||
|
* @param strign the string to run.
|
||||||
|
* @param scope the scope to use for calling the string.
|
||||||
|
* @param value the reference into which to store the output of the computation.
|
||||||
|
* @return the result of the computation.
|
||||||
|
*/
|
||||||
|
libab_result libab_run_scoped(libab* ab, const char* string, libab_ref* scope, libab_ref* value);
|
||||||
|
/**
|
||||||
|
* Calls a tree in a given scope.
|
||||||
|
* @param ab the libabacus instance to use to call the tree.
|
||||||
|
* @param tree the tree to call.
|
||||||
|
* @param scope the scope to use for the call.
|
||||||
|
* @param value the reference into which to store the output.
|
||||||
|
* @return the result of the call.
|
||||||
|
*/
|
||||||
|
libab_result libab_run_tree_scoped(libab* ab, libab_tree* tree, libab_ref* scope, libab_ref* value);
|
||||||
|
/**
|
||||||
|
* Calls a function with the given name and parameters using a given scope.
|
||||||
|
* @param ab the libabacus instance to use to call the function.
|
||||||
|
* @param function the name of the function to call.
|
||||||
|
* @param scope the scope in which to perform the call.
|
||||||
|
* @param into the reference into which to store the result.
|
||||||
|
* @param param_count the number of parameters given to this function.
|
||||||
|
* @return the result of the call.
|
||||||
|
*/
|
||||||
|
libab_result libab_run_function_scoped(libab* ab, const char* function, libab_ref* scope,
|
||||||
|
libab_ref* into,
|
||||||
|
size_t param_count, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases all the resources allocated by libabacus.
|
* Releases all the resources allocated by libabacus.
|
||||||
|
|
|
@ -23,6 +23,11 @@ struct libab_reserved_operator_s {
|
||||||
* The associativity of this operator.
|
* The associativity of this operator.
|
||||||
*/
|
*/
|
||||||
int associativity;
|
int associativity;
|
||||||
|
/**
|
||||||
|
* The function this operator performs.
|
||||||
|
*/
|
||||||
|
libab_result (*function)(libab*, libab_ref*, libab_tree*,
|
||||||
|
libab_tree*, libab_ref*);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct libab_reserved_operator_s libab_reserved_operator;
|
typedef struct libab_reserved_operator_s libab_reserved_operator;
|
||||||
|
|
|
@ -38,34 +38,34 @@ libab_result create_double_value(libab* ab, double val, libab_ref* into) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result function_atan(libab* ab, libab_ref_vec* params, libab_ref* into) {
|
libab_result function_atan(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) {
|
||||||
printf("atan called\n");
|
printf("atan called\n");
|
||||||
double* val = libab_unwrap_param(params, 0);
|
double* val = libab_unwrap_param(params, 0);
|
||||||
return create_double_value(ab, atan(*val), into);
|
return create_double_value(ab, atan(*val), into);
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result function_atan2(libab* ab, libab_ref_vec* params, libab_ref* into) {
|
libab_result function_atan2(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) {
|
||||||
printf("atan2 called\n");
|
printf("atan2 called\n");
|
||||||
double* left = libab_unwrap_param(params, 0);
|
double* left = libab_unwrap_param(params, 0);
|
||||||
double* right = libab_unwrap_param(params, 1);
|
double* right = libab_unwrap_param(params, 1);
|
||||||
return create_double_value(ab, atan2(*left, *right), into);
|
return create_double_value(ab, atan2(*left, *right), into);
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result function_print_num(libab* ab, libab_ref_vec* params, libab_ref* into) {
|
libab_result function_print_num(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) {
|
||||||
double* param = libab_unwrap_param(params, 0);
|
double* param = libab_unwrap_param(params, 0);
|
||||||
printf("%f\n", *param);
|
printf("%f\n", *param);
|
||||||
libab_get_unit_value(ab, into);
|
libab_get_unit_value(ab, into);
|
||||||
return LIBAB_SUCCESS;
|
return LIBAB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result function_print_unit(libab* ab, libab_ref_vec* params, libab_ref* into) {
|
libab_result function_print_unit(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) {
|
||||||
printf("()\n");
|
printf("()\n");
|
||||||
libab_get_unit_value(ab, into);
|
libab_get_unit_value(ab, into);
|
||||||
return LIBAB_SUCCESS;
|
return LIBAB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OP_FUNCTION(name, expression) \
|
#define OP_FUNCTION(name, expression) \
|
||||||
libab_result name(libab* ab, libab_ref_vec* params, libab_ref* into) { \
|
libab_result name(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) { \
|
||||||
libab_result result = LIBAB_SUCCESS; \
|
libab_result result = LIBAB_SUCCESS; \
|
||||||
double right; \
|
double right; \
|
||||||
double left; \
|
double left; \
|
||||||
|
@ -117,13 +117,33 @@ libab_result register_functions(libab* ab) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
libab_result loop(libab* ab, int interaction_count, libab_ref* scope) {
|
||||||
|
libab_result result = LIBAB_SUCCESS;
|
||||||
char input_buffer[2048];
|
char input_buffer[2048];
|
||||||
int interaction_count = INTERACTIONS;
|
|
||||||
libab_ref eval_into;
|
libab_ref eval_into;
|
||||||
libab_ref call_into;
|
libab_ref call_into;
|
||||||
libab_result result;
|
|
||||||
libab_result eval_result;
|
libab_result eval_result;
|
||||||
|
|
||||||
|
while (interaction_count-- && result == LIBAB_SUCCESS) {
|
||||||
|
printf("(%d) > ", INTERACTIONS - interaction_count);
|
||||||
|
fgets(input_buffer, 2048, stdin);
|
||||||
|
eval_result = libab_run_scoped(ab, input_buffer, scope, &eval_into);
|
||||||
|
|
||||||
|
if (eval_result != LIBAB_SUCCESS) {
|
||||||
|
printf("Invalid input (error code %d).\n", eval_result);
|
||||||
|
} else {
|
||||||
|
result = libab_run_function_scoped(ab, "print", scope, &call_into, 1, &eval_into);
|
||||||
|
libab_ref_free(&call_into);
|
||||||
|
}
|
||||||
|
libab_ref_free(&eval_into);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
libab_result result;
|
||||||
|
libab_ref scope;
|
||||||
libab ab;
|
libab ab;
|
||||||
|
|
||||||
if (libab_init(&ab, impl_parse, impl_free) != LIBAB_SUCCESS) {
|
if (libab_init(&ab, impl_parse, impl_free) != LIBAB_SUCCESS) {
|
||||||
|
@ -132,18 +152,12 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
result = register_functions(&ab);
|
result = register_functions(&ab);
|
||||||
while (interaction_count-- && result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
printf("(%d) > ", INTERACTIONS - interaction_count);
|
result = libab_create_table(&scope, &ab.table);
|
||||||
fgets(input_buffer, 2048, stdin);
|
}
|
||||||
eval_result = libab_run(&ab, input_buffer, &eval_into);
|
if(result == LIBAB_SUCCESS) {
|
||||||
|
loop(&ab, INTERACTIONS, &scope);
|
||||||
if (eval_result != LIBAB_SUCCESS) {
|
libab_ref_free(&scope);
|
||||||
printf("Invalid input.\n");
|
|
||||||
} else {
|
|
||||||
result = libab_run_function(&ab, "print", &call_into, 1, &eval_into);
|
|
||||||
libab_ref_free(&call_into);
|
|
||||||
}
|
|
||||||
libab_ref_free(&eval_into);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_free(&ab);
|
libab_free(&ab);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "free_functions.h"
|
#include "free_functions.h"
|
||||||
|
#include "reserved.h"
|
||||||
|
|
||||||
libab_result libab_interpreter_init(libab_interpreter* intr, libab* ab) {
|
libab_result libab_interpreter_init(libab_interpreter* intr, libab* ab) {
|
||||||
libab_result result;
|
libab_result result;
|
||||||
|
@ -21,9 +22,10 @@ struct interpreter_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
void _interpreter_init(struct interpreter_state* state,
|
void _interpreter_init(struct interpreter_state* state,
|
||||||
libab_interpreter* intr) {
|
libab_interpreter* intr,
|
||||||
|
libab_ref* scope) {
|
||||||
state->ab = intr->ab;
|
state->ab = intr->ab;
|
||||||
state->base_table = libab_ref_get(&intr->ab->table);
|
state->base_table = libab_ref_get(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _interpreter_free(struct interpreter_state* state) {}
|
void _interpreter_free(struct interpreter_state* state) {}
|
||||||
|
@ -530,7 +532,7 @@ libab_result _interpreter_call_behavior(struct interpreter_state* state,
|
||||||
libab_ref* into) {
|
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(state->ab, params, into);
|
result = behavior->data_u.internal(state->ab, scope, params, into);
|
||||||
} else {
|
} else {
|
||||||
result = _interpreter_call_tree(state, behavior->data_u.tree, params, scope, into);
|
result = _interpreter_call_tree(state, behavior->data_u.tree, params, scope, into);
|
||||||
}
|
}
|
||||||
|
@ -1162,6 +1164,13 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
|
||||||
|
|
||||||
libab_ref_copy(&function, into);
|
libab_ref_copy(&function, into);
|
||||||
libab_ref_free(&function);
|
libab_ref_free(&function);
|
||||||
|
} else if(tree->variant == TREE_RESERVED_OP) {
|
||||||
|
const libab_reserved_operator* op =
|
||||||
|
libab_find_reserved_operator(tree->string_value);
|
||||||
|
result = op->function(state->ab, scope,
|
||||||
|
vec_index(&tree->children, 0),
|
||||||
|
vec_index(&tree->children, 1),
|
||||||
|
into);
|
||||||
} else {
|
} else {
|
||||||
libab_get_unit_value(state->ab, into);
|
libab_get_unit_value(state->ab, into);
|
||||||
}
|
}
|
||||||
|
@ -1174,19 +1183,21 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree,
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree,
|
libab_result libab_interpreter_run(libab_interpreter* intr, libab_tree* tree,
|
||||||
|
libab_ref* scope,
|
||||||
libab_interpreter_scope_mode mode,
|
libab_interpreter_scope_mode mode,
|
||||||
libab_ref* into) {
|
libab_ref* into) {
|
||||||
struct interpreter_state state;
|
struct interpreter_state state;
|
||||||
libab_result result;
|
libab_result result;
|
||||||
|
|
||||||
_interpreter_init(&state, intr);
|
_interpreter_init(&state, intr, scope);
|
||||||
result = _interpreter_run(&state, tree, into, &state.ab->table, mode);
|
result = _interpreter_run(&state, tree, into, scope, mode);
|
||||||
_interpreter_free(&state);
|
_interpreter_free(&state);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||||
|
libab_ref* scope,
|
||||||
const char* function,
|
const char* function,
|
||||||
libab_ref_vec* params,
|
libab_ref_vec* params,
|
||||||
libab_ref* into) {
|
libab_ref* into) {
|
||||||
|
@ -1194,10 +1205,10 @@ libab_result libab_interpreter_run_function(libab_interpreter* intr,
|
||||||
libab_ref function_value;
|
libab_ref function_value;
|
||||||
libab_result result;
|
libab_result result;
|
||||||
|
|
||||||
_interpreter_init(&state, intr);
|
_interpreter_init(&state, intr, scope);
|
||||||
|
|
||||||
libab_ref_null(into);
|
libab_ref_null(into);
|
||||||
result = _interpreter_require_value(&state.ab->table,
|
result = _interpreter_require_value(scope,
|
||||||
function, &function_value);
|
function, &function_value);
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
libab_ref_free(into);
|
libab_ref_free(into);
|
||||||
|
|
100
src/libabacus.c
100
src/libabacus.c
|
@ -378,28 +378,49 @@ void libab_get_unit_value(libab* ab, libab_ref* into) {
|
||||||
libab_interpreter_unit_value(&ab->intr, into);
|
libab_interpreter_unit_value(&ab->intr, into);
|
||||||
}
|
}
|
||||||
|
|
||||||
libab_result libab_run(libab* ab, const char* string, libab_ref* value) {
|
libab_result _create_tree(libab* ab, const char* string, libab_tree** into) {
|
||||||
libab_result result = LIBAB_SUCCESS;
|
libab_result result = LIBAB_SUCCESS;
|
||||||
ll tokens;
|
ll tokens;
|
||||||
libab_tree* root;
|
|
||||||
|
|
||||||
ll_init(&tokens);
|
ll_init(&tokens);
|
||||||
libab_ref_null(value);
|
*into = NULL;
|
||||||
|
|
||||||
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, into);
|
||||||
}
|
|
||||||
|
|
||||||
if (result == LIBAB_SUCCESS) {
|
|
||||||
libab_ref_free(value);
|
|
||||||
result = libab_interpreter_run(&ab->intr, root, SCOPE_NORMAL, value);
|
|
||||||
libab_tree_free_recursive(root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ll_foreach(&tokens, NULL, compare_always, libab_lexer_foreach_match_free);
|
ll_foreach(&tokens, NULL, compare_always, libab_lexer_foreach_match_free);
|
||||||
ll_free(&tokens);
|
ll_free(&tokens);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_result _handle_va_params(libab* ab, libab_ref_vec* into, size_t param_count, va_list args) {
|
||||||
|
libab_result result = libab_ref_vec_init(into);
|
||||||
|
if(result == LIBAB_SUCCESS) {
|
||||||
|
while(result == LIBAB_SUCCESS && param_count--) {
|
||||||
|
result = libab_ref_vec_insert(into, va_arg(args, libab_ref*));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result != LIBAB_SUCCESS) {
|
||||||
|
libab_ref_vec_free(into);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_result libab_run(libab* ab, const char* string, libab_ref* value) {
|
||||||
|
libab_result result;
|
||||||
|
libab_tree* root;
|
||||||
|
|
||||||
|
libab_ref_null(value);
|
||||||
|
result = _create_tree(ab, string, &root);
|
||||||
|
|
||||||
|
if (result == LIBAB_SUCCESS) {
|
||||||
|
libab_ref_free(value);
|
||||||
|
result = libab_interpreter_run(&ab->intr, root, &ab->table, SCOPE_FORCE, value);
|
||||||
|
libab_tree_free_recursive(root);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -413,16 +434,10 @@ libab_result libab_run_function(libab* ab, const char* function,
|
||||||
|
|
||||||
va_start(args, param_count);
|
va_start(args, param_count);
|
||||||
libab_ref_null(into);
|
libab_ref_null(into);
|
||||||
result = libab_ref_vec_init(¶ms);
|
result = _handle_va_params(ab, ¶ms, param_count, args);
|
||||||
if(result == LIBAB_SUCCESS) {
|
if(result == LIBAB_SUCCESS) {
|
||||||
while(result == LIBAB_SUCCESS && param_count--) {
|
libab_ref_free(into);
|
||||||
result = libab_ref_vec_insert(¶ms, va_arg(args, libab_ref*));
|
result = libab_interpreter_run_function(&ab->intr, &ab->table, function, ¶ms, into);
|
||||||
}
|
|
||||||
|
|
||||||
if(result == LIBAB_SUCCESS) {
|
|
||||||
libab_ref_free(into);
|
|
||||||
result = libab_interpreter_run_function(&ab->intr, function, ¶ms, into);
|
|
||||||
}
|
|
||||||
|
|
||||||
libab_ref_vec_free(¶ms);
|
libab_ref_vec_free(¶ms);
|
||||||
}
|
}
|
||||||
|
@ -431,6 +446,49 @@ libab_result libab_run_function(libab* ab, const char* function,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libab_result libab_run_tree(libab* ab, libab_tree* tree, libab_ref* value) {
|
||||||
|
return libab_interpreter_run(&ab->intr, tree, &ab->table, SCOPE_FORCE, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_result libab_run_scoped(libab* ab, const char* string, libab_ref* scope, libab_ref* into) {
|
||||||
|
libab_result result;
|
||||||
|
libab_tree* root;
|
||||||
|
|
||||||
|
libab_ref_null(into);
|
||||||
|
result = _create_tree(ab, string, &root);
|
||||||
|
if(result == LIBAB_SUCCESS) {
|
||||||
|
libab_ref_free(into);
|
||||||
|
result = libab_interpreter_run(&ab->intr, root, scope, SCOPE_NONE, into);
|
||||||
|
libab_tree_free_recursive(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_result libab_run_function_scoped(libab* ab, const char* function, libab_ref* scope, libab_ref* into,
|
||||||
|
size_t param_count, ...) {
|
||||||
|
libab_ref_vec params;
|
||||||
|
libab_result result;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, param_count);
|
||||||
|
libab_ref_null(into);
|
||||||
|
result = _handle_va_params(ab, ¶ms, param_count, args);
|
||||||
|
if(result == LIBAB_SUCCESS) {
|
||||||
|
libab_ref_free(into);
|
||||||
|
result = libab_interpreter_run_function(&ab->intr, scope, function, ¶ms, into);
|
||||||
|
|
||||||
|
libab_ref_vec_free(¶ms);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
libab_result libab_run_tree_scoped(libab* ab, libab_tree* tree, libab_ref* scope, libab_ref* into) {
|
||||||
|
return libab_interpreter_run(&ab->intr, tree, scope, SCOPE_NONE, into);
|
||||||
|
}
|
||||||
|
|
||||||
libab_result libab_free(libab* ab) {
|
libab_result libab_free(libab* ab) {
|
||||||
libab_table_free(libab_ref_get(&ab->table));
|
libab_table_free(libab_ref_get(&ab->table));
|
||||||
libab_ref_free(&ab->table);
|
libab_ref_free(&ab->table);
|
||||||
|
|
|
@ -1071,7 +1071,6 @@ libab_result _parse_expression(struct parser_state* state,
|
||||||
result = LIBAB_UNEXPECTED;
|
result = LIBAB_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ll_foreach(&op_stack, NULL, compare_always, _parser_foreach_free_tree);
|
|
||||||
ll_foreach(&out_stack, NULL, compare_always, _parser_foreach_free_tree);
|
ll_foreach(&out_stack, NULL, compare_always, _parser_foreach_free_tree);
|
||||||
ll_free(&op_stack);
|
ll_free(&op_stack);
|
||||||
ll_free(&out_stack);
|
ll_free(&out_stack);
|
||||||
|
|
|
@ -2,11 +2,38 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
libab_result _behavior_assign(libab* ab, libab_ref* scope,
|
||||||
|
libab_tree* left, libab_tree* right,
|
||||||
|
libab_ref* into) {
|
||||||
|
libab_result result = LIBAB_SUCCESS;
|
||||||
|
|
||||||
|
if(left->variant == TREE_ID) {
|
||||||
|
result = libab_run_tree_scoped(ab, right, scope, into);
|
||||||
|
if(result == LIBAB_SUCCESS) {
|
||||||
|
result = libab_put_table_value(libab_ref_get(scope), left->string_value, into);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result != LIBAB_SUCCESS) {
|
||||||
|
libab_ref_free(into);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = LIBAB_UNEXPECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result != LIBAB_SUCCESS) {
|
||||||
|
libab_ref_null(into);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static const libab_reserved_operator libab_reserved_operators[] = {{
|
static const libab_reserved_operator libab_reserved_operators[] = {{
|
||||||
"=", /* Assignment */
|
"=", /* Assignment */
|
||||||
0, /* Lowest precedence */
|
0, /* Lowest precedence */
|
||||||
1 /* Right associative, a = b = 6 should be a = (b = 6) */
|
1, /* Right associative, a = b = 6 should be a = (b = 6) */
|
||||||
|
_behavior_assign
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static const size_t element_count =
|
static const size_t element_count =
|
||||||
sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);
|
sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue