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

sjsonnet.Expr.scala Maven / Gradle / Ivy

package sjsonnet

import java.util.{Arrays, BitSet}
import scala.collection.mutable

/**
  * [[Expr]]s are the parsed syntax trees of a Jsonnet program. They model the
  * program mostly as-written, except for resolving local variable names and
  * assigning them indices in the scope bindings array.
  *
  * Each [[Expr]] represents an expression in the Jsonnet program, and contains an
  * integer offset into the file that is later used to provide error messages.
  */
trait Expr{
  def pos: Position

  /** The name of this expression type to be shown in error messages */
  def exprErrorString: String = {
    val n = getClass.getName
    if(n.startsWith("sjsonnet.Expr$")) n.substring(14) else n
  }
}
object Expr{
  private final def arrStr(a: Array[_]): String = {
    if(a == null) "null" else a.mkString("[", ", ", "]")
  }

  case class Self(pos: Position) extends Expr
  case class Super(pos: Position) extends Expr
  case class $(pos: Position) extends Expr

  case class Id(pos: Position, name: String) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} $name"
  }
  case class ValidId(pos: Position, name: String, nameIdx: Int) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} $name"
  }
  case class Arr(pos: Position, value: Array[Expr]) extends Expr {
    override def toString = s"Arr($pos, ${arrStr(value)})"
  }

  sealed trait FieldName

  object FieldName{
    case class Fixed(value: String) extends FieldName
    case class Dyn(expr: Expr) extends FieldName
  }
  sealed trait Member

  object Member{
    sealed trait Visibility
    object Visibility{

      case object Normal extends Visibility
      case object Hidden extends Visibility
      case object Unhide extends Visibility
    }
    case class Field(pos: Position,
                     fieldName: FieldName,
                     plus: Boolean,
                     args: Params,
                     sep: Visibility,
                     rhs: Expr) extends Member {
      def isStatic = fieldName.isInstanceOf[FieldName.Fixed] && !plus && args == null && sep == Visibility.Normal && rhs.isInstanceOf[Val.Literal]
    }
    case class AssertStmt(value: Expr, msg: Expr) extends Member
  }

  case class Params(names: Array[String], defaultExprs: Array[Expr]){
    val paramMap = names.zipWithIndex.toMap
    override def toString = s"Params(${arrStr(names)}, ${arrStr(defaultExprs)})"
  }

  case class UnaryOp(pos: Position, op: Int, value: Expr) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} ${UnaryOp.name(op)}"
  }
  object UnaryOp{
    final val OP_! = 0
    final val OP_- = 1
    final val OP_~ = 2
    final val OP_+ = 3
    private val names = Map(OP_! -> "!", OP_- -> "-", OP_~ -> "~", OP_+ -> "+")
    def name(op: Int): String = names.getOrElse(op, "")
  }
  case class And(pos: Position, lhs: Expr, rhs: Expr) extends Expr
  case class Or(pos: Position, lhs: Expr, rhs: Expr) extends Expr
  case class BinaryOp(pos: Position, lhs: Expr, op: Int, rhs: Expr) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} ${BinaryOp.name(op)}"
  }
  object BinaryOp{
    final val OP_* = 0
    final val OP_/ = 1
    final val OP_% = 2
    final val OP_+ = 3
    final val OP_- = 4
    final val OP_<< = 5
    final val OP_>> = 6
    final val OP_< = 7
    final val OP_> = 8
    final val OP_<= = 9
    final val OP_>= = 10
    final val OP_in = 11
    final val OP_== = 12
    final val OP_!= = 13
    final val OP_& = 14
    final val OP_^ = 15
    final val OP_| = 16
    final val OP_&& = 17
    final val OP_|| = 18
    private val names = Map(OP_* -> "*", OP_/ -> "/", OP_% -> "%", OP_+ -> "+", OP_- -> "-", OP_<< -> "<<",
      OP_>> -> ">>", OP_< -> "<", OP_> -> ">", OP_<= -> "<=", OP_>= -> ">=", OP_in -> "in", OP_== -> "==",
      OP_!= -> "!=", OP_& -> "&", OP_^ -> "^", OP_| -> "|", OP_&& -> "&&", OP_|| -> "||" )
    def name(op: Int): String = names.getOrElse(op, "")
  }
  case class AssertExpr(pos: Position, asserted: Member.AssertStmt, returned: Expr) extends Expr
  case class LocalExpr(pos: Position, bindings: Array[Bind], returned: Expr) extends Expr {
    override def toString = s"LocalExpr($pos, ${arrStr(bindings)}, $returned)"
    override def equals(o: Any): Boolean = o match {
      case o: LocalExpr =>
        pos == o.pos && Arrays.equals(bindings.asInstanceOf[Array[AnyRef]], o.bindings.asInstanceOf[Array[AnyRef]]) && returned == o.returned
      case _ => false
    }
  }

  case class Bind(pos: Position, name: String, args: Params, rhs: Expr) extends Member
  case class Import(pos: Position, value: String) extends Expr
  case class ImportStr(pos: Position, value: String) extends Expr
  case class Error(pos: Position, value: Expr) extends Expr
  case class Apply(pos: Position, value: Expr, args: Array[Expr], namedNames: Array[String]) extends Expr
  case class Apply0(pos: Position, value: Expr) extends Expr
  case class Apply1(pos: Position, value: Expr, a1: Expr) extends Expr
  case class Apply2(pos: Position, value: Expr, a1: Expr, a2: Expr) extends Expr
  case class Apply3(pos: Position, value: Expr, a1: Expr, a2: Expr, a3: Expr) extends Expr
  case class ApplyBuiltin(pos: Position, func: Val.Builtin, argExprs: Array[Expr]) extends Expr
  case class ApplyBuiltin1(pos: Position, func: Val.Builtin1, a1: Expr) extends Expr
  case class ApplyBuiltin2(pos: Position, func: Val.Builtin2, a1: Expr, a2: Expr) extends Expr
  case class Select(pos: Position, value: Expr, name: String) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} $name"
  }
  case class SelectSuper(pos: Position, selfIdx: Int, name: String) extends Expr {
    override def exprErrorString: String = s"${super.exprErrorString} $name"
  }
  case class InSuper(pos: Position, value: Expr, selfIdx: Int) extends Expr
  case class Lookup(pos: Position, value: Expr, index: Expr) extends Expr
  case class LookupSuper(pos: Position, selfIdx: Int, index: Expr) extends Expr
  case class Slice(pos: Position,
                   value: Expr,
                   start: Option[Expr],
                   end: Option[Expr],
                   stride: Option[Expr]) extends Expr
  case class Function(pos: Position, params: Params, body: Expr) extends Expr
  case class IfElse(pos: Position, cond: Expr, then: Expr, `else`: Expr) extends Expr

  sealed trait CompSpec extends Expr
  case class IfSpec(pos: Position, cond: Expr) extends CompSpec
  case class ForSpec(pos: Position, name: String, cond: Expr) extends CompSpec

  case class Comp(pos: Position, value: Expr, first: ForSpec, rest: Array[CompSpec]) extends Expr
  case class ObjExtend(pos: Position, base: Expr, ext: ObjBody) extends Expr

  trait ObjBody extends Expr
  object ObjBody{
    case class MemberList(pos: Position, binds: Array[Bind], fields: Array[Member.Field], asserts: Array[Member.AssertStmt]) extends ObjBody
    case class ObjComp(pos: Position,
                       preLocals: Array[Bind],
                       key: Expr,
                       value: Expr,
                       plus: Boolean,
                       postLocals: Array[Bind],
                       first: ForSpec,
                       rest: List[CompSpec]) extends ObjBody {
      override def toString = s"ObjComp($pos, ${arrStr(preLocals)}, $key, $value, ${arrStr(postLocals)}, $first, $rest)"
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy