2018-03-16 22:11:05 -07:00
|
|
|
#include "reserved.h"
|
|
|
|
#include "string.h"
|
2018-03-16 23:09:11 -07:00
|
|
|
#include "util.h"
|
2018-08-10 18:40:31 -07:00
|
|
|
#include "value.h"
|
|
|
|
#include "libabacus.h"
|
2018-03-16 22:11:05 -07:00
|
|
|
|
2018-06-21 19:00:45 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-08-10 18:40:31 -07:00
|
|
|
libab_result _expect_boolean(libab* ab, libab_ref* scope,
|
|
|
|
libab_tree* to_run, int* into) {
|
|
|
|
libab_result result = LIBAB_SUCCESS;
|
|
|
|
libab_ref output;
|
|
|
|
libab_value* value;
|
|
|
|
libab_parsetype* type;
|
|
|
|
|
|
|
|
result = libab_run_tree_scoped(ab, to_run, scope, &output);
|
|
|
|
if(result == LIBAB_SUCCESS) {
|
|
|
|
value = libab_ref_get(&output);
|
|
|
|
type = libab_ref_get(&value->type);
|
|
|
|
if(type->data_u.base != libab_get_basetype_bool(ab)) {
|
|
|
|
result = LIBAB_BAD_CALL;
|
|
|
|
} else {
|
|
|
|
*into = *((int*) libab_ref_get(&value->data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
libab_ref_free(&output);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
libab_result _behavior_land(libab* ab, libab_ref* scope,
|
|
|
|
libab_tree* left, libab_tree* right,
|
|
|
|
libab_ref* into) {
|
|
|
|
libab_result result = LIBAB_SUCCESS;
|
|
|
|
int temp;
|
|
|
|
result = _expect_boolean(ab, scope, left, &temp);
|
|
|
|
if(result == LIBAB_SUCCESS && temp) {
|
|
|
|
result = _expect_boolean(ab, scope, right, &temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(result == LIBAB_SUCCESS) {
|
|
|
|
libab_get_bool_value(ab, temp, into);
|
|
|
|
} else {
|
|
|
|
libab_ref_null(into);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
libab_result _behavior_lor(libab* ab, libab_ref* scope,
|
|
|
|
libab_tree* left, libab_tree* right,
|
|
|
|
libab_ref* into) {
|
|
|
|
libab_result result = LIBAB_SUCCESS;
|
|
|
|
int temp = 0;
|
|
|
|
result = _expect_boolean(ab, scope, left, &temp);
|
|
|
|
if(result == LIBAB_SUCCESS && !temp) {
|
|
|
|
result = _expect_boolean(ab, scope, right, &temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(result == LIBAB_SUCCESS) {
|
|
|
|
libab_get_bool_value(ab, temp, into);
|
|
|
|
} else {
|
|
|
|
libab_ref_null(into);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const libab_reserved_operator libab_reserved_operators[] = {
|
|
|
|
{
|
|
|
|
"=", /* Assignment */
|
|
|
|
0, /* Lowest precedence */
|
|
|
|
1, /* Right associative, a = b = 6 should be a = (b = 6) */
|
|
|
|
_behavior_assign
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"&&", /* Logical and */
|
|
|
|
0, /* Low precedence */
|
|
|
|
-1, /* Left associative. */
|
|
|
|
_behavior_land
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"||", /* Logical or */
|
|
|
|
0, /* Low precedence */
|
|
|
|
-1, /* Left associative. */
|
|
|
|
_behavior_lor
|
|
|
|
},
|
|
|
|
};
|
2018-06-21 19:00:45 -07:00
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
static const size_t element_count =
|
2018-03-16 23:09:11 -07:00
|
|
|
sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);
|
2018-03-16 22:11:05 -07:00
|
|
|
|
|
|
|
const libab_reserved_operator* libab_find_reserved_operator(const char* name) {
|
|
|
|
size_t i;
|
2018-04-21 14:09:01 -07:00
|
|
|
for (i = 0; i < element_count; i++) {
|
|
|
|
if (strcmp(name, libab_reserved_operators[i].op) == 0)
|
2018-03-16 22:11:05 -07:00
|
|
|
return &libab_reserved_operators[i];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-03-16 23:09:11 -07:00
|
|
|
|
|
|
|
libab_result libab_register_reserved_operators(libab_lexer* lexer) {
|
|
|
|
libab_result result = LIBAB_SUCCESS;
|
2018-08-10 18:40:21 -07:00
|
|
|
char buffer[16];
|
2018-03-16 23:09:11 -07:00
|
|
|
size_t i;
|
2018-04-21 14:09:01 -07:00
|
|
|
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
2018-08-10 18:40:21 -07:00
|
|
|
libab_sanitize(buffer, libab_reserved_operators[i].op, 16);
|
2018-04-21 14:09:01 -07:00
|
|
|
result = libab_convert_lex_result(eval_config_add(
|
2018-08-10 18:40:21 -07:00
|
|
|
&lexer->config, buffer, TOKEN_OP_RESERVED));
|
2018-03-16 23:09:11 -07:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
libab_result libab_remove_reserved_operators(libab_lexer* lexer) {
|
|
|
|
libab_result result = LIBAB_SUCCESS;
|
2018-08-10 18:40:21 -07:00
|
|
|
char buffer[16];
|
2018-03-16 23:09:11 -07:00
|
|
|
size_t i;
|
2018-04-21 14:09:01 -07:00
|
|
|
for (i = 0; i < element_count && result == LIBAB_SUCCESS; i++) {
|
2018-08-10 18:40:21 -07:00
|
|
|
libab_sanitize(buffer, libab_reserved_operators[i].op, 16);
|
2018-04-21 14:09:01 -07:00
|
|
|
result = libab_convert_lex_result(eval_config_remove(
|
2018-08-10 18:40:21 -07:00
|
|
|
&lexer->config, buffer, TOKEN_OP_RESERVED));
|
2018-03-16 23:09:11 -07:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|