All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sjsonnet.ValScope.scala Maven / Gradle / Ivy

The newest version!
package sjsonnet

import java.util.Arrays

/**
 * [[ValScope]]s which model the lexical scopes within a Jsonnet file that bind variable names to
 * [[Val]]s, as well as other contextual information like `self` `this` or `super`.
 *
 * Note that scopes are standalone, and nested scopes are done by copying and updating the array of
 * bindings rather than using a linked list. This is because the bindings array is typically pretty
 * small and the constant factor overhead from a cleverer data structure dominates any algorithmic
 * improvements
 *
 * The bindings array is private and only copy-on-write, so for nested scopes which do not change it
 * (e.g. those just updating `dollar0` or `self0`) the bindings array can be shared cheaply.
 */
final class ValScope private (val bindings: Array[Lazy]) extends AnyVal {

  def length: Int = bindings.length

  def extend(newBindings: Array[Lazy], newSelf: Val.Obj, newSuper: Val.Obj): ValScope = {
    val b = Arrays.copyOf(bindings, bindings.length + newBindings.length + 2)
    b(bindings.length) = newSelf
    b(bindings.length + 1) = newSuper
    System.arraycopy(newBindings, 0, b, bindings.length + 2, newBindings.length)
    new ValScope(b)
  }

  def extendSimple(newBindingsV: Array[? <: Lazy]): ValScope = {
    if (newBindingsV == null || newBindingsV.length == 0) this
    else {
      val b = Arrays.copyOf(bindings, bindings.length + newBindingsV.length)
      System.arraycopy(newBindingsV, 0, b, bindings.length, newBindingsV.length)
      new ValScope(b)
    }
  }

  def extendBy(num: Int): ValScope =
    if (num == 0) this
    else new ValScope(Arrays.copyOf(bindings, bindings.length + num))

  def extendSimple(l1: Lazy): ValScope = {
    val b = Arrays.copyOf(bindings, bindings.length + 1)
    b(bindings.length) = l1
    new ValScope(b)
  }

  def extendSimple(l1: Lazy, l2: Lazy): ValScope = {
    val b = Arrays.copyOf(bindings, bindings.length + 2)
    b(bindings.length) = l1
    b(bindings.length + 1) = l2
    new ValScope(b)
  }

  def extendSimple(l1: Lazy, l2: Lazy, l3: Lazy): ValScope = {
    val b = Arrays.copyOf(bindings, bindings.length + 3)
    b(bindings.length) = l1
    b(bindings.length + 1) = l2
    b(bindings.length + 2) = l3
    new ValScope(b)
  }
}

object ValScope {
  private val emptyArr = new Array[Lazy](0)
  def empty = new ValScope(emptyArr)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy