3 #include "common/err.h"
19 static long binary(const char *fnname, UwUVMArgs *args, BinaryOP op)
21 uwuutil_require_exact(fnname, args, 2);
23 UwUVMValue value0 = uwuvm_get_arg(args, 0);
25 if (value0.type != &uwuint_type)
26 error("type error: %s requires an integer as $1\n", fnname);
28 UwUVMValue value1 = uwuvm_get_arg(args, 1);
30 if (value1.type != &uwuint_type)
31 error("type error: %s requires an integer as $2\n", fnname);
33 long a = uwuint_get(value0);
34 long b = uwuint_get(value1);
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;
55 static long reduce(const char *fnname, UwUVMArgs *args, ReduceOP op, long result)
59 for (size_t i = 0; i < args->num; i++) {
60 UwUVMValue value = uwuvm_get_arg(args, i);
62 if (value.type != &uwuint_type)
63 error("type error: %s only accepts integers as arguments (invalid argument: $%lu)\n", fnname, i + 1);
65 long this = uwuint_get(value);
68 case ROP_ADD: result += this; break;
69 case ROP_MUL: result *= this; break;
73 else if (this != first)
83 UwUVMValue uwu_add(UwUVMArgs *args)
85 return uwuint_create(reduce("int.add", args, ROP_ADD, 0));
88 UwUVMValue uwu_sub(UwUVMArgs *args)
90 return uwuint_create(binary("int.sub", args, BOP_SUB));
93 UwUVMValue uwu_mul(UwUVMArgs *args)
95 return uwuint_create(reduce("int.mul", args, ROP_MUL, 1));
98 UwUVMValue uwu_div(UwUVMArgs *args)
100 return uwuint_create(binary("int.div", args, BOP_DIV));
103 UwUVMValue uwu_mod(UwUVMArgs *args)
105 return uwuint_create(binary("int.mod", args, BOP_MOD));
108 UwUVMValue uwu_smaller(UwUVMArgs *args)
110 return uwubool_create(binary("int.smaller", args, BOP_SML) == 1);
113 UwUVMValue uwu_greater(UwUVMArgs *args)
115 return uwubool_create(binary("int.greater", args, BOP_GRT) == 1);
118 UwUVMValue uwu_equal(UwUVMArgs *args)
120 uwuutil_require_min("int.equal", args, 2);
121 return uwubool_create(reduce("int.equal", args, ROP_EQU, 1) == 1);
124 UwUVMValue uwu_is(UwUVMArgs *args)
126 return uwuutil_is_type("int.is", args, &uwuint_type);