Fixed the code style in *.c files to two spaces indentation and add a linter named funstx to Fun. (0.39.0)
This commit is contained in:
parent
33001a7ad2
commit
03b2532474
237 changed files with 17550 additions and 13911 deletions
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file abs.c
|
||||
* @file abs.c
|
||||
* @brief Implements the OP_ABS opcode for absolute value in the VM.
|
||||
*
|
||||
* This file handles the OP_ABS instruction, which computes the absolute value
|
||||
|
|
@ -26,11 +26,14 @@
|
|||
*/
|
||||
|
||||
case OP_ABS: {
|
||||
Value x = pop_value(vm);
|
||||
if (x.type != VAL_INT) { fprintf(stderr, "ABS expects int\n"); exit(1); }
|
||||
int64_t v = x.i;
|
||||
if (v < 0) v = -v;
|
||||
push_value(vm, make_int(v));
|
||||
free_value(x);
|
||||
break;
|
||||
Value x = pop_value(vm);
|
||||
if (x.type != VAL_INT) {
|
||||
fprintf(stderr, "ABS expects int\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t v = x.i;
|
||||
if (v < 0) v = -v;
|
||||
push_value(vm, make_int(v));
|
||||
free_value(x);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,34 +10,34 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ceil.c
|
||||
* @file ceil.c
|
||||
* @brief Implements the OP_CEIL opcode using C99 math.h ceil().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_CEIL: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
/* ceil(n) == n for integers */
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = ceil(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
/* ceil(n) == n for integers */
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = ceil(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: CEIL expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: CEIL expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file clamp.c
|
||||
* @file clamp.c
|
||||
* @brief Implements the OP_CLAMP opcode for value clamping in the VM.
|
||||
*
|
||||
* This file handles the OP_CLAMP instruction, which clamps a value between
|
||||
|
|
@ -27,19 +27,19 @@
|
|||
*/
|
||||
|
||||
case OP_CLAMP: {
|
||||
Value hi = pop_value(vm);
|
||||
Value lo = pop_value(vm);
|
||||
Value x = pop_value(vm);
|
||||
if (x.type != VAL_INT || lo.type != VAL_INT || hi.type != VAL_INT) {
|
||||
fprintf(stderr, "CLAMP expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t v = x.i;
|
||||
if (v < lo.i) v = lo.i;
|
||||
if (v > hi.i) v = hi.i;
|
||||
push_value(vm, make_int(v));
|
||||
free_value(x);
|
||||
free_value(lo);
|
||||
free_value(hi);
|
||||
break;
|
||||
Value hi = pop_value(vm);
|
||||
Value lo = pop_value(vm);
|
||||
Value x = pop_value(vm);
|
||||
if (x.type != VAL_INT || lo.type != VAL_INT || hi.type != VAL_INT) {
|
||||
fprintf(stderr, "CLAMP expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t v = x.i;
|
||||
if (v < lo.i) v = lo.i;
|
||||
if (v > hi.i) v = hi.i;
|
||||
push_value(vm, make_int(v));
|
||||
free_value(x);
|
||||
free_value(lo);
|
||||
free_value(hi);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file cos.c
|
||||
* @file cos.c
|
||||
* @brief Implements the OP_COS opcode using C99 math.h cos().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_COS: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = cos(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: COS expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = cos(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: COS expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file exp.c
|
||||
* @file exp.c
|
||||
* @brief Implements the OP_EXP opcode using C99 math.h exp().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_EXP: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = exp(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: EXP expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = exp(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: EXP expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,34 +10,34 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file floor.c
|
||||
* @file floor.c
|
||||
* @brief Implements the OP_FLOOR opcode using C99 math.h floor().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_FLOOR: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
/* floor(n) == n for integers */
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = floor(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
/* floor(n) == n for integers */
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = floor(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: FLOOR expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: FLOOR expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file fmax.c
|
||||
* @file fmax.c
|
||||
* @brief Implements the OP_FMAX opcode using C99 math.h fmax().
|
||||
* Accepts int or float; follows IEEE-754 NaN handling per fmax.
|
||||
*/
|
||||
|
|
@ -18,24 +18,28 @@
|
|||
#include <math.h>
|
||||
|
||||
case OP_FMAX: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (!((a.type == VAL_INT || a.type == VAL_FLOAT) && (b.type == VAL_INT || b.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: FMAX expects numbers, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
double da = (a.type == VAL_FLOAT) ? a.d : (double)a.i;
|
||||
double db = (b.type == VAL_FLOAT) ? b.d : (double)b.i;
|
||||
double r = fmax(da, db);
|
||||
Value out;
|
||||
if (!isnan(r) && !isinf(r) && r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) out = make_int(ii); else out = make_float(r);
|
||||
} else {
|
||||
out = make_float(r);
|
||||
}
|
||||
free_value(a); free_value(b);
|
||||
push_value(vm, out);
|
||||
break;
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (!((a.type == VAL_INT || a.type == VAL_FLOAT) && (b.type == VAL_INT || b.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: FMAX expects numbers, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
double da = (a.type == VAL_FLOAT) ? a.d : (double)a.i;
|
||||
double db = (b.type == VAL_FLOAT) ? b.d : (double)b.i;
|
||||
double r = fmax(da, db);
|
||||
Value out;
|
||||
if (!isnan(r) && !isinf(r) && r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r)
|
||||
out = make_int(ii);
|
||||
else
|
||||
out = make_float(r);
|
||||
} else {
|
||||
out = make_float(r);
|
||||
}
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
push_value(vm, out);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file fmin.c
|
||||
* @file fmin.c
|
||||
* @brief Implements the OP_FMIN opcode using C99 math.h fmin().
|
||||
* Accepts int or float; follows IEEE-754 NaN handling per fmin.
|
||||
*/
|
||||
|
|
@ -18,24 +18,28 @@
|
|||
#include <math.h>
|
||||
|
||||
case OP_FMIN: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (!((a.type == VAL_INT || a.type == VAL_FLOAT) && (b.type == VAL_INT || b.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: FMIN expects numbers, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
double da = (a.type == VAL_FLOAT) ? a.d : (double)a.i;
|
||||
double db = (b.type == VAL_FLOAT) ? b.d : (double)b.i;
|
||||
double r = fmin(da, db);
|
||||
Value out;
|
||||
if (!isnan(r) && !isinf(r) && r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) out = make_int(ii); else out = make_float(r);
|
||||
} else {
|
||||
out = make_float(r);
|
||||
}
|
||||
free_value(a); free_value(b);
|
||||
push_value(vm, out);
|
||||
break;
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (!((a.type == VAL_INT || a.type == VAL_FLOAT) && (b.type == VAL_INT || b.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: FMIN expects numbers, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
double da = (a.type == VAL_FLOAT) ? a.d : (double)a.i;
|
||||
double db = (b.type == VAL_FLOAT) ? b.d : (double)b.i;
|
||||
double r = fmin(da, db);
|
||||
Value out;
|
||||
if (!isnan(r) && !isinf(r) && r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r)
|
||||
out = make_int(ii);
|
||||
else
|
||||
out = make_float(r);
|
||||
} else {
|
||||
out = make_float(r);
|
||||
}
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
push_value(vm, out);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,31 +10,37 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file gcd.c
|
||||
* @file gcd.c
|
||||
* @brief Implements the OP_GCD opcode for greatest common divisor.
|
||||
*/
|
||||
|
||||
case OP_GCD: {
|
||||
Value vb = pop_value(vm);
|
||||
Value va = pop_value(vm);
|
||||
if (!((va.type == VAL_INT) || (va.type == VAL_FLOAT)) ||
|
||||
!((vb.type == VAL_INT) || (vb.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: GCD expects numbers, got %s and %s\n",
|
||||
value_type_name(va.type), value_type_name(vb.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (va.type == VAL_INT) ? va.i : (int64_t)va.d;
|
||||
int64_t b = (vb.type == VAL_INT) ? vb.i : (int64_t)vb.d;
|
||||
if (a == INT64_MIN) a = (int64_t)INT64_MAX; else if (a < 0) a = -a;
|
||||
if (b == INT64_MIN) b = (int64_t)INT64_MAX; else if (b < 0) b = -b;
|
||||
while (b != 0) {
|
||||
int64_t t = a % b;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
Value res = make_int(a);
|
||||
free_value(va);
|
||||
free_value(vb);
|
||||
push_value(vm, res);
|
||||
break;
|
||||
Value vb = pop_value(vm);
|
||||
Value va = pop_value(vm);
|
||||
if (!((va.type == VAL_INT) || (va.type == VAL_FLOAT)) ||
|
||||
!((vb.type == VAL_INT) || (vb.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: GCD expects numbers, got %s and %s\n",
|
||||
value_type_name(va.type), value_type_name(vb.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (va.type == VAL_INT) ? va.i : (int64_t)va.d;
|
||||
int64_t b = (vb.type == VAL_INT) ? vb.i : (int64_t)vb.d;
|
||||
if (a == INT64_MIN)
|
||||
a = (int64_t)INT64_MAX;
|
||||
else if (a < 0)
|
||||
a = -a;
|
||||
if (b == INT64_MIN)
|
||||
b = (int64_t)INT64_MAX;
|
||||
else if (b < 0)
|
||||
b = -b;
|
||||
while (b != 0) {
|
||||
int64_t t = a % b;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
Value res = make_int(a);
|
||||
free_value(va);
|
||||
free_value(vb);
|
||||
push_value(vm, res);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,38 +10,39 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file isqrt.c
|
||||
* @file isqrt.c
|
||||
* @brief Implements the OP_ISQRT opcode for integer square root (floor).
|
||||
*/
|
||||
|
||||
case OP_ISQRT: {
|
||||
Value v = pop_value(vm);
|
||||
if (!((v.type == VAL_INT) || (v.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: ISQRT expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (v.type == VAL_INT) ? v.i : (int64_t)v.d;
|
||||
if (a <= 0) {
|
||||
free_value(v);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
/* Binary isqrt inline */
|
||||
uint64_t n = (uint64_t)a;
|
||||
uint64_t x = 0;
|
||||
uint64_t bit = (uint64_t)1 << 62; /* highest even bit set */
|
||||
while (bit > n) bit >>= 2;
|
||||
while (bit != 0) {
|
||||
if (n >= x + bit) {
|
||||
n -= x + bit;
|
||||
x = (x >> 1) + bit;
|
||||
} else {
|
||||
x >>= 1;
|
||||
}
|
||||
bit >>= 2;
|
||||
}
|
||||
int64_t r = (int64_t)x;
|
||||
Value v = pop_value(vm);
|
||||
if (!((v.type == VAL_INT) || (v.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: ISQRT expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (v.type == VAL_INT) ? v.i : (int64_t)v.d;
|
||||
if (a <= 0) {
|
||||
free_value(v);
|
||||
push_value(vm, make_int(r));
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
/* Binary isqrt inline */
|
||||
uint64_t n = (uint64_t)a;
|
||||
uint64_t x = 0;
|
||||
uint64_t bit = (uint64_t)1 << 62; /* highest even bit set */
|
||||
while (bit > n)
|
||||
bit >>= 2;
|
||||
while (bit != 0) {
|
||||
if (n >= x + bit) {
|
||||
n -= x + bit;
|
||||
x = (x >> 1) + bit;
|
||||
} else {
|
||||
x >>= 1;
|
||||
}
|
||||
bit >>= 2;
|
||||
}
|
||||
int64_t r = (int64_t)x;
|
||||
free_value(v);
|
||||
push_value(vm, make_int(r));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,39 +10,48 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file lcm.c
|
||||
* @file lcm.c
|
||||
* @brief Implements the OP_LCM opcode for least common multiple.
|
||||
*/
|
||||
|
||||
case OP_LCM: {
|
||||
Value vb = pop_value(vm);
|
||||
Value va = pop_value(vm);
|
||||
if (!((va.type == VAL_INT) || (va.type == VAL_FLOAT)) ||
|
||||
!((vb.type == VAL_INT) || (vb.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: LCM expects numbers, got %s and %s\n",
|
||||
value_type_name(va.type), value_type_name(vb.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (va.type == VAL_INT) ? va.i : (int64_t)va.d;
|
||||
int64_t b = (vb.type == VAL_INT) ? vb.i : (int64_t)vb.d;
|
||||
if (a == INT64_MIN) a = (int64_t)INT64_MAX; else if (a < 0) a = -a;
|
||||
if (b == INT64_MIN) b = (int64_t)INT64_MAX; else if (b < 0) b = -b;
|
||||
if (a == 0 || b == 0) {
|
||||
free_value(va); free_value(vb);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
/* gcd(a,b) */
|
||||
int64_t x = a, y = b;
|
||||
while (y != 0) {
|
||||
int64_t t = x % y; x = y; y = t;
|
||||
}
|
||||
int64_t g = x;
|
||||
/* lcm = (a/g)*b (attempt to reduce overflow) */
|
||||
int64_t l = (a / g) * b;
|
||||
Value res = make_int(l);
|
||||
Value vb = pop_value(vm);
|
||||
Value va = pop_value(vm);
|
||||
if (!((va.type == VAL_INT) || (va.type == VAL_FLOAT)) ||
|
||||
!((vb.type == VAL_INT) || (vb.type == VAL_FLOAT))) {
|
||||
fprintf(stderr, "Runtime type error: LCM expects numbers, got %s and %s\n",
|
||||
value_type_name(va.type), value_type_name(vb.type));
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = (va.type == VAL_INT) ? va.i : (int64_t)va.d;
|
||||
int64_t b = (vb.type == VAL_INT) ? vb.i : (int64_t)vb.d;
|
||||
if (a == INT64_MIN)
|
||||
a = (int64_t)INT64_MAX;
|
||||
else if (a < 0)
|
||||
a = -a;
|
||||
if (b == INT64_MIN)
|
||||
b = (int64_t)INT64_MAX;
|
||||
else if (b < 0)
|
||||
b = -b;
|
||||
if (a == 0 || b == 0) {
|
||||
free_value(va);
|
||||
free_value(vb);
|
||||
push_value(vm, res);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
/* gcd(a,b) */
|
||||
int64_t x = a, y = b;
|
||||
while (y != 0) {
|
||||
int64_t t = x % y;
|
||||
x = y;
|
||||
y = t;
|
||||
}
|
||||
int64_t g = x;
|
||||
/* lcm = (a/g)*b (attempt to reduce overflow) */
|
||||
int64_t l = (a / g) * b;
|
||||
Value res = make_int(l);
|
||||
free_value(va);
|
||||
free_value(vb);
|
||||
push_value(vm, res);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,27 +10,27 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file log.c
|
||||
* @file log.c
|
||||
* @brief Implements the OP_LOG opcode using C99 math.h log() (natural logarithm).
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_LOG: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x <= 0.0) {
|
||||
/* Domain error: return NaN to signal invalid input */
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
double r = log(x);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x <= 0.0) {
|
||||
/* Domain error: return NaN to signal invalid input */
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: LOG expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
double r = log(x);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: LOG expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,26 +10,26 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file log10.c
|
||||
* @file log10.c
|
||||
* @brief Implements the OP_LOG10 opcode using C99 math.h log10().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_LOG10: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x <= 0.0) {
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
double r = log10(x);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x <= 0.0) {
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: LOG10 expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
double r = log10(x);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: LOG10 expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file max.c
|
||||
* @file max.c
|
||||
* @brief Implements the OP_MAX opcode for finding the maximum of two values in the VM.
|
||||
*
|
||||
* This file handles the OP_MAX instruction, which finds the maximum of two integer values.
|
||||
|
|
@ -32,10 +32,14 @@
|
|||
*/
|
||||
|
||||
case OP_MAX: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) { fprintf(stderr, "MAX expects ints\n"); exit(1); }
|
||||
push_value(vm, make_int(a.i > b.i ? a.i : b.i));
|
||||
free_value(a); free_value(b);
|
||||
break;
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) {
|
||||
fprintf(stderr, "MAX expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
push_value(vm, make_int(a.i > b.i ? a.i : b.i));
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file min.c
|
||||
* @file min.c
|
||||
* @brief Implements the OP_MIN opcode for finding the minimum of two values in the VM.
|
||||
*
|
||||
* This file handles the OP_MIN instruction, which finds the minimum of two integer values.
|
||||
|
|
@ -32,10 +32,14 @@
|
|||
*/
|
||||
|
||||
case OP_MIN: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) { fprintf(stderr, "MIN expects ints\n"); exit(1); }
|
||||
push_value(vm, make_int(a.i < b.i ? a.i : b.i));
|
||||
free_value(a); free_value(b);
|
||||
break;
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) {
|
||||
fprintf(stderr, "MIN expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
push_value(vm, make_int(a.i < b.i ? a.i : b.i));
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file mod.c
|
||||
* @file mod.c
|
||||
* @brief Implements the OP_MOD opcode for modulo operation in the VM.
|
||||
*
|
||||
* This file handles the OP_MOD instruction, which computes the modulo of two integer values.
|
||||
|
|
@ -33,20 +33,20 @@
|
|||
*/
|
||||
|
||||
case OP_MOD: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) {
|
||||
fprintf(stderr, "Runtime type error: MOD expects ints, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
if (b.i == 0) {
|
||||
fprintf(stderr, "Runtime error: modulo by zero\n");
|
||||
exit(1);
|
||||
}
|
||||
Value res = make_int(a.i % b.i);
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
push_value(vm, res);
|
||||
break;
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) {
|
||||
fprintf(stderr, "Runtime type error: MOD expects ints, got %s and %s\n",
|
||||
value_type_name(a.type), value_type_name(b.type));
|
||||
exit(1);
|
||||
}
|
||||
if (b.i == 0) {
|
||||
fprintf(stderr, "Runtime error: modulo by zero\n");
|
||||
exit(1);
|
||||
}
|
||||
Value res = make_int(a.i % b.i);
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
push_value(vm, res);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file pow.c
|
||||
* @file pow.c
|
||||
* @brief Implements the OP_POW opcode for exponentiation in the VM.
|
||||
*
|
||||
* This file handles the OP_POW instruction, which computes the power of two integer values.
|
||||
|
|
@ -32,20 +32,26 @@
|
|||
*/
|
||||
|
||||
case OP_POW: {
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) { fprintf(stderr, "POW expects ints\n"); exit(1); }
|
||||
int64_t base = a.i;
|
||||
int64_t exp = b.i;
|
||||
int64_t res = 1;
|
||||
if (exp < 0) { res = 0; } else {
|
||||
while (exp > 0) {
|
||||
if (exp & 1) res *= base;
|
||||
base *= base;
|
||||
exp >>= 1;
|
||||
}
|
||||
Value b = pop_value(vm);
|
||||
Value a = pop_value(vm);
|
||||
if (a.type != VAL_INT || b.type != VAL_INT) {
|
||||
fprintf(stderr, "POW expects ints\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t base = a.i;
|
||||
int64_t exp = b.i;
|
||||
int64_t res = 1;
|
||||
if (exp < 0) {
|
||||
res = 0;
|
||||
} else {
|
||||
while (exp > 0) {
|
||||
if (exp & 1) res *= base;
|
||||
base *= base;
|
||||
exp >>= 1;
|
||||
}
|
||||
push_value(vm, make_int(res));
|
||||
free_value(a); free_value(b);
|
||||
break;
|
||||
}
|
||||
push_value(vm, make_int(res));
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file random_int.c
|
||||
* @file random_int.c
|
||||
* @brief Implements the OP_RANDOM_INT opcode for generating random integers in the VM.
|
||||
*
|
||||
* This file handles the OP_RANDOM_INT instruction, which generates a random integer
|
||||
|
|
@ -34,14 +34,23 @@
|
|||
*/
|
||||
|
||||
case OP_RANDOM_INT: {
|
||||
Value hi = pop_value(vm);
|
||||
Value lo = pop_value(vm);
|
||||
if (lo.type != VAL_INT || hi.type != VAL_INT) { fprintf(stderr, "RANDOM_INT expects (int, int)\n"); exit(1); }
|
||||
int64_t a = lo.i, b = hi.i;
|
||||
if (b <= a) { push_value(vm, make_int((int64_t)a)); free_value(lo); free_value(hi); break; }
|
||||
int64_t span = b - a;
|
||||
int64_t r = (int64_t)(rand() % (span));
|
||||
push_value(vm, make_int(a + r));
|
||||
free_value(lo); free_value(hi);
|
||||
Value hi = pop_value(vm);
|
||||
Value lo = pop_value(vm);
|
||||
if (lo.type != VAL_INT || hi.type != VAL_INT) {
|
||||
fprintf(stderr, "RANDOM_INT expects (int, int)\n");
|
||||
exit(1);
|
||||
}
|
||||
int64_t a = lo.i, b = hi.i;
|
||||
if (b <= a) {
|
||||
push_value(vm, make_int((int64_t)a));
|
||||
free_value(lo);
|
||||
free_value(hi);
|
||||
break;
|
||||
}
|
||||
int64_t span = b - a;
|
||||
int64_t r = (int64_t)(rand() % (span));
|
||||
push_value(vm, make_int(a + r));
|
||||
free_value(lo);
|
||||
free_value(hi);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file random_seed.c
|
||||
* @file random_seed.c
|
||||
* @brief Implements the OP_RANDOM_SEED opcode for seeding the random number generator in the VM.
|
||||
*
|
||||
* This file handles the OP_RANDOM_SEED instruction, which seeds the random number generator
|
||||
|
|
@ -31,10 +31,13 @@
|
|||
*/
|
||||
|
||||
case OP_RANDOM_SEED: {
|
||||
Value seed = pop_value(vm);
|
||||
if (seed.type != VAL_INT) { fprintf(stderr, "RANDOM_SEED expects int\n"); exit(1); }
|
||||
srand((unsigned int)seed.i);
|
||||
free_value(seed);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
Value seed = pop_value(vm);
|
||||
if (seed.type != VAL_INT) {
|
||||
fprintf(stderr, "RANDOM_SEED expects int\n");
|
||||
exit(1);
|
||||
}
|
||||
srand((unsigned int)seed.i);
|
||||
free_value(seed);
|
||||
push_value(vm, make_int(0));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file round.c
|
||||
* @file round.c
|
||||
* @brief Implements the OP_ROUND opcode using C99 math.h round().
|
||||
* C99 round() rounds half away from zero.
|
||||
*/
|
||||
|
|
@ -18,26 +18,26 @@
|
|||
#include <math.h>
|
||||
|
||||
case OP_ROUND: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = round(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = round(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: ROUND expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: ROUND expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,24 +10,27 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file sign.c
|
||||
* @file sign.c
|
||||
* @brief Implements the OP_SIGN opcode returning -1, 0, or 1.
|
||||
*/
|
||||
|
||||
case OP_SIGN: {
|
||||
Value v = pop_value(vm);
|
||||
int out = 0;
|
||||
if (v.type == VAL_INT) {
|
||||
out = (v.i > 0) - (v.i < 0);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
if (v.d > 0.0) out = 1;
|
||||
else if (v.d < 0.0) out = -1;
|
||||
else out = 0;
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SIGN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
free_value(v);
|
||||
push_value(vm, make_int(out));
|
||||
break;
|
||||
Value v = pop_value(vm);
|
||||
int out = 0;
|
||||
if (v.type == VAL_INT) {
|
||||
out = (v.i > 0) - (v.i < 0);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
if (v.d > 0.0)
|
||||
out = 1;
|
||||
else if (v.d < 0.0)
|
||||
out = -1;
|
||||
else
|
||||
out = 0;
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SIGN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
free_value(v);
|
||||
push_value(vm, make_int(out));
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file sin.c
|
||||
* @file sin.c
|
||||
* @brief Implements the OP_SIN opcode using C99 math.h sin().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_SIN: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = sin(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SIN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = sin(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SIN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,36 +10,36 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file sqrt.c
|
||||
* @file sqrt.c
|
||||
* @brief Implements the OP_SQRT opcode using C99 math.h sqrt().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_SQRT: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x < 0.0) {
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
double r = sqrt(x);
|
||||
/* preserve int if exactly integral */
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
if (x < 0.0) {
|
||||
push_value(vm, make_float(NAN));
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SQRT expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
double r = sqrt(x);
|
||||
/* preserve int if exactly integral */
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: SQRT expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,22 +10,22 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file tan.c
|
||||
* @file tan.c
|
||||
* @brief Implements the OP_TAN opcode using C99 math.h tan().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_TAN: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = tan(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: TAN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT || v.type == VAL_FLOAT) {
|
||||
double x = (v.type == VAL_FLOAT) ? v.d : (double)v.i;
|
||||
double r = tan(x);
|
||||
push_value(vm, make_float(r));
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: TAN expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,33 +10,33 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file trunc.c
|
||||
* @file trunc.c
|
||||
* @brief Implements the OP_TRUNC opcode using C99 math.h trunc().
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
case OP_TRUNC: {
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = trunc(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
free_value(v);
|
||||
Value v = pop_value(vm);
|
||||
if (v.type == VAL_INT) {
|
||||
push_value(vm, make_int(v.i));
|
||||
free_value(v);
|
||||
} else if (v.type == VAL_FLOAT) {
|
||||
double r = trunc(v.d);
|
||||
if (r >= (double)INT64_MIN && r <= (double)INT64_MAX) {
|
||||
int64_t ii = (int64_t)r;
|
||||
if ((double)ii == r) {
|
||||
push_value(vm, make_int(ii));
|
||||
} else {
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: TRUNC expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
push_value(vm, make_float(r));
|
||||
}
|
||||
break;
|
||||
free_value(v);
|
||||
} else {
|
||||
fprintf(stderr, "Runtime type error: TRUNC expects number, got %s\n", value_type_name(v.type));
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue