#include <stdio.h>
#include <stdlib.h>
-#include "../src/err.h"
-#include "../api/vm.h"
-#include "../api/int.h"
-#include "../api/bool.h"
+#include "common/err.h"
+#include "api/vm.h"
+#include "api/int.h"
+#include "api/bool.h"
+#include "api/util.h"
typedef enum
{
BOP_EQU,
} BinaryOP;
-static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
+static long binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
{
- if (args->num != 2)
- error("error: %s requires exactly 2 arguments\n", fnname);
+ uwuutil_require_exact(fnname, args, 2);
UwUVMValue value0 = uwuvm_get_arg(args, 0);
if (value0.type != &uwuint_type)
- error("error: %s requires an integer as $0\n", fnname);
+ error("type error: %s requires an integer as $0\n", fnname);
UwUVMValue value1 = uwuvm_get_arg(args, 1);
if (value1.type != &uwuint_type)
- error("error: %s requires an integer as $1\n", fnname);
+ error("type error: %s requires an integer as $1\n", fnname);
- int a = *(int *) value0.data;
- int b = *(int *) value1.data;
+ long a = uwuint_get(value0);
+ long b = uwuint_get(value1);
switch (op) {
case BOP_SUB: return a - b;
case BOP_GRT: return a > b;
case BOP_EQU: return a == b;
}
+
+ return 0;
}
typedef enum
ROP_EQU,
} ReduceOP;
-static int reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, int result)
+static long reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, long result)
{
- int first;
+ long first;
for (size_t i = 0; i < args->num; i++) {
UwUVMValue value = uwuvm_get_arg(args, i);
if (value.type != &uwuint_type)
- error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
+ error("type error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
- int this = *(int *) value.data;
+ long this = uwuint_get(value);
switch (op) {
case ROP_ADD: result += this; break;
UwUVMValue uwu_equal(UwUVMArgs *args)
{
- if (args->num < 2)
- error("error: :int:equal requires at least 2 arguments\n");
-
+ uwuutil_require_min(":int:equal", args, 2);
return uwubool_create(reduce(":int:equal", args, ROP_EQU, 1) == 1);
}
UwUVMValue uwu_is(UwUVMArgs *args)
{
- if (args->num < 1)
- 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 != &uwuint_type)
- return uwubool_create(false);
-
- return uwubool_create(true);
+ return uwuutil_is_type(":int:is", args, &uwuint_type);
}