diff --git a/include/free_functions.h b/include/free_functions.h index 88ac4e0..ab28c52 100644 --- a/include/free_functions.h +++ b/include/free_functions.h @@ -24,6 +24,11 @@ void libab_free_function_list(void* func_list); * @param unit the unit to free. */ void libab_free_unit(void* unit); +/** + * Frees a boolean value. + * @param b the bool to free. + */ +void libab_free_bool(void* b); /** * Frees a parsetype. * @param parsetype the parsetype to free. diff --git a/include/libabacus.h b/include/libabacus.h index 3cbd5e0..ed46105 100644 --- a/include/libabacus.h +++ b/include/libabacus.h @@ -47,6 +47,10 @@ struct libab_s { * The number type instance. */ libab_ref type_num; + /** + * The boolean type instance. + */ + libab_ref type_bool; /** * The function list type instance. */ @@ -144,6 +148,12 @@ libab_result libab_create_type(libab* ab, libab_ref* into, const char* type); * @return the num basetype. */ libab_basetype* libab_get_basetype_num(libab* ab); +/** + * Finds and returns the built-in libabacus boolean type. + * @param ab the ab instance for which to return a type. + * @return the boolean basetype. + */ +libab_basetype* libab_get_basetype_bool(libab* ab); /** * Finds and returns the built-in libabacus function type. * @param ab the ab instance for which to return a type. @@ -169,6 +179,12 @@ libab_basetype* libab_get_basetype_unit(libab* ab); * @param into the reference to store the type into. */ void libab_get_type_num(libab* ab, libab_ref* into); +/** + * Get the type of a boolean in this libabacus instance. + * @param ab the instance to get the type for. + * @param into the reference to store the type into. + */ +void libab_get_type_bool(libab* ab, libab_ref* into); /** * Get the type of the function list in this libabacus instance. * @param ab the instance to get the type for. diff --git a/src/free_functions.c b/src/free_functions.c index 2fe60ee..16bef70 100644 --- a/src/free_functions.c +++ b/src/free_functions.c @@ -16,6 +16,9 @@ void libab_free_function_list(void* function_list) { } void libab_free_unit(void* unit) { +} +void libab_free_bool(void* b) { + free(b); } void libab_free_parsetype(void* parsetype) { libab_parsetype_free(parsetype); diff --git a/src/interactive.c b/src/interactive.c index 63e0c39..7e2b6ab 100644 --- a/src/interactive.c +++ b/src/interactive.c @@ -58,6 +58,13 @@ libab_result function_print_num(libab* ab, libab_ref* scope, libab_ref_vec* para return LIBAB_SUCCESS; } +libab_result function_print_bool(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) { + int* param = libab_unwrap_param(params, 0); + printf("%s\n", *param ? "true" : "false"); + libab_get_unit_value(ab, into); + return LIBAB_SUCCESS; +} + libab_result function_print_unit(libab* ab, libab_ref* scope, libab_ref_vec* params, libab_ref* into) { printf("()\n"); libab_get_unit_value(ab, into); @@ -88,12 +95,14 @@ libab_result register_functions(libab* ab) { libab_ref difficult_type; libab_ref print_num_type; libab_ref print_unit_type; + libab_ref print_bool_type; result = libab_create_type(ab, &trig_type, "(num)->num"); TRY(libab_create_type(ab, &atan2_type, "(num, num)->num")); TRY(libab_create_type(ab, &difficult_type, "((num)->num)->num")); TRY(libab_create_type(ab, &print_num_type, "(num)->unit")); TRY(libab_create_type(ab, &print_unit_type, "(unit)->unit")); + TRY(libab_create_type(ab, &print_bool_type, "(bool)->unit")); TRY(libab_register_function(ab, "atan", &trig_type, function_atan)); TRY(libab_register_function(ab, "atan2", &atan2_type, function_atan2)); @@ -103,6 +112,7 @@ libab_result register_functions(libab* ab) { TRY(libab_register_function(ab, "divide", &atan2_type, function_divide)); TRY(libab_register_function(ab, "print", &print_num_type, function_print_num)); TRY(libab_register_function(ab, "print", &print_unit_type, function_print_unit)); + TRY(libab_register_function(ab, "print", &print_bool_type, function_print_bool)); TRY(libab_register_operator_infix(ab, "+", 0, -1, "plus")); TRY(libab_register_operator_infix(ab, "-", 0, -1, "minus")); TRY(libab_register_operator_infix(ab, "*", 1, -1, "times")); @@ -113,6 +123,7 @@ libab_result register_functions(libab* ab) { libab_ref_free(&difficult_type); libab_ref_free(&print_num_type); libab_ref_free(&print_unit_type); + libab_ref_free(&print_bool_type); return result; } diff --git a/src/libabacus.c b/src/libabacus.c index 114339d..7afa618 100644 --- a/src/libabacus.c +++ b/src/libabacus.c @@ -16,6 +16,8 @@ static libab_basetype _basetype_function = {libab_free_function, static libab_basetype _basetype_unit = { libab_free_unit, NULL, 0 }; +static libab_basetype _basetype_bool = { libab_free_bool, NULL, 0 }; + libab_result _prepare_types(libab* ab, void (*free_function)(void*)); libab_result libab_init(libab* ab, void* (*parse_function)(const char*), @@ -27,6 +29,7 @@ libab_result libab_init(libab* ab, void* (*parse_function)(const char*), libab_result result; libab_ref_null(&null_ref); libab_ref_null(&ab->type_num); + libab_ref_null(&ab->type_bool); libab_ref_null(&ab->type_function_list); libab_ref_null(&ab->type_unit); @@ -35,6 +38,7 @@ libab_result libab_init(libab* ab, void* (*parse_function)(const char*), if (result == LIBAB_SUCCESS) { libab_ref_free(&ab->type_num); + libab_ref_free(&ab->type_bool); libab_ref_free(&ab->type_function_list); libab_ref_free(&ab->type_unit); result = _prepare_types(ab, free_function); @@ -59,6 +63,7 @@ libab_result libab_init(libab* ab, void* (*parse_function)(const char*), if (result != LIBAB_SUCCESS) { libab_ref_free(&ab->table); libab_ref_free(&ab->type_num); + libab_ref_free(&ab->type_bool); libab_ref_free(&ab->type_function_list); libab_ref_free(&ab->type_unit); @@ -282,6 +287,7 @@ libab_result _prepare_types(libab* ab, void (*free_function)(void*)) { ab->basetype_num.free_function = free_function; libab_ref_null(&ab->type_num); + libab_ref_null(&ab->type_bool); libab_ref_null(&ab->type_function_list); libab_ref_null(&ab->type_unit); @@ -291,6 +297,12 @@ libab_result _prepare_types(libab* ab, void (*free_function)(void*)) { libab_instantiate_basetype(&ab->basetype_num, &ab->type_num, 0); } + if (result == LIBAB_SUCCESS) { + libab_ref_free(&ab->type_bool); + result = + libab_instantiate_basetype(&_basetype_bool, &ab->type_bool, 0); + } + if (result == LIBAB_SUCCESS) { libab_ref_free(&ab->type_function_list); result = libab_instantiate_basetype(&_basetype_function_list, @@ -306,6 +318,10 @@ libab_result _prepare_types(libab* ab, void (*free_function)(void*)) { result = libab_register_basetype(ab, "num", &ab->basetype_num); } + if(result == LIBAB_SUCCESS) { + result = libab_register_basetype(ab, "bool", &_basetype_bool); + } + if (result == LIBAB_SUCCESS) { result = libab_register_basetype(ab, "function", &_basetype_function); } @@ -321,9 +337,11 @@ libab_result _prepare_types(libab* ab, void (*free_function)(void*)) { if (result != LIBAB_SUCCESS) { libab_ref_free(&ab->type_num); + libab_ref_free(&ab->type_bool); libab_ref_free(&ab->type_function_list); libab_ref_free(&ab->type_unit); libab_ref_null(&ab->type_num); + libab_ref_null(&ab->type_bool); libab_ref_null(&ab->type_function_list); libab_ref_null(&ab->type_unit); } @@ -350,6 +368,8 @@ libab_result libab_create_type(libab* ab, libab_ref* into, const char* type) { libab_basetype* libab_get_basetype_num(libab* ab) { return &ab->basetype_num; } +libab_basetype* libab_get_basetype_bool(libab* ab) { return &_basetype_bool; } + libab_basetype* libab_get_basetype_function(libab* ab) { return &_basetype_function; } @@ -366,6 +386,10 @@ void libab_get_type_num(libab* ab, libab_ref* into) { libab_ref_copy(&ab->type_num, into); } +void libab_get_type_bool(libab* ab, libab_ref* into) { + libab_ref_copy(&ab->type_bool, into); +} + void libab_get_type_function_list(libab* ab, libab_ref* into) { libab_ref_copy(&ab->type_function_list, into); } @@ -493,6 +517,7 @@ libab_result libab_free(libab* ab) { libab_table_free(libab_ref_get(&ab->table)); libab_ref_free(&ab->table); libab_ref_free(&ab->type_num); + libab_ref_free(&ab->type_bool); libab_ref_free(&ab->type_function_list); libab_ref_free(&ab->type_unit); libab_parser_free(&ab->parser);