From 4f94de8efe9b434725ad639deb18c88971ff3fe7 Mon Sep 17 00:00:00 2001 From: DieMyst Date: Mon, 30 Oct 2023 16:27:40 +0700 Subject: [PATCH] restrict `nil` and `[]` for assignment --- aqua-src/antithesis.aqua | 9 +++---- .../raw/ApplyPropertiesRawInliner.scala | 2 +- .../main/scala/aqua/raw/value/ValueRaw.scala | 1 + .../main/scala/aqua/parser/ParserError.scala | 4 ++-- .../parser/expr/func/AssignmentExpr.scala | 13 ++-------- .../aqua/semantics/expr/ArrowTypeSem.scala | 6 ++--- .../semantics/expr/func/AssignmentSem.scala | 24 ++++++------------- .../semantics/rules/names/NamesAlgebra.scala | 6 +++-- .../rules/names/NamesInterpreter.scala | 21 ++++++++++++++++ 9 files changed, 43 insertions(+), 43 deletions(-) diff --git a/aqua-src/antithesis.aqua b/aqua-src/antithesis.aqua index 731efd5b..ddd2312b 100644 --- a/aqua-src/antithesis.aqua +++ b/aqua-src/antithesis.aqua @@ -1,6 +1,3 @@ -alias Troll: u32 - -func test() -> i8: - MyAbility = Troll(f = "sf") - - <- 42 \ No newline at end of file +func z() -> string: + arr = nil + <- arr! \ No newline at end of file diff --git a/model/inline/src/main/scala/aqua/model/inline/raw/ApplyPropertiesRawInliner.scala b/model/inline/src/main/scala/aqua/model/inline/raw/ApplyPropertiesRawInliner.scala index f683fe01..34429411 100644 --- a/model/inline/src/main/scala/aqua/model/inline/raw/ApplyPropertiesRawInliner.scala +++ b/model/inline/src/main/scala/aqua/model/inline/raw/ApplyPropertiesRawInliner.scala @@ -343,7 +343,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi Some(IntoIndexRaw(idx, _), otherProperties) ) => unfold(vr).flatMap { - case (VarModel(nameVM, _, _), inl) => + case (VarModel(nameVM, _, _), _) => for { gateInlined <- unfoldStreamGate(nameVM, st, idx) (gateVM, gateInline) = gateInlined diff --git a/model/raw/src/main/scala/aqua/raw/value/ValueRaw.scala b/model/raw/src/main/scala/aqua/raw/value/ValueRaw.scala index 19abc606..6ac5ea23 100644 --- a/model/raw/src/main/scala/aqua/raw/value/ValueRaw.scala +++ b/model/raw/src/main/scala/aqua/raw/value/ValueRaw.scala @@ -34,6 +34,7 @@ object ValueRaw { val ParticleTimestamp: LiteralRaw = LiteralRaw("%timestamp%", ScalarType.u64) val Nil: LiteralRaw = LiteralRaw("[]", StreamType(BottomType)) + val VarNil: VarRaw = VarRaw("nil", StreamType(BottomType)) /** * Type of error value diff --git a/parser/src/main/scala/aqua/parser/ParserError.scala b/parser/src/main/scala/aqua/parser/ParserError.scala index b6f585dc..12d804d6 100644 --- a/parser/src/main/scala/aqua/parser/ParserError.scala +++ b/parser/src/main/scala/aqua/parser/ParserError.scala @@ -42,12 +42,12 @@ object ParserError { case WithContext(str, exp: WithContext) => expectationToString(exp, List(str)) case WithContext(str, exp) => s"$str (${expectationToString(exp)})" +: acc case FailWith(_, message) => message +: acc - case InRange(offset, lower, upper) => + case InRange(_, lower, upper) => if (lower == upper) s"Expected symbol '${betterSymbol(lower)}'" +: acc else s"Expected symbols from '${betterSymbol(lower)}' to '${betterSymbol(upper)}'" +: acc - case OneOfStr(offset, strs) => + case OneOfStr(_, strs) => s"Expected one of these strings: ${strs.map(s => s"'$s'").mkString(", ")}" +: acc case e => ("Expected: " + e.toString) +: acc } diff --git a/parser/src/main/scala/aqua/parser/expr/func/AssignmentExpr.scala b/parser/src/main/scala/aqua/parser/expr/func/AssignmentExpr.scala index 050fca33..3ae5028a 100644 --- a/parser/src/main/scala/aqua/parser/expr/func/AssignmentExpr.scala +++ b/parser/src/main/scala/aqua/parser/expr/func/AssignmentExpr.scala @@ -20,16 +20,7 @@ case class AssignmentExpr[F[_]]( object AssignmentExpr extends Expr.Leaf { override val p: P[AssignmentExpr[Span.S]] = - ((Name.variable <* ` = `).with1 ~ ValueToken.`value`).flatMap { case (variable, value) => - value match { - case CollectionToken(_, values) => - if (values.isEmpty) - P.failWith( - "Assigning empty array to a variable is prohibited. You can create an array with values (like '[a, b, c]') or use '[]' in place." - ) - else P.pure(AssignmentExpr(variable, value)) - case _ => - P.pure(AssignmentExpr(variable, value)) - } + ((Name.variable <* ` = `).with1 ~ ValueToken.`value`).map { case (variable, value) => + AssignmentExpr(variable, value) } } diff --git a/semantics/src/main/scala/aqua/semantics/expr/ArrowTypeSem.scala b/semantics/src/main/scala/aqua/semantics/expr/ArrowTypeSem.scala index 4fb30b60..d62c0b83 100644 --- a/semantics/src/main/scala/aqua/semantics/expr/ArrowTypeSem.scala +++ b/semantics/src/main/scala/aqua/semantics/expr/ArrowTypeSem.scala @@ -3,19 +3,17 @@ package aqua.semantics.expr import aqua.parser.expr.ArrowTypeExpr import aqua.raw.{Raw, TypeRaw} import aqua.semantics.Prog -import aqua.semantics.rules.abilities.AbilitiesAlgebra import aqua.semantics.rules.definitions.DefinitionsAlgebra import aqua.semantics.rules.types.TypesAlgebra -import cats.syntax.functor.* +import cats.Monad import cats.syntax.applicative.* import cats.syntax.flatMap.* -import cats.Monad +import cats.syntax.functor.* class ArrowTypeSem[S[_]](val expr: ArrowTypeExpr[S]) extends AnyVal { def program[Alg[_]: Monad](implicit T: TypesAlgebra[S, Alg], - A: AbilitiesAlgebra[S, Alg], D: DefinitionsAlgebra[S, Alg] ): Prog[Alg, Raw] = T.resolveArrowDef(expr.`type`).flatMap { diff --git a/semantics/src/main/scala/aqua/semantics/expr/func/AssignmentSem.scala b/semantics/src/main/scala/aqua/semantics/expr/func/AssignmentSem.scala index 6f401e61..514caed4 100644 --- a/semantics/src/main/scala/aqua/semantics/expr/func/AssignmentSem.scala +++ b/semantics/src/main/scala/aqua/semantics/expr/func/AssignmentSem.scala @@ -1,11 +1,9 @@ package aqua.semantics.expr.func -import aqua.raw.Raw -import aqua.types.ArrowType -import aqua.raw.value.CallArrowRaw -import aqua.raw.ops.AssignmentTag import aqua.parser.expr.func.AssignmentExpr -import aqua.raw.arrow.FuncRaw +import aqua.raw.Raw +import aqua.raw.ops.AssignmentTag +import aqua.raw.value.ValueRaw import aqua.semantics.Prog import aqua.semantics.rules.ValuesAlgebra import aqua.semantics.rules.names.NamesAlgebra @@ -22,18 +20,10 @@ class AssignmentSem[S[_]](val expr: AssignmentExpr[S]) extends AnyVal { ): Prog[Alg, Raw] = V.valueToRaw(expr.value).flatMap { case Some(vm) => - vm.`type` match { - case at @ ArrowType(_, _) => - N.defineArrow(expr.variable, at, false) as (AssignmentTag( - vm, - expr.variable.value - ).funcOpLeaf: Raw) - case _ => - N.derive(expr.variable, vm.`type`, vm.varNames) as (AssignmentTag( - vm, - expr.variable.value - ).funcOpLeaf: Raw) - } + N.assign(expr.variable, vm) as (AssignmentTag( + vm, + expr.variable.value + ).funcOpLeaf: Raw) case _ => Raw.error("Cannot resolve assignment type").pure[Alg] } diff --git a/semantics/src/main/scala/aqua/semantics/rules/names/NamesAlgebra.scala b/semantics/src/main/scala/aqua/semantics/rules/names/NamesAlgebra.scala index 132f7d80..57e41b05 100644 --- a/semantics/src/main/scala/aqua/semantics/rules/names/NamesAlgebra.scala +++ b/semantics/src/main/scala/aqua/semantics/rules/names/NamesAlgebra.scala @@ -1,8 +1,8 @@ package aqua.semantics.rules.names -import aqua.parser.lexer.{LiteralToken, Name, Token, ValueToken} +import aqua.parser.lexer.{Name, Token} +import aqua.raw.value.ValueRaw import aqua.types.{ArrowType, StreamType, Type} -import cats.InjectK trait NamesAlgebra[S[_], Alg[_]] { @@ -21,6 +21,8 @@ trait NamesAlgebra[S[_], Alg[_]] { def defineConstant(name: Name[S], `type`: Type): Alg[Boolean] + def assign(name: Name[S], value: ValueRaw): Alg[Boolean] + def defineArrow(name: Name[S], gen: ArrowType, isRoot: Boolean): Alg[Boolean] def streamsDefinedWithinScope(): Alg[Map[String, StreamType]] diff --git a/semantics/src/main/scala/aqua/semantics/rules/names/NamesInterpreter.scala b/semantics/src/main/scala/aqua/semantics/rules/names/NamesInterpreter.scala index bd718aea..7ed42320 100644 --- a/semantics/src/main/scala/aqua/semantics/rules/names/NamesInterpreter.scala +++ b/semantics/src/main/scala/aqua/semantics/rules/names/NamesInterpreter.scala @@ -1,6 +1,7 @@ package aqua.semantics.rules.names import aqua.parser.lexer.{Name, Token} +import aqua.raw.value.{ValueRaw, VarRaw} import aqua.semantics.Levenshtein import aqua.semantics.rules.StackInterpreter import aqua.semantics.rules.report.ReportAlgebra @@ -131,6 +132,26 @@ class NamesInterpreter[S[_], X](using ).as(true) }.flatTap(_ => locations.addToken(name.value, name)) + override def assign(name: Name[S], value: ValueRaw): SX[Boolean] = + value match { + case ValueRaw.Nil | ValueRaw.VarNil => + report + .error( + name, + "Assigning empty array or 'nil' to a variable is prohibited. " + + "You can create an array with values (like '[a, b, c]') or use '[]' in place." + ) + .as(false) + case _ => + value.`type` match { + case at@ArrowType(_, _) => + defineArrow(name, at, false) + case _ => + derive(name, value.`type`, value.varNames) + } + + } + override def defineArrow(name: Name[S], arrowType: ArrowType, isRoot: Boolean): SX[Boolean] = readName(name.value).flatMap { case Some(_) =>