-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathr2f-rev.R
More file actions
43 lines (35 loc) · 1.32 KB
/
Copy pathr2f-rev.R
File metadata and controls
43 lines (35 loc) · 1.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# r2f-rev.R
# Handler for rev()
r2f_handlers[["rev"]] <- function(args, scope, ..., hoist = NULL) {
stopifnot(length(args) == 1L)
x <- r2f(args[[1L]], scope, ..., hoist = hoist)
if (is.null(x@value)) {
stop("rev() expects a typed value", call. = FALSE)
}
# Scalars (incl. length-1 vectors that are lowered as scalars) reverse to self.
if (passes_as_scalar(x@value)) {
return(x)
}
if (x@value@rank != 1L) {
stop("rev() only supports rank 0-1 inputs", call. = FALSE)
}
# Fortran array sections require an array designator; hoist array expressions.
if (is.null(x@value@name)) {
tmp <- hoist$declare_tmp(mode = x@value@mode, dims = x@value@dims)
hoist$emit(glue("{tmp@name} = {x}"))
x <- Fortran(tmp@name, tmp)
}
base_name <- x@value@name %||%
stop("missing array name for rev()", call. = FALSE)
# External logical args are stored as integer(0/1) and symbol-lowered as `(x/=0)`.
# Reverse the underlying storage then booleanize the resulting section.
if (identical(x@value@mode, "logical") && logical_as_int(x@value)) {
out_val <- Variable("logical", x@value@dims)
return(Fortran(
glue("({base_name}(size({base_name}):1:-1) /= 0)"),
out_val
))
}
out_val <- Variable(x@value@mode, x@value@dims)
Fortran(glue("{base_name}(size({base_name}):1:-1)"), out_val)
}