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;
}
{
bool *copy = malloc(sizeof(*copy));
*copy = *(bool *) data;
- return copy;
+ return copy;
}
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,
#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);
+#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,
+};
#include "vm.h"
+extern UwUVMType uwuint_type;
+
UwUVMValue uwuint_create(int value);
#endif
UwUVMValue uwunil_create()
{
return (UwUVMValue) {
- .type = VT_NAT,
- .value = {
- .nat_value = {
- .type = &uwunil_type,
- .data = NULL,
- }
- }
+ .type = &uwunil_type,
+ .data = NULL,
};
}
return strdup("");
}
-UwUVMNativeType uwunil_type = {
+UwUVMType uwunil_type = {
.copy = &uwunil_copy,
.delete = &uwunil_delete,
.print = &uwunil_print,
#include "vm.h"
-extern UwUVMNativeType uwunil_type;
+extern UwUVMType uwunil_type;
UwUVMValue uwunil_create();
--- /dev/null
+#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,
+};
--- /dev/null
+#ifndef _API_REF_H_
+#define _API_REF_H_
+
+#include "vm.h"
+
+extern UwUVMType uwuref_type;
+
+UwUVMValue uwuref_create(UwUVMFunction *function);
+
+#endif
#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,
+};
#include "vm.h"
+extern UwUVMType uwustr_type;
+
UwUVMValue uwustr_create(const char *value);
char *uwustr_get(UwUVMValue vm_value);
#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)
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)
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) {
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
{
} 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;
{
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;
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);
}
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;
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;
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);