Skip to content

Commit 92e07b2

Browse files
authored
Merge pull request t-kalinowski#53 from mns-nordicals/fix/unary-+,-,!
Add unary "+", "-" and "!"
2 parents 599bd98 + d31b362 commit 92e07b2

3 files changed

Lines changed: 71 additions & 4 deletions

File tree

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# quickr (development version)
2+
- Added support for `!` and unary `-` and `+` (#49, @mns-nordicals)
23

34
- Functions can now return multiple arrays in a `list()`, optionally
45
named (#49, @mns-nordicals).

R/r2f.R

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -658,13 +658,25 @@ maybe_cast_double <- function(x) {
658658
}
659659

660660
r2f_handlers[["+"]] <- function(args, scope, ...) {
661-
.[left, right] <- lapply(args, r2f, scope, ...)
662-
Fortran(glue("({left} + {right})"), conform(left@value, right@value))
661+
# Support both binary and unary plus
662+
if (length(args) == 1L) {
663+
x <- r2f(args[[1L]], scope, ...)
664+
Fortran(glue("(+{x})"), x@value)
665+
} else {
666+
.[left, right] <- lapply(args, r2f, scope, ...)
667+
Fortran(glue("({left} + {right})"), conform(left@value, right@value))
668+
}
663669
}
664670

665671
r2f_handlers[["-"]] <- function(args, scope, ...) {
666-
.[left, right] <- lapply(args, r2f, scope, ...)
667-
Fortran(glue("({left} - {right})"), conform(left@value, right@value))
672+
# Support both binary and unary minus
673+
if (length(args) == 1L) {
674+
x <- r2f(args[[1L]], scope, ...)
675+
Fortran(glue("(-{x})"), x@value)
676+
} else {
677+
.[left, right] <- lapply(args, r2f, scope, ...)
678+
Fortran(glue("({left} - {right})"), conform(left@value, right@value))
679+
}
668680
}
669681

670682
r2f_handlers[["*"]] <- function(args, scope = NULL, ...) {
@@ -727,6 +739,16 @@ r2f_handlers[["!="]] <- function(args, scope, ...) {
727739
Fortran(glue("({left} /= {right})"), var)
728740
}
729741

742+
# ---- unary logical not ----
743+
r2f_handlers[["!"]] <- function(args, scope, ...) {
744+
stopifnot(length(args) == 1L)
745+
x <- r2f(args[[1L]], scope, ...)
746+
if (x@value@mode != "logical") {
747+
stop("'!' expects a logical value; numeric coercions not yet supported")
748+
}
749+
Fortran(glue("(.not. {x})"), x@value)
750+
}
751+
730752

731753
# ---- remainder (%%) and integer division (%/%) ----
732754
#

tests/testthat/test-unary-intrinsics.R

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,47 @@ test_that("complex unary intrinsics", {
100100
expect_quick_equal(fn, z)
101101
}
102102
})
103+
104+
105+
test_that("unary logical 'not'-operator on vector", {
106+
fn <- function(x) {
107+
declare(type(x = integer(n)))
108+
lgl <- x > 1L
109+
not_lgl <- !lgl
110+
not_lgl
111+
}
112+
113+
x1 <- -3:3
114+
x2 <- 0:5
115+
expect_quick_identical(fn, list(x1), list(x2))
116+
})
117+
118+
test_that("unary minus and plus for integer and double", {
119+
fn_neg_i <- function(x) {
120+
declare(type(x = integer(n)))
121+
y <- -x
122+
y
123+
}
124+
fn_pos_i <- function(x) {
125+
declare(type(x = integer(n)))
126+
y <- +x
127+
y
128+
}
129+
xi <- -5:5
130+
expect_quick_identical(fn_neg_i, list(xi))
131+
expect_quick_identical(fn_pos_i, list(xi))
132+
133+
fn_neg_d <- function(x) {
134+
declare(type(x = double(n)))
135+
y <- -x
136+
y
137+
}
138+
fn_pos_d <- function(x) {
139+
declare(type(x = double(n)))
140+
y <- +x
141+
y
142+
}
143+
xd <- -5:5 + 0.5
144+
expect_quick_equal(fn_neg_d, list(xd))
145+
expect_quick_equal(fn_pos_d, list(xd))
146+
})

0 commit comments

Comments
 (0)