-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathr2f-core-handlers.R
More file actions
84 lines (74 loc) · 2.22 KB
/
Copy pathr2f-core-handlers.R
File metadata and controls
84 lines (74 loc) · 2.22 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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# r2f-core-handlers.R
# Handlers for core language constructs: declare, Fortran, (, {
# --- Handlers ---
r2f_handlers[["declare"]] <- function(args, scope, ...) {
for (a in args) {
if (is_missing(a)) {
next
}
if (is_parallel_decl_call(a)) {
if (has_pending_parallel(scope)) {
stop("parallel()/omp() declaration already pending.", call. = FALSE)
}
set_pending_parallel(scope, parse_parallel_decl(a))
} else if (is_type_call(a)) {
var <- type_call_to_var(a)
var@is_arg <- var@name %in% names(formals(scope@closure))
if (identical(var@mode, "logical") && isTRUE(var@is_arg)) {
var@logical_as_int <- TRUE
}
scope[[var@name]] <- var
} else if (is_call(a, quote(`{`))) {
Recall(as.list(a)[-1], scope)
}
}
Fortran("")
}
r2f_handlers[["Fortran"]] <- function(args, scope = NULL, ...) {
if (!is_string(args[[1]])) {
stop("Fortran() must be called with a string")
}
Fortran(args[[1]])
# enable passing through literal fortran code
# used like:
# Fortran("nearest(x, 1)", double(length(x)))
# Fortran("nearest(x, 1)", x)
# Fortran("x = nearest(x, 1)")
}
r2f_handlers[["stop"]] <- function(args, scope = NULL, ...) {
if (!length(args)) {
msg <- "Execution halted"
} else {
if (
length(args) != 1L ||
!is.character(args[[1L]]) ||
length(args[[1L]]) != 1L
) {
stop(
"stop() only supports a single string literal message",
call. = FALSE
)
}
msg <- args[[1L]]
}
mark_scope_uses_errors(scope)
Fortran(str_flatten_lines(quickr_error_fortran_lines(msg)))
}
r2f_handlers[["("]] <- function(args, scope, ...) {
x <- r2f(args[[1L]], scope, ...)
Fortran(glue("({x})"), x@value)
}
r2f_handlers[["{"]] <- function(args, scope, ..., hoist = NULL) {
# every top level R-expr / fortran statement gets its own hoist target.
x <- vector("list", length(args))
for (i in seq_along(args)) {
stmt <- args[[i]]
check_pending_parallel_target(stmt, scope)
x[[i]] <- r2f(stmt, scope, ...)
}
check_pending_parallel_consumed(scope)
code <- str_flatten_lines(x)
# browser()
value <- (if (length(args)) last(x)@value) %||% Variable()
Fortran(code, value)
}