From 8214aa834455f9a54c259e9f1bf25285efce8520 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 20 Apr 2018 00:25:31 -0700 Subject: [PATCH] Allow tree-based function implementations. --- include/custom.h | 34 ++++++++++++++++++++++++++++++++-- src/custom.c | 3 +++ src/libabacus.c | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/custom.h b/include/custom.h index 4b02ad9..80abb42 100644 --- a/include/custom.h +++ b/include/custom.h @@ -19,15 +19,43 @@ enum libab_operator_variant_e { OPERATOR_POSTFIX }; +/** + * The variant of the implementation of a behavior. + */ +enum libab_behavior_variant_e { + BIMPL_INTERNAL, + BIMPL_TREE +}; + +/** + * A struct that represents the implementation of a behavior. + */ +struct libab_behavior_impl_s { + /** + * The variant of this implementation. + */ + enum libab_behavior_variant_e variant; + union { + /** + * The internal function used for an internal implementation. + */ + libab_function_ptr internal; + /** + * The tree-based implementation. + */ + libab_ref tree; + } data_u; +}; + /** * The common information * that both operators and functions shared. */ struct libab_behavior_s { /** - * The function that handles the parameters. + * The implementation of this behavior. */ - libab_function_ptr function; + struct libab_behavior_impl_s impl; /** * The type of the function. */ @@ -72,6 +100,8 @@ struct libab_function_s { }; typedef enum libab_operator_variant_e libab_operator_variant; +typedef enum libab_behavior_variant_e libab_behavior_variant; +typedef struct libab_behavior_impl_s libab_behavior_impl; typedef struct libab_behavior_s libab_behavior; typedef struct libab_operator_s libab_operator; typedef struct libab_function_s libab_function; diff --git a/src/custom.c b/src/custom.c index 0939490..4366193 100644 --- a/src/custom.c +++ b/src/custom.c @@ -2,6 +2,9 @@ void libab_behavior_free(libab_behavior* behavior) { libab_ref_free(&behavior->type); + if(behavior->impl.variant == BIMPL_TREE) { + libab_ref_free(&behavior->impl.data_u.tree); + } } void libab_operator_free(libab_operator* op) { diff --git a/src/libabacus.c b/src/libabacus.c index a95c4ec..94cdab0 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -38,6 +38,8 @@ libab_result _initialize_behavior(libab* ab, libab_behavior* behavior, ll_init(&tokens); + behavior->impl.variant = BIMPL_INTERNAL; + behavior->impl.data_u.internal = func; result = libab_lexer_lex(&ab->lexer, type, &tokens); if(result == LIBAB_SUCCESS) { result = libab_parser_parse_type(&ab->parser, &tokens, type, &behavior->type);