Git Product home page Git Product logo

rstatic's Introduction

rstatic

rstatic is a package that makes it easier to analyze R code. These are the guiding principles:

  • Reference semantics make code easier to transform. Want to make major code transformations without losing track of an important expression? References have you covered. rstatic's code objects have reference semantics by way of R6.

  • Method dispatch on code objects makes recursive descent algorithms easier to understand. This is more effective if code is organized into meaningful, extensible classes. rstatic's class hierarchy is arranged according to the semantics of R.

  • Access to the parent of a node in an abstract syntax tree is useful for some analyses. rstatic transparently keeps track of each node's parents.

  • Access to code elements by name is clearer than by index. We'd rather write my_call$args[[2]] to access a call's second argument than my_call[[3]]. rstatic uses a consistent set of names for code elements.

  • Abstract syntax trees are not ideal for analyses that need control- and data-flow information. rstatic can convert code to a control flow graph in static single assignment (SSA) form. SSA form exposes data flows by giving each variable definition a unique name.

The codetools and CodeDepends packages use R's built-in language objects to extract similar information from code. They may be more appropriate for quick, ad-hoc analyses.

Installation

rstatic is unstable and under active development, so it's not yet available on CRAN. To install, open an R prompt and run:

install.packages("devtools")

devtools::install_github("nick-ulle/rstatic")

Usage

The package includes a vignette that serves as an introduction. To access the vignette, open an R prompt and run:

library(rstatic)
vignette("rstatic-intro")

Known Issues

See the to-do list.

rstatic's People

Contributors

clarkfitzg avatar duncantl avatar nick-ulle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

rstatic's Issues

Selecting indices from subset assignment

I'd like to pick the indices out of a subset assignment. That is, for the line:

x[i, j, k] = foo

I want an argument list of [i, j, k]. Right now the argument list isn't named. I can get the indices by dropping the first and last arguments. This is acceptable, but I think it could be improved.

I would like it best if the argument list had semantically meaningful names, for example something like:
[original = x, indices = [i, j, k], value = foo].

Looking at the documentation for [<-, we see:

     x[i] <- value
     x[i, j, ...] <- value

This suggests another option- to do something like the match.call for the subset assignment, so that the arguments have names x, i, j, dots, value. This does raise some issues, because x[i] is different from x[i,] (with j missing).

Current behavior:

> e3 = quote_ast(x[1, 1] <- foo)
> e3
<Replacement> $parent $read $write
x = `[<-`(x, 1, 1, foo)

> e3$read
<Call> $args $fn $parent
`[<-`(x, 1, 1, foo)

> e3$read$args
<ArgumentList> $contents $parent
list(x, 1, 1, foo)

How to read in ast for script?

We often start with something like a parsed script. How to convert this to an AST?

e = parse(text = "x = 1:10
plot(x)")

to_ast(e)
# Error in to_ast.default(e) : Cannot convert 'expression' to an ASTNode.

The approach below works fine to convert each element. Is there something like a c() function for AST objects?

lapply(e, to_ast)

Is 'rlang' a dependency?

rstatic uses package rlang, but doesn't mention it in DESCRIPTION.

clarkf@poisson ~/dev/rstatic (master)
$ grep -r "rlang::" *
R/utilities.R:  dots = rlang::quos(...)
R/utilities.R:    if (rlang::quo_is_missing(elt))
R/utilities.R:      rlang::eval_tidy(elt)

vignette not building

clark@DSI-CF ~/dev/rstatic (master)
$ R CMD build .
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘rstatic’:
* checking DESCRIPTION meta-information ... OK
* installing the package to build vignettes
* creating vignettes ... ERROR
Warning in engine$weave(file, quiet = quiet, encoding = enc) :
  Pandoc (>= 1.12.3) and/or pandoc-citeproc not available. Falling back to R Markdown v1.
Warning in engine$weave(file, quiet = quiet, encoding = enc) :
  Pandoc (>= 1.12.3) and/or pandoc-citeproc not available. Falling back to R Markdown v1.
Quitting from lines 55-67 (rstatic-intro.Rmd) 
Error: processing vignette 'rstatic-intro.Rmd' failed with diagnostics:
could not find function "to_ast"
Execution halted

Looks like the variable names just need to be updated.

not able to evaluate SSA R code

How can the following code be converted to SSA?

library(rstatic)

node0 = quote_ast({
    x = data.frame(a = 1:10, b = letters[1:10])
    x$c = rnorm(10)
    sum(x$a)
    head(x)
})

# We can evaluate this.
eval(to_r(node0))

# Seems to go from a brace to a function
node = to_cfg(node0)
nr = to_r(node)
f = eval(nr)

# But we can't evaluate it here.
f()

Some relevant output:

> f()
Error in x_2$c = rnorm(10) : object 'x_2' not found
> f
function () 
{
    x_1 = data.frame(a = 1:10, b = letters[1:10])
    x_2$c = rnorm(10)
    sum(x_2$a)
    return(head(x_2))
}

It seems we need to add the line x_2 = x_1.

Make ASTNode initializer methods more convenient

Generating new code is unwieldy because most of the ASTNode initializer methods only accept ASTNodes as arguments. This issue is to make the initializer methods more user friendly by having them accept regular R objects and convert automatically.

For example,

Call$new(Symbol$new("+"), list(Integer$new(3L), Integer$new(4L)))

should be something we can write succinctly as

Call$new("+", list(3L, 4L))

or even

Call$new("+", 3L, 4L)

Lightweight CFG generation

The information in the CFG (including SSA form) would be more useful if it existed alongside the AST rather than being a replacement.

The goal of this issue is to come up with a "lightweight" version of the CFG that is still useful for compilation but can also be used for transformations to the AST.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.