R/subset.R

Defines functions names.Branch names.Return names.If names.Loop names.While names.For names.Invocation names.Call names.Assignment names.Parameter names.Function names.ParameterList names.ASTNode length.ASTNode length.Container `[.Container` `[[.ASTNode` `[[.Container` `[[<-.ASTNode` `[[<-.Container`

# To see the fields, use `ls(..., all = T)`

#' @export
names.Branch   = function(x) c("target")
#' @export
  names.Return = function(x) c("target", "read")

#' @export
names.If      = function(x) c("true", "false", "condition")
#' @export
names.Loop    = function(x) c("body", "exit")
#' @export
  names.While = function(x) c("body", "exit", "condition")
#' @export
  names.For   = function(x) c("body", "exit", "variable", "iterator")

#' @export
names.Invocation = function(x) c("args")
#' @export
  names.Call     = function(x) c("fn", "args")

#' @export
names.Assignment = function(x) c("write", "read")
#' @export
names.Parameter = function(x) c("default")
#' @export
names.Function  = function(x) c("body", "params")

# NOTE: Methods for *List objects are a temporary fix until we figure out
# where to use names() versus child_fields().
#' @export
names.ParameterList = function(x) names(x$contents)

#' @export
names.ArgumentList = names.ParameterList

#' @export
names.ASTNode = function(x) character(0)


# Length ----------------------------------------

#' @export
length.ASTNode = function(x) {
  length(names(x))
}

#' @export
length.Container = function(x) {
  length(x$contents)
}


# Subset ----------------------------------------

#' @export
`[.Container` = function(x, i, ...) {
  x$contents[i, ...]
}


# Subset2 ----------------------------------------

#' @export
`[[.ASTNode` = function(x, i, ...) {
  if (!is.numeric(i))
    return (NextMethod())

  x = .subset2(x, names(x)[[ i[[1L]] ]], ...)

  if (length(i) <= 1)
    return (x)

  x[[ i[-1L], ... ]]
}

#' @export
`[[.Container` = function(x, i, ...) {
  if (!is.numeric(i))
    return (NextMethod())

  x = x$contents[[ i[[1L]], ... ]]

  if (length(i) <= 1)
    return (x)

  x[[ i[-1], ... ]]
}


# Replacement2 ----------------------------------------

#' @export
`[[<-.ASTNode` = function(x, i, ..., value) {
  if (!is.numeric(i))
    return (NextMethod())

  field = names(x)[[ i[[1L]] ]]

  if (length(i) > 1)
    # Call the replacement method for the child node.
    value = `[[<-`(x[[field]], i[-1L], ..., value = value)

  i = field
  # Replace, ignoring the ASTNode class.
  NextMethod()
}

#' @export
`[[<-.Container` = function(x, i, ..., value) {
  if (!is.numeric(i))
    return (NextMethod())

  i1 = i[[1L]]

  if (length(i) > 1)
    value = `[[<-`(x$contents[[i1]], i[-1L], ..., value = value)

  # Replace the list element.
  x$contents[[i1, ...]] = value
  x
}
nick-ulle/ast documentation built on Oct. 18, 2019, 4:37 a.m.