Skip to content

Commit 016d895

Browse files
committed
Consolidate elementwise operators into a descriptor table
Every elementwise binary operator (+ - * / ^ %% %/%, comparisons, & && | ||) becomes a row in binop_table, compiled by one compile_binop that applies a closed set of mode rules (promote / double / compare / logical) and resolves shapes through resolve_elementwise(), the renamed maybe_reshape_vector_matrix() with the conformability policy applied via guard_conformable_dims() -- now the single guard emitter shared with the BLAS lowerings and ifelse() (whose private axis verdict and inline .or. guard are deleted). check_conformable() was dims_match() in list form; both call sites now say so. The real-domain floor spelling shared by floor() and double %/% is factored into real_floor_expr(). Behavior-neutral: zero snapshot churn, full QUICKR_FULL_GRID=1 pass, and byte-identical generated Fortran over a 20-program differential battery against the previous commit.
1 parent 109160b commit 016d895

8 files changed

Lines changed: 331 additions & 556 deletions

R/r2f-arithmetic.R

Lines changed: 0 additions & 148 deletions
This file was deleted.

R/r2f-conditionals.R

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,11 @@ ifelse_branch_shape_msg <- paste0(
88
"R-style recycling is not supported"
99
)
1010

11-
# Three-valued conformability verdict for one axis of an ifelse() branch
12-
# against `test`: ok+known (no guard), not-ok+known (compile error), or
13-
# unknown (runtime guard). NA dims are always unknown: two unknown lengths
14-
# are not the same quantity.
15-
ifelse_axis_verdict <- function(test_dim, branch_dim) {
16-
if (is_wholenumber(test_dim) && is_wholenumber(branch_dim)) {
17-
return(list(
18-
ok = identical(as.integer(test_dim), as.integer(branch_dim)),
19-
unknown = FALSE
20-
))
21-
}
22-
if (!is_scalar_na(test_dim) && !is_scalar_na(branch_dim)) {
23-
test_norm <- fortranize_expr_symbols(test_dim)
24-
branch_norm <- fortranize_expr_symbols(branch_dim)
25-
if (identical(test_norm, branch_norm)) {
26-
return(list(ok = TRUE, unknown = FALSE))
27-
}
28-
}
29-
list(ok = TRUE, unknown = TRUE)
30-
}
31-
3211
# Enforce the shape contract for one ifelse() branch: scalars broadcast
3312
# natively; a non-scalar branch must match `test`'s shape, because
3413
# merge() requires conformable arguments and a runtime mismatch would
35-
# read past the shorter branch. Statically unequal dims are a compile
14+
# read past the shorter branch. Per axis, guard_conformable_dims()
15+
# applies the framework policy: statically unequal dims are a compile
3616
# error; symbolic dims get a statement-level runtime size guard.
3717
check_ifelse_branch_shape <- function(branch, mask, hoist, scope) {
3818
if (passes_as_scalar(branch@value)) {
@@ -41,39 +21,19 @@ check_ifelse_branch_shape <- function(branch, mask, hoist, scope) {
4121
if (branch@value@rank != mask@value@rank) {
4222
stop(ifelse_branch_shape_msg, call. = FALSE)
4323
}
44-
unknown_axes <- integer()
4524
for (axis in seq_len(mask@value@rank)) {
46-
verdict <- ifelse_axis_verdict(
25+
guard_conformable_dims(
26+
dim_or_one(branch, axis),
4727
dim_or_one(mask, axis),
48-
dim_or_one(branch, axis)
28+
ifelse_branch_shape_msg,
29+
hoist,
30+
scope,
31+
left = branch,
32+
right = mask,
33+
left_axis = axis,
34+
right_axis = axis
4935
)
50-
if (!verdict$ok) {
51-
stop(ifelse_branch_shape_msg, call. = FALSE)
52-
}
53-
if (verdict$unknown) {
54-
unknown_axes <- c(unknown_axes, axis)
55-
}
56-
}
57-
if (!length(unknown_axes)) {
58-
return(invisible())
5936
}
60-
if (is.null(hoist)) {
61-
stop(
62-
"cannot emit a runtime length guard here; ",
63-
"ifelse() branch lengths must match `test` statically",
64-
call. = FALSE
65-
)
66-
}
67-
# size() is an inquiry, so applying it to operand expression text does
68-
# not evaluate the operands.
69-
condition <- str_flatten(
70-
map_chr(
71-
unknown_axes,
72-
function(axis) glue("size({branch}, {axis}) /= size({mask}, {axis})")
73-
),
74-
" .or. "
75-
)
76-
emit_quickr_error_if(condition, ifelse_branch_shape_msg, hoist, scope)
7737
invisible()
7838
}
7939

0 commit comments

Comments
 (0)