From 32790fc5f295e9ee5b8cff4d43f02e4f365e0c57 Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Tue, 14 Aug 2018 15:31:05 +0300 Subject: [PATCH 1/6] Aded Set support for PrismLang --- .../prismlang/compiler/StaticAnalyser.scala | 21 +++++++++++++++++++ .../prismlang/compiler/Transformer.scala | 1 + .../encryfoundation/prismlang/core/Ast.scala | 2 ++ .../prismlang/core/TypeSystem.scala | 3 +++ .../prismlang/core/Types.scala | 18 ++++++++++++++++ .../prismlang/core/wrapped/PValue.scala | 1 + .../prismlang/evaluator/Evaluator.scala | 1 + .../prismlang/parser/Expressions.scala | 3 +++ .../integration/SyntaxConstructionsSpec.scala | 18 ++++++++++++++++ 9 files changed, 68 insertions(+) diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala index 0b559a7..44b1dad 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala @@ -23,6 +23,7 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex scanSimpleExpr orElse scanRef orElse scanCollection orElse + scanSet orElse scanConstant orElse scanTransformers orElse pass @@ -196,11 +197,26 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex eltsS.foreach(elt => matchType(eltsS.head.tpe, elt.tpe, Some(s"Collection is inconsistent, ${elt.tpe} stands out."))) eltsS.head.tpe match { case Types.PCollection(inT) if inT.isCollection => error("Illegal level of nesting") + case Types.PSet(inT) if inT.isCollection => error("Illegal level of nesting") case _ => // Do nothing } coll.copy(eltsS, computeType(coll.copy(eltsS))) } + def scanSet: Scan = { + case set @ Expr.Set(elts, _) => + if (elts.size > Constants.CollMaxLength) error(s"Set size limit overflow (${elts.size} > ${Constants.CollMaxLength})") + else if (elts.size < 1) error("Empty set") + val eltsS: Set[Expr] = elts.map(scan) + eltsS.foreach(elt => matchType(eltsS.head.tpe, elt.tpe, Some(s"Set is inconsistent, ${elt.tpe} stands out."))) + eltsS.head.tpe match { + case Types.PCollection(inT) if inT.isCollection => error("Illegal level of nesting") + case Types.PSet(inT) if inT.isCollection => error("Illegal level of nesting") + case _ => // Do nothing + } + set.copy(eltsS, computeType(set.copy(eltsS))) + } + def scanConstant: Scan = { /** Scan each element of tuple ensuring its actual size does not * overflow `TupleMaxLength`, then check type consistency of all elements. */ @@ -305,6 +321,10 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex case _: SliceOp.Index => inT case _: SliceOp.Slice => coll } + case set @ Types.PSet(inT) => op match { + case _: SliceOp.Index => inT + case _: SliceOp.Slice => set + } case otherT => error(s"$otherT does not support subscription") } case Expr.Unary(_, operand, _) => computeType(operand) @@ -313,6 +333,7 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex case Expr.Lambda(args, body, _) => Types.PFunc(types.resolveArgs(args), computeType(body)) case Expr.Tuple(elts, _) => Types.PTuple(elts.map(elt => computeType(elt))) case Expr.Collection(elts, _) => Types.PCollection(computeType(elts.head)) + case Expr.Set(elts, _) => Types.PSet(computeType(elts.head)) case Expr.Map(_, func, _) => computeType(func) match { case Types.PFunc(_, retT) => Types.PCollection(retT) case otherT => error(s"$otherT is not a function") diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala index 7ff5aa7..d23d566 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala @@ -57,6 +57,7 @@ object Transformer { case sub @ Expr.Subscript(value, _, _) => sub.copy(transform(value)) case coll @ Expr.Collection(elts, _) => coll.copy(elts.map(transform)) + case set @ Expr.Set(elts, _) => set.copy(elts.map(transform)) case tuple @ Expr.Tuple(elts, _) => tuple.copy(elts.map(transform)) case other => other diff --git a/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala b/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala index 3bd5bee..424de8a 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala @@ -58,6 +58,8 @@ object Ast { case class Collection(elts: List[Expr], override val tpe: PType = Nit) extends Expr + case class Set(elts: scala.collection.immutable.Set[Expr], override val tpe: PType = Nit) extends Expr + case class Tuple(elts: List[Expr], override val tpe: PType = Nit) extends Expr case class Base58Str(value: String) extends Expr { override val tpe: PType = PCollection.ofByte } diff --git a/src/main/scala/org/encryfoundation/prismlang/core/TypeSystem.scala b/src/main/scala/org/encryfoundation/prismlang/core/TypeSystem.scala index e4be986..55bdfbf 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/TypeSystem.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/TypeSystem.scala @@ -19,6 +19,9 @@ case class TypeSystem(additionalTypes: Seq[Types.PType]) { def resolveType(ident: TypeIdent): Types.PType = { val typeParams: List[Types.PType] = ident.typeParams.map(resolveType) typeByIdent(ident.name).map { + case Types.PSet(_) => + if (typeParams.size == 1) Types.PSet(typeParams.head) + else throw TypeSystemException("'Set[T]' takes exactly one type parameter") case Types.PCollection(_) => if (typeParams.size == 1) Types.PCollection(typeParams.head) else throw TypeSystemException("'Array[T]' takes exactly one type parameter") diff --git a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala index 0d9ee30..f9cae0f 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala @@ -118,6 +118,24 @@ object Types { val ofString: PCollection = PCollection(PString) } + case class PSet(valT : PType) extends PType with Parametrized{ + override type Underlying = Set[valT.Underlying] + override val ident: String = "Set" + override val isCollection: Boolean = true + override val dataCost: Int = 10 * valT.dataCost + + override def isApplicable(func: PFunc): Boolean = + func.args.size == 1 && (valT.isSubtypeOf(func.args.head._2) || valT == func.args.head._2) + + override def equals(obj: Any): Boolean = obj match { + case set: PCollection => + set.valT == this.valT || set.valT.isSubtypeOf(this.valT) || set.valT.canBeDerivedTo(this.valT) + case tag: TaggedType if tag.isCollection => tag.underlyingType == this + case _ => false + } + } + + case class PFunc(args: List[(String, PType)], retT: PType) extends PType { override type Underlying = PFunction override val ident: String = "Func" diff --git a/src/main/scala/org/encryfoundation/prismlang/core/wrapped/PValue.scala b/src/main/scala/org/encryfoundation/prismlang/core/wrapped/PValue.scala index 1408aa5..d05bdab 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/wrapped/PValue.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/wrapped/PValue.scala @@ -19,6 +19,7 @@ object PValue { new PValue { override val tpe: Types.PType = t override val value: tpe.Underlying = (v match { + case set: Set[_] if t.isCollection => set.toList case arr: Array[_] if t.isCollection => arr.toList case seq: Seq[_] if t.isCollection => seq.toList case int: Int if t.isNumeric => int.toLong diff --git a/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala b/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala index b30cb5a..5ed377a 100644 --- a/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala +++ b/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala @@ -206,6 +206,7 @@ case class Evaluator(initialEnv: ScopedRuntimeEnvironment, types: TypeSystem) { } case Expr.Collection(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) case Expr.Tuple(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) + case Expr.Set(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) case Expr.Base58Str(value) => Base58.decode(value).map(_.toList).getOrElse(error("Base58 string decoding failed")) case Expr.Base16Str(value) => Base16.decode(value).map(_.toList).getOrElse(error("Base16 string decoding failed")) diff --git a/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala b/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala index f881a4e..425e2bd 100644 --- a/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala +++ b/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala @@ -72,6 +72,8 @@ object Expressions { } } + val setContents: noApi.Parser[Seq[Ast.Expr]] = P( test.rep(1, "," ~ LineBreak.?) ~ ",".? ~ LineBreak.? ) + val set: core.Parser[Ast.Expr.Set, Char, String] = P( setContents ).map(exps => Ast.Expr.Set(exps.toSet)) val listContents: noApi.Parser[Seq[Ast.Expr]] = P( test.rep(1, "," ~ LineBreak.?) ~ ",".? ~ LineBreak.? ) val list: core.Parser[Ast.Expr.Collection, Char, String] = P( listContents ).map(exps => Ast.Expr.Collection(exps.toList)) val tupleContents: core.Parser[Seq[Ast.Expr], Char, String] = P( test ~ "," ~ listContents.?).map { case (head, rest) => head +: rest.getOrElse(Seq.empty) } @@ -81,6 +83,7 @@ object Expressions { P( "(" ~ LineBreak.? ~ (tuple | expr) ~ ")" | "Array(" ~ LineBreak.? ~ list ~ ")" | + "Set(" ~ LineBreak.? ~ set ~ ")" | BASE58STRING.rep(1).map(_.mkString).map(Ast.Expr.Base58Str) | BASE16STRING.rep(1).map(_.mkString).map(Ast.Expr.Base16Str) | STRING.rep(1).map(_.mkString).map(Ast.Expr.Str) | diff --git a/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala b/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala index f3bc2dc..6fa722c 100644 --- a/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala +++ b/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala @@ -84,6 +84,24 @@ class SyntaxConstructionsSpec extends PropSpec with Utils { evaluationSuccess = Option(true), expectedValue = Option(longMin)) } + property("Set construction") { + val toByteCast = + """ + { + let a = 1 + let b = 1 + let c = 1 + let d = 1 + let e = 6 + let g = Set(a,b,c,d,e) + g[1] + g[0] + } + """.stripMargin + + testCompiledExpressionWithOptionalEvaluation(toByteCast, compilationSuccess = true, + evaluationSuccess = Option(true), expectedValue = Option(7)) + } + property("Int Lower Boundary check") { val longMax = Long.MaxValue val letLongMaxNumber = From 727a556834bfd8cba16c4cf3ff5e048e329115ba Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Tue, 14 Aug 2018 15:36:37 +0300 Subject: [PATCH 2/6] removed emptu line --- src/main/scala/org/encryfoundation/prismlang/core/Types.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala index f9cae0f..9fc5bc8 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala @@ -135,7 +135,6 @@ object Types { } } - case class PFunc(args: List[(String, PType)], retT: PType) extends PType { override type Underlying = PFunction override val ident: String = "Func" From f445ae24743cd6cc380e01ebd12c609271bd472d Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Tue, 14 Aug 2018 15:46:46 +0300 Subject: [PATCH 3/6] minor refactoring --- .../encryfoundation/prismlang/compiler/StaticAnalyser.scala | 2 +- .../prismlang/integration/SyntaxConstructionsSpec.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala index 44b1dad..9f9c567 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala @@ -212,7 +212,7 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex eltsS.head.tpe match { case Types.PCollection(inT) if inT.isCollection => error("Illegal level of nesting") case Types.PSet(inT) if inT.isCollection => error("Illegal level of nesting") - case _ => // Do nothing + case _ => } set.copy(eltsS, computeType(set.copy(eltsS))) } diff --git a/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala b/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala index 6fa722c..74ac55a 100644 --- a/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala +++ b/src/test/scala/org/encryfoundation/prismlang/integration/SyntaxConstructionsSpec.scala @@ -85,7 +85,7 @@ class SyntaxConstructionsSpec extends PropSpec with Utils { } property("Set construction") { - val toByteCast = + val setConstruction = """ { let a = 1 @@ -98,7 +98,7 @@ class SyntaxConstructionsSpec extends PropSpec with Utils { } """.stripMargin - testCompiledExpressionWithOptionalEvaluation(toByteCast, compilationSuccess = true, + testCompiledExpressionWithOptionalEvaluation(setConstruction, compilationSuccess = true, evaluationSuccess = Option(true), expectedValue = Option(7)) } From 352bcde7d7e88bba405f30146ab260eeaaefa123 Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Wed, 15 Aug 2018 10:53:08 +0300 Subject: [PATCH 4/6] pain --- .../prismlang/codec/PCodec.scala | 49 ++++++++++--------- .../prismlang/compiler/CostEstimator.scala | 1 + .../prismlang/compiler/Transformer.scala | 2 + .../prismlang/core/Types.scala | 13 +++-- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala b/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala index 256a348..75805c4 100644 --- a/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala +++ b/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala @@ -18,19 +18,21 @@ object PCodec { implicit def dString = dT.bind[PString.type](4) implicit def dByte = dT.bind[PByte.type](5) implicit def dColl = dT.bind[PCollection](6) - implicit def dFunc = dT.bind[PFunc](7) - implicit def dTuple = dT.bind[PTuple](8) - implicit def dObj = dT.bind[ArbitraryProduct](9) - implicit def dStructTag = dT.bind[StructTag](10) - implicit def dSig = dT.bind[Signature25519.type](11) - implicit def dMulSig = dT.bind[MultiSig.type](12) - implicit def dEncryBox = dT.bind[EncryBox.type](13) - implicit def dAssetBox = dT.bind[AssetBox.type](14) - implicit def dAiBox = dT.bind[AssetIssuingBox.type](15) - implicit def dDBox = dT.bind[DataBox.type](16) - implicit def dTransact = dT.bind[EncryTransaction.type](17) - implicit def dState = dT.bind[EncryState.type](18) - implicit def dNit = dT.bind[Nit.type](19) + implicit def dSet = dT.bind[PSet](7) + implicit def dFunc = dT.bind[PFunc](8) + implicit def dTuple = dT.bind[PTuple](9) + implicit def dObj = dT.bind[ArbitraryProduct](10) + implicit def dStructTag = dT.bind[StructTag](11) + implicit def dSig = dT.bind[Signature25519.type](12) + implicit def dMulSig = dT.bind[MultiSig.type](13) + implicit def dEncryBox = dT.bind[EncryBox.type](14) + implicit def dAssetBox = dT.bind[AssetBox.type](15) + implicit def dAiBox = dT.bind[AssetIssuingBox.type](16) + implicit def dDBox = dT.bind[DataBox.type](17) + implicit def dTransact = dT.bind[EncryTransaction.type](18) + implicit def dState = dT.bind[EncryState.type](19) + implicit def dNit = dT.bind[Nit.type](20) + implicit def dExp = Discriminated[Expr, Int](uint8) implicit def dBlc = dExp.bind[Expr.Block](0) @@ -52,16 +54,17 @@ object PCodec { implicit def dByteConst = dExp.bind[Expr.ByteConst](16) implicit def dStr = dExp.bind[Expr.Str](17) implicit def dCollConst = dExp.bind[Expr.Collection](18) - implicit def dTupleConst = dExp.bind[Expr.Tuple](19) - implicit def dBase58Str = dExp.bind[Expr.Base58Str](20) - implicit def dBase16Str = dExp.bind[Expr.Base16Str](21) - implicit def dTrue = dExp.bind[Expr.True.type](22) - implicit def dFalse = dExp.bind[Expr.False.type](23) - implicit def dSizeOf = dExp.bind[Expr.SizeOf](24) - implicit def dExists = dExp.bind[Expr.Exists](25) - implicit def dSum = dExp.bind[Expr.Sum](26) - implicit def dMap = dExp.bind[Expr.Map](27) - implicit def dFilt = dExp.bind[Expr.Filter](28) + implicit def dSetConst = dExp.bind[Expr.Set](19) + implicit def dTupleConst = dExp.bind[Expr.Tuple](20) + implicit def dBase58Str = dExp.bind[Expr.Base58Str](21) + implicit def dBase16Str = dExp.bind[Expr.Base16Str](22) + implicit def dTrue = dExp.bind[Expr.True.type](23) + implicit def dFalse = dExp.bind[Expr.False.type](24) + implicit def dSizeOf = dExp.bind[Expr.SizeOf](25) + implicit def dExists = dExp.bind[Expr.Exists](26) + implicit def dSum = dExp.bind[Expr.Sum](27) + implicit def dMap = dExp.bind[Expr.Map](28) + implicit def dFilt = dExp.bind[Expr.Filter](29) implicit def dNode = Discriminated[Node, Int](uint2) implicit def dModule = dNode.bind[Module](0) diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala index 27fca76..809fdd0 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala @@ -57,6 +57,7 @@ case class CostEstimator(initialEnv: Map[String, Int]) { } def costOfConst: Cost = { + //case Expr.Set(elts, _) => case Expr.Collection(elts, _) => CollEltC * elts.length + elts.map(costOf).sum case Expr.Tuple(elts, _) => TupleEltC * elts.length + elts.map(costOf).sum case Expr.Base58Str(value) => CharC * value.length + DecodingC diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala index d23d566..b18dc1a 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala @@ -57,7 +57,9 @@ object Transformer { case sub @ Expr.Subscript(value, _, _) => sub.copy(transform(value)) case coll @ Expr.Collection(elts, _) => coll.copy(elts.map(transform)) + case set @ Expr.Set(elts, _) => set.copy(elts.map(transform)) + case tuple @ Expr.Tuple(elts, _) => tuple.copy(elts.map(transform)) case other => other diff --git a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala index 9fc5bc8..28cf49b 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/Types.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/Types.scala @@ -118,7 +118,7 @@ object Types { val ofString: PCollection = PCollection(PString) } - case class PSet(valT : PType) extends PType with Parametrized{ + case class PSet(valT : PType) extends PType with Parametrized { override type Underlying = Set[valT.Underlying] override val ident: String = "Set" override val isCollection: Boolean = true @@ -128,12 +128,19 @@ object Types { func.args.size == 1 && (valT.isSubtypeOf(func.args.head._2) || valT == func.args.head._2) override def equals(obj: Any): Boolean = obj match { - case set: PCollection => + case set: PSet => set.valT == this.valT || set.valT.isSubtypeOf(this.valT) || set.valT.canBeDerivedTo(this.valT) case tag: TaggedType if tag.isCollection => tag.underlyingType == this case _ => false } } + object PSet { + val ofByte: PSet = PSet(PByte) + val ofByteArrays: PSet = PSet(PSet(PByte)) + val ofInt: PSet = PSet(PInt) + val ofBool: PSet = PSet(PBoolean) + val ofString: PSet = PSet(PString) + } case class PFunc(args: List[(String, PType)], retT: PType) extends PType { override type Underlying = PFunction @@ -345,7 +352,7 @@ object Types { /** All types with type parameters including `PTuple` instances * of all possible dimensions. */ val parametrizedTypes: List[Parametrized] = List( - PCollection(Nit) + PCollection(Nit), PSet(Nit) ) ++ (1 to Constants.TupleMaxDim).map(i => PTuple((1 to i).map(_ => Nit).toList)) val productTypes: List[Product] = List( From 0c0cde7bea4df4ec0ea53f35543f2b47b2542d4a Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Wed, 15 Aug 2018 11:32:38 +0300 Subject: [PATCH 5/6] finallly working set --- .../scala/org/encryfoundation/prismlang/codec/PCodec.scala | 2 +- .../encryfoundation/prismlang/compiler/StaticAnalyser.scala | 6 +++--- .../encryfoundation/prismlang/compiler/Transformer.scala | 2 +- src/main/scala/org/encryfoundation/prismlang/core/Ast.scala | 2 +- .../org/encryfoundation/prismlang/evaluator/Evaluator.scala | 2 +- .../org/encryfoundation/prismlang/parser/Expressions.scala | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala b/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala index 75805c4..394206c 100644 --- a/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala +++ b/src/main/scala/org/encryfoundation/prismlang/codec/PCodec.scala @@ -54,7 +54,7 @@ object PCodec { implicit def dByteConst = dExp.bind[Expr.ByteConst](16) implicit def dStr = dExp.bind[Expr.Str](17) implicit def dCollConst = dExp.bind[Expr.Collection](18) - implicit def dSetConst = dExp.bind[Expr.Set](19) + implicit def dSetConst = dExp.bind[Expr.PrismSet](19) implicit def dTupleConst = dExp.bind[Expr.Tuple](20) implicit def dBase58Str = dExp.bind[Expr.Base58Str](21) implicit def dBase16Str = dExp.bind[Expr.Base16Str](22) diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala index 9f9c567..06b546c 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/StaticAnalyser.scala @@ -204,10 +204,10 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex } def scanSet: Scan = { - case set @ Expr.Set(elts, _) => + case set @ Expr.PrismSet(elts, _) => if (elts.size > Constants.CollMaxLength) error(s"Set size limit overflow (${elts.size} > ${Constants.CollMaxLength})") else if (elts.size < 1) error("Empty set") - val eltsS: Set[Expr] = elts.map(scan) + val eltsS: List[Expr] = elts.map(scan).distinct eltsS.foreach(elt => matchType(eltsS.head.tpe, elt.tpe, Some(s"Set is inconsistent, ${elt.tpe} stands out."))) eltsS.head.tpe match { case Types.PCollection(inT) if inT.isCollection => error("Illegal level of nesting") @@ -333,7 +333,7 @@ case class StaticAnalyser(initialScope: ScopedSymbolTable, types: TypeSystem) ex case Expr.Lambda(args, body, _) => Types.PFunc(types.resolveArgs(args), computeType(body)) case Expr.Tuple(elts, _) => Types.PTuple(elts.map(elt => computeType(elt))) case Expr.Collection(elts, _) => Types.PCollection(computeType(elts.head)) - case Expr.Set(elts, _) => Types.PSet(computeType(elts.head)) + case Expr.PrismSet(elts, _) => Types.PSet(computeType(elts.head)) case Expr.Map(_, func, _) => computeType(func) match { case Types.PFunc(_, retT) => Types.PCollection(retT) case otherT => error(s"$otherT is not a function") diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala index b18dc1a..8f02f84 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/Transformer.scala @@ -58,7 +58,7 @@ object Transformer { case coll @ Expr.Collection(elts, _) => coll.copy(elts.map(transform)) - case set @ Expr.Set(elts, _) => set.copy(elts.map(transform)) + case set @ Expr.PrismSet(elts, _) => set.copy(elts.map(transform)) case tuple @ Expr.Tuple(elts, _) => tuple.copy(elts.map(transform)) diff --git a/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala b/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala index 424de8a..95036af 100644 --- a/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala +++ b/src/main/scala/org/encryfoundation/prismlang/core/Ast.scala @@ -58,7 +58,7 @@ object Ast { case class Collection(elts: List[Expr], override val tpe: PType = Nit) extends Expr - case class Set(elts: scala.collection.immutable.Set[Expr], override val tpe: PType = Nit) extends Expr + case class PrismSet(elts: List[Expr], override val tpe: PType = Nit) extends Expr case class Tuple(elts: List[Expr], override val tpe: PType = Nit) extends Expr diff --git a/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala b/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala index 5ed377a..017c97d 100644 --- a/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala +++ b/src/main/scala/org/encryfoundation/prismlang/evaluator/Evaluator.scala @@ -206,7 +206,7 @@ case class Evaluator(initialEnv: ScopedRuntimeEnvironment, types: TypeSystem) { } case Expr.Collection(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) case Expr.Tuple(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) - case Expr.Set(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)) + case Expr.PrismSet(elts, _) => elts.map(elt => eval[elt.tpe.Underlying](elt)).toSet case Expr.Base58Str(value) => Base58.decode(value).map(_.toList).getOrElse(error("Base58 string decoding failed")) case Expr.Base16Str(value) => Base16.decode(value).map(_.toList).getOrElse(error("Base16 string decoding failed")) diff --git a/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala b/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala index 425e2bd..bc2ae32 100644 --- a/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala +++ b/src/main/scala/org/encryfoundation/prismlang/parser/Expressions.scala @@ -73,7 +73,7 @@ object Expressions { } val setContents: noApi.Parser[Seq[Ast.Expr]] = P( test.rep(1, "," ~ LineBreak.?) ~ ",".? ~ LineBreak.? ) - val set: core.Parser[Ast.Expr.Set, Char, String] = P( setContents ).map(exps => Ast.Expr.Set(exps.toSet)) + val set: core.Parser[Ast.Expr.PrismSet, Char, String] = P( setContents ).map(exps => Ast.Expr.PrismSet(exps.toList)) val listContents: noApi.Parser[Seq[Ast.Expr]] = P( test.rep(1, "," ~ LineBreak.?) ~ ",".? ~ LineBreak.? ) val list: core.Parser[Ast.Expr.Collection, Char, String] = P( listContents ).map(exps => Ast.Expr.Collection(exps.toList)) val tupleContents: core.Parser[Seq[Ast.Expr], Char, String] = P( test ~ "," ~ listContents.?).map { case (head, rest) => head +: rest.getOrElse(Seq.empty) } From 0daa295eb95d426e38884b93a1eb6704f2d5edd6 Mon Sep 17 00:00:00 2001 From: ugulavaGeorge Date: Wed, 15 Aug 2018 11:39:14 +0300 Subject: [PATCH 6/6] Set cost added in estimator --- .../org/encryfoundation/prismlang/compiler/CostEstimator.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala b/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala index 809fdd0..c5884e8 100644 --- a/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala +++ b/src/main/scala/org/encryfoundation/prismlang/compiler/CostEstimator.scala @@ -57,7 +57,7 @@ case class CostEstimator(initialEnv: Map[String, Int]) { } def costOfConst: Cost = { - //case Expr.Set(elts, _) => + case Expr.PrismSet(elts, _) => CollEltC * elts.length + elts.map(costOf).sum case Expr.Collection(elts, _) => CollEltC * elts.length + elts.map(costOf).sum case Expr.Tuple(elts, _) => TupleEltC * elts.length + elts.map(costOf).sum case Expr.Base58Str(value) => CharC * value.length + DecodingC