Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f371dee
Hoist dims2c size evaluation at translation time
t-kalinowski Jan 25, 2026
659ff61
Restrict vector-matrix recycling to nrow
t-kalinowski Jan 26, 2026
7dc5ebe
Error on undeclared arguments
t-kalinowski Jan 26, 2026
fcf2d8a
Validate names after Fortran mapping
t-kalinowski Jan 26, 2026
8b218f3
Support dotted symbols in quick()
t-kalinowski Jan 26, 2026
049522d
Support .Machine$double.eps
t-kalinowski Jan 26, 2026
045250a
Support svd() results via $d/$u/$v
t-kalinowski Jan 26, 2026
e07270f
update AGENTS.md
t-kalinowski Jan 26, 2026
a45500f
Support drop() for singleton matrices
t-kalinowski Jan 26, 2026
b58aee1
Support optional arguments with NULL defaults in local closures
t-kalinowski Jan 26, 2026
c2d79e3
render readme
t-kalinowski Jan 26, 2026
69a7780
Use Linpack QR path for qr.solve
t-kalinowski Jan 26, 2026
63e1b45
render readme
t-kalinowski Jan 26, 2026
abd8cd1
Rerender readme
t-kalinowski Jan 26, 2026
a98f935
Fix C bridge size hoist placement
t-kalinowski Jan 26, 2026
bac32a5
Validate optional NULL args in closures
t-kalinowski Jan 26, 2026
b969cc7
Treat unconditional optional arg assignment as initialized
t-kalinowski Jan 26, 2026
c328fb0
render readme
t-kalinowski Jan 26, 2026
89eddde
Update NEWS for linear algebra and naming
t-kalinowski Jan 26, 2026
3b7d555
Add tests for size expressions and optional args
t-kalinowski Jan 26, 2026
f67fd29
Fix dotted arg size expressions in C bridge
t-kalinowski Jan 27, 2026
29e9285
Add coverage-oriented quick() tests
t-kalinowski Jan 27, 2026
972bac1
Update NEWS for recent fixes
t-kalinowski Jan 27, 2026
c20ffa7
add tests
t-kalinowski Jan 27, 2026
d0aa8a8
More tests
t-kalinowski Jan 27, 2026
42eeb52
Make it possible to return the output of an `svd()` directly
t-kalinowski Jan 27, 2026
02fd044
more tests
t-kalinowski Jan 28, 2026
9e017d9
rerender readme
t-kalinowski Jan 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This project is an R package that transpiles R functions to Fortran.
R -q -e 'devtools::test()'
```

- To run the full `R CMD check` locally:
- To run the full `R CMD check` locally (this takes a long time):
```sh
R -q -e 'rcmdcheck::rcmdcheck(error_on = "warning")'
```
Expand All @@ -16,6 +16,17 @@ R -q -e 'rcmdcheck::rcmdcheck(error_on = "warning")'
R -q -e 'devtools::test_active_file("tests/testthat/test-dims2f.R")'
```

- To run a subset of test files:
```sh
R -q -e 'devtools::test(filter = "regex")'
```
filter arg behavior: If not `NULL`, only tests with file names matching this regular expression will be executed. Matching is performed on the file name after it's stripped of "test-" and ".R".

- To run full coverage and save zero-coverage JSON output:
```sh
R -q -e 'covr::package_coverage() -> cov; saveRDS(cov, "cov.rds"); z <- covr::zero_coverage(cov); jsonlite::toJSON(z, pretty = TRUE)'
```

- To see the generated C and Fortran code for an R function, use `r2f()`:
```sh
R --no-save -q <<'EOF'
Expand All @@ -33,10 +44,13 @@ EOF

- Never disable or skip tests.

- When adding tests, prefer user-facing API tests (e.g. `expect_quick_identical()`); avoid asserting on generated Fortran/C translation strings.
- When adding tests, strongly prefer tests that only excercise the public API (e.g. `expect_quick_identical()`); avoid asserting on generated Fortran/C translation strings unless explicitly asked. Avoid testing internal functions unless explicitly.

- When writing tests, make sure that we test both C/Fortran code generation (typically reported accuratly by covr), as well as calling the generated function (not covered by covr). Our tests must excercise the actual generated function.

- While troubleshooting and iterating towards a solution, you can run targeted single-file tests; After large refactors, always run the full test suite.

- While troubleshooting and iterating towards a solution, you can run targeted single-file tests; before committing/pushing, always run the full test suite and `rcmdcheck`.
- Before finishing a task, always run the full test suite and `rcmdcheck`.
- Before opening a PR, always run `rcmdcheck`.

- Prefer extending S7 classes with explicit properties over attaching arbitrary unchecked attributes.

Expand Down
31 changes: 30 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
- Added initial matrix/linear algebra handler support from base R, using the
same BLAS/LAPACK as R: `%*%`, `t()`, `crossprod()`, `tcrossprod()`,
`outer()` (with `FUN="*"`), `%o%`, `forwardsolve()`, `backsolve()`, `diag()`,
`t()`, `chol()`, `chol2inv()`, `solve()`, and `qr.solve()`.
`t()`, `chol()`, `chol2inv()`, `solve()`, and `qr.solve()`. This includes
support for:

- `drop()` for rank 0-2 inputs (including singleton matrices).
- `svd()` results via `$d`, `$u`, and `$v` (either from `s <- svd(x)` or
directly from `svd(x)$d`/`$u`/`$v`).
- `.Machine$double.eps`.
- `qr.solve()` using the LINPACK QR path (for better compatibility with
base R behavior).

The plan is to add more functions in the future (#77, #79 @mns-nordicals)

Expand Down Expand Up @@ -79,6 +87,27 @@
- Fixed a crash when compiling chained / fall-through assignments like
`a <- b <- 1` (#60).

- `quick()` now supports dotted symbols (e.g. `foo.bar`) for arguments, locals,
and loop variables. Conflicting names that map to the same Fortran symbol now
error (Fortran is case-insensitive).

- Fixed C bridge size checks for dotted argument names used in
`declare(type(...))` size expressions (e.g. `type(x = double(foo.bar))`).

- `quick()` now gives a helpful error message when a function argument is used
without being declared
(i.e. missing `declare(type(arg = ...))`).

- Fixed an error in invalid subscript arity reporting, e.g. `x[1, 2, 3]` on a
matrix now errors cleanly instead of failing while formatting the message.

- Vector-matrix recycling in arithmetic is now restricted to recycling
along the first axes only.

- Local closures now support optional arguments with `NULL` defaults, with
validation to ensure optional arguments are initialized (via `is.null()`)
before use.

# quickr 0.2.1

- Added support for `!` and unary `-` and `+` (#49, @mns-nordicals)
Expand Down
36 changes: 36 additions & 0 deletions R/aaa-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,42 @@ NULL

`%||%` <- function(x, y) if (is.null(x)) y else x

fortranize_name <- function(name, prefix = "v_") {
stopifnot(is_string(name), is_string(prefix), nzchar(prefix))
out <- gsub("[^A-Za-z0-9_]", "_", name)
if (!nzchar(out) || !grepl("^[A-Za-z]", out)) {
out <- paste0(prefix, out)
}
out
}

fortranize_expr_symbols <- function(expr) {
if (!is.symbol(expr) && !is.call(expr)) {
return(expr)
}
syms <- all.vars(expr)
if (!length(syms)) {
return(expr)
}
replacements <- setNames(
lapply(syms, \(sym) as.symbol(fortranize_name(sym))),
syms
)
substitute_(expr, list2env(replacements, parent = emptyenv()))
}

scope_fortran_symbol <- function(sym, scope) {
stopifnot(is.symbol(sym))
if (is.null(scope)) {
return(sym)
}
var <- get0(as.character(sym), scope)
if (inherits(var, Variable) && !is.null(var@name)) {
return(as.symbol(var@name))
}
sym
}

quickr_r_cmd <- function(
os_type = .Platform$OS.type,
r_home = R.home,
Expand Down
Loading