3 #include "../src/err.h"
5 #include "../api/int.h"
6 #include "../api/bool.h"
7 #include "../api/util.h"
19 static int binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
22 error("error: %s requires exactly 2 arguments\n", fnname);
24 UwUVMValue value0 = uwuvm_get_arg(args, 0);
26 if (value0.type != &uwuint_type)
27 error("error: %s requires an integer as $0\n", fnname);
29 UwUVMValue value1 = uwuvm_get_arg(args, 1);
31 if (value1.type != &uwuint_type)
32 error("error: %s requires an integer as $1\n", fnname);
34 int a = uwuint_get(value0);
35 int b = uwuint_get(value1);
38 case BOP_SUB: return a - b;
39 case BOP_DIV: return a / b;
40 case BOP_MOD: return a % b;
41 case BOP_SML: return a < b;
42 case BOP_GRT: return a > b;
43 case BOP_EQU: return a == b;
54 static int reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, int result)
58 for (size_t i = 0; i < args->num; i++) {
59 UwUVMValue value = uwuvm_get_arg(args, i);
61 if (value.type != &uwuint_type)
62 error("error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i);
64 int this = uwuint_get(value);
67 case ROP_ADD: result += this; break;
68 case ROP_MUL: result *= this; break;
72 else if (this != first)
82 UwUVMValue uwu_add(UwUVMArgs *args)
84 return uwuint_create(reduce(":int:add", args, ROP_ADD, 0));
87 UwUVMValue uwu_sub(UwUVMArgs *args)
89 return uwuint_create(binary(":int:sub", args, BOP_SUB));
92 UwUVMValue uwu_mul(UwUVMArgs *args)
94 return uwuint_create(reduce(":int:mul", args, ROP_MUL, 1));
97 UwUVMValue uwu_div(UwUVMArgs *args)
99 return uwuint_create(binary(":int:div", args, BOP_DIV));
102 UwUVMValue uwu_mod(UwUVMArgs *args)
104 return uwuint_create(binary(":int:mod", args, BOP_MOD));
107 UwUVMValue uwu_smaller(UwUVMArgs *args)
109 return uwubool_create(binary(":int:smaller", args, BOP_SML) == 1);
112 UwUVMValue uwu_greater(UwUVMArgs *args)
114 return uwubool_create(binary(":int:greater", args, BOP_GRT) == 1);
117 UwUVMValue uwu_equal(UwUVMArgs *args)
120 error("error: :int:equal requires at least 2 arguments\n");
122 return uwubool_create(reduce(":int:equal", args, ROP_EQU, 1) == 1);
125 UwUVMValue uwu_is(UwUVMArgs *args)
127 return uwuutil_is_type(":int:is", args, &uwuint_type);