From 058d954e80f83c26deb209008f11d87a5b59418e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 30 Dec 2021 16:02:10 +0100 Subject: [PATCH] Unify value types --- api/bool.c | 23 ++++++++--------------- api/bool.h | 2 +- api/int.c | 31 ++++++++++++++++++++++++++----- api/int.h | 2 ++ api/nil.c | 11 +++-------- api/nil.h | 2 +- api/ref.c | 31 +++++++++++++++++++++++++++++++ api/ref.h | 10 ++++++++++ api/str.c | 36 ++++++++++++++++++------------------ api/str.h | 2 ++ api/vm.c | 31 +++++++------------------------ api/vm.h | 32 +++++++------------------------- std/bool.c | 7 +++---- std/int.c | 14 +++++++------- 14 files changed, 126 insertions(+), 108 deletions(-) create mode 100644 api/ref.c create mode 100644 api/ref.h diff --git a/api/bool.c b/api/bool.c index 2857f0b..4cbc3f3 100644 --- a/api/bool.c +++ b/api/bool.c @@ -7,27 +7,20 @@ UwUVMValue uwubool_create(bool value) { UwUVMValue vm_value = { - .type = VT_NAT, - .value = { - .nat_value = { - .type = &uwubool_type, - .data = malloc(sizeof(bool)) - }, - }, + .type = &uwubool_type, + .data = malloc(sizeof(bool)), }; - *(bool *) vm_value.value.nat_value.data = value; + *(bool *) vm_value.data = value; return vm_value; } bool uwubool_get(UwUVMValue vm_value) { - if (vm_value.type != VT_NAT) - return true; - else if (vm_value.value.nat_value.type == &uwunil_type) + if (vm_value.type == &uwunil_type) return false; - else if (vm_value.value.nat_value.type == &uwubool_type) - return *(bool *) vm_value.value.nat_value.data; + else if (vm_value.type == &uwubool_type) + return *(bool *) vm_value.data; else return true; } @@ -36,7 +29,7 @@ static void *uwubool_copy(void *data) { bool *copy = malloc(sizeof(*copy)); *copy = *(bool *) data; - return copy; + return copy; } static char *uwubool_print(void *data) @@ -44,7 +37,7 @@ static char *uwubool_print(void *data) return strdup(((bool *) data) ? "true" : "false"); } -UwUVMNativeType uwubool_type = { +UwUVMType uwubool_type = { .copy = &uwubool_copy, .delete = &free, .print = &uwubool_print, diff --git a/api/bool.h b/api/bool.h index 2299177..70dfd60 100644 --- a/api/bool.h +++ b/api/bool.h @@ -4,7 +4,7 @@ #include #include "vm.h" -extern UwUVMNativeType uwubool_type; +extern UwUVMType uwubool_type; UwUVMValue uwubool_create(bool value); bool uwubool_get(UwUVMValue vm_value); diff --git a/api/int.c b/api/int.c index 49463cf..0b9329d 100644 --- a/api/int.c +++ b/api/int.c @@ -1,11 +1,32 @@ +#include +#include "../src/util.h" #include "int.h" UwUVMValue uwuint_create(int value) { - return (UwUVMValue) { - .type = VT_INT, - .value = { - .int_value = value, - }, + UwUVMValue vm_value = { + .type = &uwuint_type, + .data = malloc(sizeof(int)) }; + *(int *) vm_value.data = value; + + return vm_value; +} + +void *uwuint_copy(void *data) +{ + int *copy = malloc(sizeof(*copy)); + *copy = *(int *) data; + return copy; } + +char *uwuint_print(void *data) +{ + return asprintf_wrapper("%d", *(int *) data); +} + +UwUVMType uwuint_type = { + .copy = &uwuint_copy, + .delete = &free, + .print = &uwuint_print, +}; diff --git a/api/int.h b/api/int.h index fd284c7..e9c5798 100644 --- a/api/int.h +++ b/api/int.h @@ -3,6 +3,8 @@ #include "vm.h" +extern UwUVMType uwuint_type; + UwUVMValue uwuint_create(int value); #endif diff --git a/api/nil.c b/api/nil.c index bbd1eb8..b6304e0 100644 --- a/api/nil.c +++ b/api/nil.c @@ -4,13 +4,8 @@ UwUVMValue uwunil_create() { return (UwUVMValue) { - .type = VT_NAT, - .value = { - .nat_value = { - .type = &uwunil_type, - .data = NULL, - } - } + .type = &uwunil_type, + .data = NULL, }; } @@ -30,7 +25,7 @@ static char *uwunil_print(void *data) return strdup(""); } -UwUVMNativeType uwunil_type = { +UwUVMType uwunil_type = { .copy = &uwunil_copy, .delete = &uwunil_delete, .print = &uwunil_print, diff --git a/api/nil.h b/api/nil.h index 22df640..014be45 100644 --- a/api/nil.h +++ b/api/nil.h @@ -3,7 +3,7 @@ #include "vm.h" -extern UwUVMNativeType uwunil_type; +extern UwUVMType uwunil_type; UwUVMValue uwunil_create(); diff --git a/api/ref.c b/api/ref.c new file mode 100644 index 0000000..f66ae19 --- /dev/null +++ b/api/ref.c @@ -0,0 +1,31 @@ +#include "../src/util.h" +#include "ref.h" + +UwUVMValue uwuref_create(UwUVMFunction *function) +{ + return (UwUVMValue) { + .type = &uwuref_type, + .data = function, + }; +} + +static void *uwuref_copy(void *data) +{ + return data; +} + +static void uwuref_delete(void *data) +{ + (void) data; +} + +static char *uwuref_print(void *data) +{ + return asprintf_wrapper("[Function reference: %p]", data); +} + +UwUVMType uwuref_type = { + .copy = &uwuref_copy, + .delete = &uwuref_delete, + .print = &uwuref_print, +}; diff --git a/api/ref.h b/api/ref.h new file mode 100644 index 0000000..6a2fead --- /dev/null +++ b/api/ref.h @@ -0,0 +1,10 @@ +#ifndef _API_REF_H_ +#define _API_REF_H_ + +#include "vm.h" + +extern UwUVMType uwuref_type; + +UwUVMValue uwuref_create(UwUVMFunction *function); + +#endif diff --git a/api/str.c b/api/str.c index 37b8e70..84d2b10 100644 --- a/api/str.c +++ b/api/str.c @@ -1,32 +1,32 @@ #include -#include "../src/util.h" +#include #include "str.h" UwUVMValue uwustr_create(const char *value) { return (UwUVMValue) { - .type = VT_STR, - .value = { - .str_value = strdup(value), - }, + .type = &uwustr_type, + .data = strdup(value), }; } char *uwustr_get(UwUVMValue vm_value) { - switch (vm_value.type) { - case VT_INT: - return asprintf_wrapper("%d", vm_value.value.int_value); - - case VT_STR: - return strdup(vm_value.value.str_value); + vm_value.type->print(vm_value.data); +} - case VT_REF: - return asprintf_wrapper("[Function reference: %p]", vm_value.value.ref_value); +static void *uwustr_copy(void *data) +{ + return strdup(data); +} - case VT_NAT: - return vm_value.value.nat_value.type->print - ? vm_value.value.nat_value.type->print(vm_value.value.nat_value.data) - : asprintf_wrapper("[Native value: %p: %p]", vm_value.value.nat_value.data, vm_value.value.nat_value.type); - } +static char *uwustr_print(void *data) +{ + return strdup(data); } + +UwUVMType uwustr_type = { + .copy = &uwustr_copy, + .delete = &free, + .print = &uwustr_print, +}; diff --git a/api/str.h b/api/str.h index b035f2a..609328e 100644 --- a/api/str.h +++ b/api/str.h @@ -3,6 +3,8 @@ #include "vm.h" +extern UwUVMType uwustr_type; + UwUVMValue uwustr_create(const char *value); char *uwustr_get(UwUVMValue vm_value); diff --git a/api/vm.c b/api/vm.c index c33c32e..73ec87e 100644 --- a/api/vm.c +++ b/api/vm.c @@ -3,14 +3,12 @@ #include "../src/err.h" #include "vm.h" #include "str.h" +#include "ref.h" #include "int.h" void uwuvm_free_value(UwUVMValue value) { - if (value.type == VT_STR) - free(value.value.str_value); - else if (value.type == VT_NAT) - value.value.nat_value.type->delete(value.value.nat_value.data); + value.type->delete(value.data); } void uwuvm_free_args(UwUVMArgs *args) @@ -31,20 +29,10 @@ void uwuvm_free_args(UwUVMArgs *args) UwUVMValue uwuvm_copy_value(UwUVMValue value) { - if (value.type == VT_STR) - return uwustr_create(value.value.str_value); - else if (value.type == VT_NAT) - return (UwUVMValue) { - .type = value.type, - .value = { - .nat_value = { - .type = value.value.nat_value.type, - .data = value.value.nat_value.type->copy(value.value.nat_value.data), - } - } - }; - else - return value; + return (UwUVMValue) { + .type = value.type, + .data = value.type->copy(value.data), + }; } UwUVMValue uwuvm_get_arg(UwUVMArgs *args, size_t i) @@ -73,12 +61,7 @@ UwUVMValue uwuvm_evaluate_expression(UwUVMExpression *expression, UwUVMArgs *arg return uwuvm_copy_value(uwuvm_get_arg(args, expression->value.int_value)); case EX_FNNAME: - return (UwUVMValue) { - .type = VT_REF, - .value = { - .ref_value = expression->value.ref_value, - }, - }; + return uwuref_create(expression->value.ref_value); case EX_FNCALL: return uwuvm_run_function(expression->value.cll_value.function, (UwUVMArgs) { diff --git a/api/vm.h b/api/vm.h index 94103d5..7286f63 100644 --- a/api/vm.h +++ b/api/vm.h @@ -16,23 +16,23 @@ typedef struct void *(*copy )(void *data); void (*delete)(void *data); char *(*print )(void *data); -} UwUVMNativeType; +} UwUVMType; typedef struct { void *data; - UwUVMNativeType *type; -} UwUVMNativeValue; + UwUVMType *type; +} UwUVMValue; typedef struct UwUVMArgs { size_t num; - struct UwUVMValue **evaluated; + UwUVMValue **evaluated; struct UwUVMExpression *unevaluated; struct UwUVMArgs *super; } UwUVMArgs; -typedef struct UwUVMValue (*UwUVMNativeFunction)(UwUVMArgs *args); +typedef UwUVMValue (*UwUVMNativeFunction)(UwUVMArgs *args); typedef struct { @@ -44,24 +44,6 @@ typedef struct } value; } UwUVMFunction; -typedef struct UwUVMValue -{ - enum - { - VT_INT, - VT_STR, - VT_REF, - VT_NAT, - } type; - union - { - int int_value; - char *str_value; - UwUVMFunction *ref_value; - UwUVMNativeValue nat_value; - } value; -} UwUVMValue; - typedef struct UwUVMExpression { ExpressionType type; @@ -83,8 +65,8 @@ typedef struct { void *api_library; UwUVMFunction *main_function; - UwUVMFunction **functions; - size_t num_functions; + UwUVMFunction **functions; + size_t num_functions; void **libraries; size_t num_libraries; } UwUVMProgram; diff --git a/std/bool.c b/std/bool.c index 76772bf..02aa887 100644 --- a/std/bool.c +++ b/std/bool.c @@ -87,10 +87,9 @@ UwUVMValue uwu_is(UwUVMArgs *args) if (args->num < 1) error("error: :bool:is requires at least 1 argument\n"); - for (size_t i = 0; i < args->num; i++) { - UwUVMValue value = uwuvm_get_arg(args, i); - return uwubool_create(value.type != VT_NAT || value.value.nat_value.type != &uwubool_type); - } + for (size_t i = 0; i < args->num; i++) + if (uwuvm_get_arg(args, i).type != &uwubool_type) + return uwubool_create(false); return uwubool_create(true); } diff --git a/std/int.c b/std/int.c index dfc436c..c6c8ab7 100644 --- a/std/int.c +++ b/std/int.c @@ -22,16 +22,16 @@ static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op) UwUVMValue value0 = uwuvm_get_arg(args, 0); - if (value0.type != VT_INT) + if (value0.type != &uwuint_type) error("error: %s requires an integer as $0\n", fnname); UwUVMValue value1 = uwuvm_get_arg(args, 1); - if (value1.type != VT_INT) + if (value1.type != &uwuint_type) error("error: %s requires an integer as $1\n", fnname); - int a = value0.value.int_value; - int b = value1.value.int_value; + int a = *(int *) value0.data; + int b = *(int *) value1.data; switch (op) { case BOP_SUB: return a - b; @@ -57,10 +57,10 @@ static int reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, int result) for (size_t i = 0; i < args->num; i++) { UwUVMValue value = uwuvm_get_arg(args, i); - if (value.type != VT_INT) + if (value.type != &uwuint_type) error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i); - int this = value.value.int_value; + int this = *(int *) value.data; switch (op) { case ROP_ADD: result += this; break; @@ -127,7 +127,7 @@ UwUVMValue uwu_is(UwUVMArgs *args) error("error: :int:is requires at least 1 argument\n"); for (size_t i = 0; i < args->num; i++) - if (uwuvm_get_arg(args, i).type != VT_INT) + if (uwuvm_get_arg(args, i).type != &uwuint_type) return uwubool_create(false); return uwubool_create(true); -- 2.44.0