Skip to content

Commit

Permalink
sigma-ast: all tests passed
Browse files Browse the repository at this point in the history
  • Loading branch information
aslesarenko committed Aug 27, 2023
1 parent f8fafbc commit d479754
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 66 deletions.
11 changes: 0 additions & 11 deletions core/shared/src/main/scala/sigma/ast/SType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -782,17 +782,6 @@ object STuple extends STypeCompanion {
/** Helper factory method. */
def apply(items: SType*): STuple = STuple(items.toArray)

private val MaxTupleLength: Int = SigmaConstants.MaxTupleLength.value
private val componentNames = Array.tabulate(MaxTupleLength){ i => s"_${i + 1}" }

/** Returns method name for the tuple component accessor (i.e. `_1`, `_2`, etc.) */
def componentNameByIndex(i: Int): String =
try componentNames(i)
catch {
case e: IndexOutOfBoundsException =>
throw new IllegalArgumentException(
s"Tuple component '_${i+1}' is not defined: valid range (1 .. $MaxTupleLength)", e)
}
}

/** Type descriptor of `Box` type of ErgoTree. */
Expand Down
6 changes: 3 additions & 3 deletions interpreter/shared/src/main/scala/sigmastate/SMethod.scala
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,9 @@ object SMethod {
* `parse` method and hence it is part of consensus protocol
*/
def fromIds(typeId: Byte, methodId: Byte): SMethod = {
ValidationRules.CheckTypeWithMethods(typeId, MethodsContainer.containers.contains(typeId))
val methods = MethodsContainer.containers(typeId)
val method = methods.methodById(methodId)
ValidationRules.CheckTypeWithMethods(typeId, MethodsContainer.contains(typeId))
val container = MethodsContainer(typeId)
val method = container.methodById(methodId)
method
}
}
Expand Down
7 changes: 2 additions & 5 deletions interpreter/shared/src/main/scala/sigmastate/lang/Terms.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,8 @@ object Terms {
override def companion = Select
override val tpe: SType = resType.getOrElse(obj.tpe match {
case p: SProduct =>
MethodsContainer.containers.get(p.typeCode) match {
case Some(container) =>
val i = container.methodIndex(field)
if (i == -1) NoType
else container.methods(i).stype
MethodsContainer.getMethod(p, field) match {
case Some(m) => m.stype
case None => NoType
}
case _ => NoType
Expand Down
48 changes: 33 additions & 15 deletions interpreter/shared/src/main/scala/sigmastate/types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,23 @@ import org.ergoplatform._
import org.ergoplatform.validation._
import scorex.crypto.authds.avltree.batch.{Insert, Lookup, Remove, Update}
import scorex.crypto.authds.{ADKey, ADValue}
import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray}
import sigma.ast.SType.TypeCode
import sigma.ast._
import sigma.data.{Nullable, RType, SigmaConstants}
import sigma.reflection.{RClass, RMethod}
import sigma.util.Extensions.{IntOps, LongOps, ShortOps}
import sigma.reflection.RClass
import sigma.{Coll, _}
import sigmastate.SMethod.{InvokeDescBuilder, MethodCallIrBuilder, MethodCostFunc, javaMethodOf}
import sigmastate.SMethod.{MethodCallIrBuilder, MethodCostFunc, javaMethodOf}
import sigmastate.Values._
import Evaluation.stypeToRType
import sigma.ast.SCollection.{SBooleanArray, SBoxArray, SByteArray, SByteArray2, SHeaderArray}
import sigmastate.eval._
import sigmastate.interpreter._
import sigmastate.lang.Terms
import sigmastate.lang.Terms._
import sigmastate.lang.{SigmaBuilder, Terms}
import sigmastate.serialization.OpCodes
import sigmastate.utils.Overloading.Overload1
import sigmastate.utxo._
import sigmastate.lang.Terms._
import sigmastate.utils.SparseArrayContainer
import sigmastate.utxo._

import java.math.BigInteger
import scala.collection.compat.immutable.ArraySeq
import scala.language.implicitConversions
import scala.reflect.ClassTag
import scala.util.{Failure, Success}

/** Base type for all companions of AST nodes of sigma lang. */
Expand All @@ -47,6 +40,9 @@ sealed trait MethodsContainer {
/** Type for which this container defines methods. */
def ownerType: STypeCompanion

override def toString: String =
getClass.getSimpleName.stripSuffix("$") // e.g. SInt, SCollection, etc

/** Represents class of `this`. */
lazy val thisRClass: RClass[_] = RClass(this.getClass)
def typeId: Byte = ownerType.typeId
Expand Down Expand Up @@ -102,7 +98,7 @@ sealed trait MethodsContainer {

}
object MethodsContainer {
val containers = new SparseArrayContainer[MethodsContainer](Array(
private val containers = new SparseArrayContainer[MethodsContainer](Array(
SByteMethods,
SShortMethods,
SIntMethods,
Expand All @@ -125,14 +121,21 @@ object MethodsContainer {
SAnyMethods
).map(m => (m.typeId, m)))

def contains(typeId: TypeCode): Boolean = containers.contains(typeId)

def apply(typeId: TypeCode): MethodsContainer = containers(typeId)

/** Finds the method of the give type.
*
* @param tpe type of the object for which the method is looked up
* @param methodName name of the method
* @return method descriptor or None if not found
*/
def getMethod(tpe: SProduct, methodName: String): Option[SMethod] = {
containers.get(tpe.typeCode).flatMap(_.method(methodName))
def getMethod(tpe: SType, methodName: String): Option[SMethod] = tpe match {
case tup: STuple =>
STupleMethods.getTupleMethod(tup, methodName)
case _ =>
containers.get(tpe.typeCode).flatMap(_.method(methodName))
}
}

Expand Down Expand Up @@ -958,6 +961,10 @@ object STupleMethods extends MethodsContainer {
/** Type for which this container defines methods. */
override def ownerType: STypeCompanion = STuple

private val MaxTupleLength: Int = SigmaConstants.MaxTupleLength.value

private val componentNames = Array.tabulate(MaxTupleLength) { i => s"_${i + 1}" }

/** A list of Coll methods inherited from Coll type and available as method of tuple. */
lazy val colMethods: Seq[SMethod] = {
val subst = Map(SType.tIV -> SAny)
Expand All @@ -968,6 +975,17 @@ object STupleMethods extends MethodsContainer {
}
}

def getTupleMethod(tup: STuple, name: String): Option[SMethod] = {
colMethods.find(_.name == name).orElse {
val iComponent = componentNames.lastIndexOf(name, end = tup.items.length - 1)
if (iComponent == -1) None
else
Some(SMethod(
STupleMethods, name, SFunc(tup, tup.items(iComponent)),
(iComponent + 1).toByte, SelectField.costKind))
}
}

override protected def getMethods(): Seq[SMethod] = super.getMethods()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class SigmaPPrintSpec extends SigmaDslTesting {
),
"""MethodCall.typed[Value[SCollection[SBox.type]]](
| ValUse(1, SContext),
| SContext.getMethodByName("dataInputs"),
| SContextMethods.getMethodByName("dataInputs"),
| Vector(),
| Map()
|)""".stripMargin)
Expand All @@ -172,7 +172,7 @@ class SigmaPPrintSpec extends SigmaDslTesting {
),
"""MethodCall.typed[Value[SCollection[SInt.type]]](
| ValUse(1, SCollectionType(SBox)),
| SCollection.getMethodByName("indices").withConcreteTypes(Map(STypeVar("IV") -> SBox)),
| SCollectionMethods.getMethodByName("indices").withConcreteTypes(Map(STypeVar("IV") -> SBox)),
| Vector(),
| Map()
|)""".stripMargin)
Expand Down
8 changes: 3 additions & 5 deletions sc/shared/src/main/scala/sigmastate/eval/TreeBuilding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -403,14 +403,12 @@ trait TreeBuilding extends SigmaLibrary { IR: IRContext =>
case Def(MethodCall(objSym, m, argSyms, _)) =>
val obj = recurse[SType](objSym)
val args = argSyms.collect { case argSym: Sym => recurse[SType](argSym) }
MethodsContainer.containers.get(obj.tpe.typeCode) match {
case Some(mc) =>
val method = mc.method(m.getName)
.getOrElse(error(s"Cannot find method ${m.getName} in object $obj"))
MethodsContainer.getMethod(obj.tpe, m.getName) match {
case Some(method) =>
val specMethod = method.specializeFor(obj.tpe, args.map(_.tpe))
builder.mkMethodCall(obj, specMethod, args.toIndexedSeq, Map())
case None =>
error(s"Cannot find methods container for type ${obj.tpe}")
error(s"Cannot find method ${m.getName} in object $obj")
}

case Def(d) =>
Expand Down
16 changes: 4 additions & 12 deletions sc/shared/src/main/scala/sigmastate/lang/SigmaTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,10 @@ class SigmaTyper(val builder: SigmaBuilder,
val newObj = assignType(env, obj)
newObj.tpe match {
case tNewObj: SProduct =>
val method = MethodsContainer.containers.get(tNewObj.typeCode) match {
case Some(mc) =>
val iField = mc.methodIndex(n)
if (iField != -1) {
mc.methods(iField)
} else
throw new MethodNotFound(
s"Cannot find method '$n' in in the object $obj of Product type with methods ${mc.methods}", obj.sourceContext.toOption)
case None =>
throw new MethodNotFound(
s"Cannot find methods container for type $tNewObj.", obj.sourceContext.toOption)
}
val method = MethodsContainer.getMethod(tNewObj, n).getOrElse(
throw new MethodNotFound(
s"Cannot find method '$n' in in the object $obj of Product type with methods",
obj.sourceContext.toOption))
val tMeth = method.stype
val tRes = tMeth match {
case SFunc(args, _, _) =>
Expand Down
7 changes: 3 additions & 4 deletions sc/shared/src/test/scala/sigma/SigmaDslSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4482,12 +4482,11 @@ class SigmaDslSpecification extends SigmaDslTesting
val tA = RType[A]
val typeName = tA.name
val stypeA = Evaluation.rtypeToSType(tA)
val typeCompanion = stypeA.asInstanceOf[STypeCompanion]
val mc = MethodsContainer.containers(typeCompanion.typeId)
val m = MethodsContainer.getMethod(stypeA, propName).get
existingFeature(scalaFunc,
s"{ (x: $typeName) => x.$propName }",
FuncValue(Vector((1, stypeA)),
MethodCall(ValUse(1, stypeA), mc.getMethodByName(propName), Vector(), Map() )
MethodCall(ValUse(1, stypeA), m, Vector(), Map() )
))
}

Expand Down Expand Up @@ -10033,7 +10032,7 @@ class SigmaDslSpecification extends SigmaDslTesting
// TODO v6.0: Add support of SFunc in TypeSerializer (see https://github.com/ScorexFoundation/sigmastate-interpreter/issues/847)
assertExceptionThrown(
f.verifyCase(Coll[Int](), Expected(Success(Coll[Int]()), 0)),
exceptionLike[MatchError]("(SInt$) => SInt$ (of class sigmastate.SFunc)")
exceptionLike[MatchError]("(SInt$) => SInt$ (of class sigma.ast.SFunc)")
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ class ErgoTreeSpecification extends SigmaDslTesting with ContractsTestkit {
case Some(tyDesc) =>
assert(canHaveMethods, s"Type $tyDesc should NOT have methods")

val mc = MethodsContainer.containers(tyDesc.typeId)
val mc = MethodsContainer(tyDesc.typeId)
mc.methods.length shouldBe methods.length
for (expectedMethod <- methods) {
if (expectedMethod.isResolvableFromIds) {
Expand Down
12 changes: 6 additions & 6 deletions sc/shared/src/test/scala/sigmastate/helpers/SigmaPPrint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,12 @@ object SigmaPPrint extends PPrinter {
Tree.Literal(s"FuncValue.AddToEnvironmentDesc")
case MethodDesc(method) =>
Tree.Apply("MethodDesc", Seq(methodLiteral(method)).iterator)
case sigmastate.SGlobalMethods =>
Tree.Literal(s"SGlobalMethods")
case sigmastate.SCollectionMethods =>
Tree.Literal(s"SCollectionMethods")
case sigmastate.SOptionMethods =>
Tree.Literal(s"SOptionMethods")
case SGlobal =>
Tree.Literal(s"SGlobal")
case SCollection =>
Tree.Literal(s"SCollection")
case SOption =>
Tree.Literal(s"SOption")
case t: STypeCompanion if t.isInstanceOf[SType] =>
Tree.Literal(s"S${t.typeName}")
case c: ValueCompanion =>
Expand Down
4 changes: 2 additions & 2 deletions sc/shared/src/test/scala/sigmastate/utils/SpecGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ trait SpecGen {
def collectMethods(): Seq[SMethod] = {
for {
tc <- typesWithMethods.sortBy(_.typeId)
mc = MethodsContainer.containers(tc.typeId)
mc = MethodsContainer(tc.typeId)
m <- mc.methods.sortBy(_.methodId)
} yield m
}
Expand Down Expand Up @@ -217,7 +217,7 @@ trait SpecGen {
}

def printMethods(tc: STypeCompanion) = {
val mc = MethodsContainer.containers(tc.typeId)
val mc = MethodsContainer(tc.typeId)
val methodSubsections = for { m <- mc.methods.sortBy(_.methodId) } yield {
methodSubsection(tc.typeName, m)
}
Expand Down

0 comments on commit d479754

Please sign in to comment.