Skip to content

Commit f8e26fe

Browse files
gh-124: Fix CDIV.
1 parent 3490680 commit f8e26fe

1 file changed

Lines changed: 34 additions & 13 deletions

File tree

src/builtins.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,24 +3050,45 @@ static Value builtin_div(Interpreter* interp, Value* args, int argc, Expr** arg_
30503050
return result;
30513051
}
30523052

3053-
// CDIV: ceiling integer division (int-only semantics similar to Python's safe_cdiv)
3053+
// CDIV: ceiling division (supports INT and FLT; returns same numeric type)
30543054
static Value builtin_cdiv(Interpreter* interp, Value* args, int argc, Expr** arg_nodes, Env* env, int line, int col) {
30553055
(void)arg_nodes; (void)env;
3056-
EXPECT_INT(args[0], "CDIV", interp, line, col);
3057-
EXPECT_INT(args[1], "CDIV", interp, line, col);
3056+
EXPECT_NUM(args[0], "CDIV", interp, line, col);
3057+
EXPECT_NUM(args[1], "CDIV", interp, line, col);
30583058

3059-
int64_t a = args[0].as.i;
3060-
int64_t b = args[1].as.i;
3061-
if (b == 0) {
3062-
RUNTIME_ERROR(interp, "Division by zero", line, col);
3059+
if (args[0].type != args[1].type) {
3060+
RUNTIME_ERROR(interp, "CDIV cannot mix INT and FLT", line, col);
30633061
}
3064-
double res = ceil((double)a / (double)b);
3065-
Value result = value_int((int64_t)res);
3066-
if (!writeback_ptr_range(interp, arg_nodes, env, 0, 2, result, "CDIV", line, col)) {
3067-
value_free(result);
3068-
return value_null();
3062+
3063+
int out_base = result_base_from_values(args[0], args[1]);
3064+
3065+
if (args[0].type == VAL_INT) {
3066+
int64_t a = args[0].as.i;
3067+
int64_t b = args[1].as.i;
3068+
if (b == 0) {
3069+
RUNTIME_ERROR(interp, "Division by zero", line, col);
3070+
}
3071+
int64_t q = a / b;
3072+
int64_t r = a % b;
3073+
if (r != 0 && ((a > 0) == (b > 0))) q += 1;
3074+
Value result = value_int_base(q, out_base);
3075+
if (!writeback_ptr_range(interp, arg_nodes, env, 0, 2, result, "CDIV", line, col)) {
3076+
value_free(result);
3077+
return value_null();
3078+
}
3079+
return result;
3080+
} else {
3081+
if (args[1].as.f == 0.0) {
3082+
RUNTIME_ERROR(interp, "Division by zero", line, col);
3083+
}
3084+
double res = ceil(args[0].as.f / args[1].as.f);
3085+
Value result = value_flt_base(res, out_base);
3086+
if (!writeback_ptr_range(interp, arg_nodes, env, 0, 2, result, "CDIV", line, col)) {
3087+
value_free(result);
3088+
return value_null();
3089+
}
3090+
return result;
30693091
}
3070-
return result;
30713092
}
30723093

30733094
static Value builtin_mod(Interpreter* interp, Value* args, int argc, Expr** arg_nodes, Env* env, int line, int col) {

0 commit comments

Comments
 (0)