3 #include "../src/err.h"
5 #include "../api/int.h"
6 #include "../api/bool.h"
18 static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
21 error("error: %s requires exactly 2 arguments\n", fnname);
23 UwUVMValue value0 = uwuvm_get_arg(args, 0);
25 if (value0.type != &uwuint_type)
26 error("error: %s requires an integer as $0\n", fnname);
28 UwUVMValue value1 = uwuvm_get_arg(args, 1);
30 if (value1.type != &uwuint_type)
31 error("error: %s requires an integer as $1\n", fnname);
33 int a = *(int *) value0.data;
34 int b = *(int *) value1.data;
37 case BOP_SUB: return a - b;
38 case BOP_DIV: return a / b;
39 case BOP_MOD: return a % b;
40 case BOP_SML: return a < b;
41 case BOP_GRT: return a > b;
42 case BOP_EQU: return a == b;
53 static int reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, int result)
57 for (size_t i = 0; i < args->num; i++) {
58 UwUVMValue value = uwuvm_get_arg(args, i);
60 if (value.type != &uwuint_type)
61 error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
63 int this = *(int *) value.data;
66 case ROP_ADD: result += this; break;
67 case ROP_MUL: result *= this; break;
71 else if (this != first)
81 UwUVMValue uwu_add(UwUVMArgs *args)
83 return uwuint_create(reduce(":int:add", args, ROP_ADD, 0));
86 UwUVMValue uwu_sub(UwUVMArgs *args)
88 return uwuint_create(binary(":int:sub", args, BOP_SUB));
91 UwUVMValue uwu_mul(UwUVMArgs *args)
93 return uwuint_create(reduce(":int:mul", args, ROP_MUL, 1));
96 UwUVMValue uwu_div(UwUVMArgs *args)
98 return uwuint_create(binary(":int:div", args, BOP_DIV));
101 UwUVMValue uwu_mod(UwUVMArgs *args)
103 return uwuint_create(binary(":int:mod", args, BOP_MOD));
106 UwUVMValue uwu_smaller(UwUVMArgs *args)
108 return uwubool_create(binary(":int:smaller", args, BOP_SML) == 1);
111 UwUVMValue uwu_greater(UwUVMArgs *args)
113 return uwubool_create(binary(":int:greater", args, BOP_GRT) == 1);
116 UwUVMValue uwu_equal(UwUVMArgs *args)
119 error("error: :int:equal requires at least 2 arguments\n");
121 return uwubool_create(reduce(":int:equal", args, ROP_EQU, 1) == 1);
124 UwUVMValue uwu_is(UwUVMArgs *args)
127 error("error: :int:is requires at least 1 argument\n");
129 for (size_t i = 0; i < args->num; i++)
130 if (uwuvm_get_arg(args, i).type != &uwuint_type)
131 return uwubool_create(false);
133 return uwubool_create(true);