aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/bool.c23
-rw-r--r--api/bool.h2
-rw-r--r--api/int.c31
-rw-r--r--api/int.h2
-rw-r--r--api/nil.c11
-rw-r--r--api/nil.h2
-rw-r--r--api/ref.c31
-rw-r--r--api/ref.h10
-rw-r--r--api/str.c36
-rw-r--r--api/str.h2
-rw-r--r--api/vm.c31
-rw-r--r--api/vm.h32
-rw-r--r--std/bool.c7
-rw-r--r--std/int.c14
14 files changed, 126 insertions, 108 deletions
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 <stdbool.h>
#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 <stdlib.h>
+#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 <string.h>
-#include "../src/util.h"
+#include <stdlib.h>
#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);