From 48300cd86ea0313778a4f703aae404e81574a653 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 21 Jun 2018 19:00:45 -0700 Subject: [PATCH] Implement reserved operators. --- include/reserved.h | 5 +++++ src/interpreter.c | 8 ++++++++ src/reserved.c | 29 ++++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/reserved.h b/include/reserved.h index cd2ae3f..2d9d692 100644 --- a/include/reserved.h +++ b/include/reserved.h @@ -23,6 +23,11 @@ struct libab_reserved_operator_s { * The associativity of this operator. */ 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; diff --git a/src/interpreter.c b/src/interpreter.c index 9140712..a6fb3e7 100644 --- a/src/interpreter.c +++ b/src/interpreter.c @@ -2,6 +2,7 @@ #include "util.h" #include "value.h" #include "free_functions.h" +#include "reserved.h" libab_result libab_interpreter_init(libab_interpreter* intr, libab* ab) { libab_result result; @@ -1163,6 +1164,13 @@ libab_result _interpreter_run(struct interpreter_state* state, libab_tree* tree, libab_ref_copy(&function, into); 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 { libab_get_unit_value(state->ab, into); } diff --git a/src/reserved.c b/src/reserved.c index 04983ce..43f13b0 100644 --- a/src/reserved.c +++ b/src/reserved.c @@ -2,11 +2,38 @@ #include "string.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[] = {{ "=", /* Assignment */ 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 = sizeof(libab_reserved_operators) / sizeof(libab_reserved_operator);