restrict nil and [] for assignment

This commit is contained in:
DieMyst 2023-10-30 16:27:40 +07:00
parent 38f77285f5
commit 4f94de8efe
9 changed files with 43 additions and 43 deletions

View File

@ -1,6 +1,3 @@
alias Troll: u32 func z() -> string:
arr = nil
func test() -> i8: <- arr!
MyAbility = Troll(f = "sf")
<- 42

View File

@ -343,7 +343,7 @@ object ApplyPropertiesRawInliner extends RawInliner[ApplyPropertyRaw] with Loggi
Some(IntoIndexRaw(idx, _), otherProperties) Some(IntoIndexRaw(idx, _), otherProperties)
) => ) =>
unfold(vr).flatMap { unfold(vr).flatMap {
case (VarModel(nameVM, _, _), inl) => case (VarModel(nameVM, _, _), _) =>
for { for {
gateInlined <- unfoldStreamGate(nameVM, st, idx) gateInlined <- unfoldStreamGate(nameVM, st, idx)
(gateVM, gateInline) = gateInlined (gateVM, gateInline) = gateInlined

View File

@ -34,6 +34,7 @@ object ValueRaw {
val ParticleTimestamp: LiteralRaw = LiteralRaw("%timestamp%", ScalarType.u64) val ParticleTimestamp: LiteralRaw = LiteralRaw("%timestamp%", ScalarType.u64)
val Nil: LiteralRaw = LiteralRaw("[]", StreamType(BottomType)) val Nil: LiteralRaw = LiteralRaw("[]", StreamType(BottomType))
val VarNil: VarRaw = VarRaw("nil", StreamType(BottomType))
/** /**
* Type of error value * Type of error value

View File

@ -42,12 +42,12 @@ object ParserError {
case WithContext(str, exp: WithContext) => expectationToString(exp, List(str)) case WithContext(str, exp: WithContext) => expectationToString(exp, List(str))
case WithContext(str, exp) => s"$str (${expectationToString(exp)})" +: acc case WithContext(str, exp) => s"$str (${expectationToString(exp)})" +: acc
case FailWith(_, message) => message +: acc case FailWith(_, message) => message +: acc
case InRange(offset, lower, upper) => case InRange(_, lower, upper) =>
if (lower == upper) if (lower == upper)
s"Expected symbol '${betterSymbol(lower)}'" +: acc s"Expected symbol '${betterSymbol(lower)}'" +: acc
else else
s"Expected symbols from '${betterSymbol(lower)}' to '${betterSymbol(upper)}'" +: acc 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 s"Expected one of these strings: ${strs.map(s => s"'$s'").mkString(", ")}" +: acc
case e => ("Expected: " + e.toString) +: acc case e => ("Expected: " + e.toString) +: acc
} }

View File

@ -20,16 +20,7 @@ case class AssignmentExpr[F[_]](
object AssignmentExpr extends Expr.Leaf { object AssignmentExpr extends Expr.Leaf {
override val p: P[AssignmentExpr[Span.S]] = override val p: P[AssignmentExpr[Span.S]] =
((Name.variable <* ` = `).with1 ~ ValueToken.`value`).flatMap { case (variable, value) => ((Name.variable <* ` = `).with1 ~ ValueToken.`value`).map { case (variable, value) =>
value match { AssignmentExpr(variable, value)
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))
}
} }
} }

View File

@ -3,19 +3,17 @@ package aqua.semantics.expr
import aqua.parser.expr.ArrowTypeExpr import aqua.parser.expr.ArrowTypeExpr
import aqua.raw.{Raw, TypeRaw} import aqua.raw.{Raw, TypeRaw}
import aqua.semantics.Prog import aqua.semantics.Prog
import aqua.semantics.rules.abilities.AbilitiesAlgebra
import aqua.semantics.rules.definitions.DefinitionsAlgebra import aqua.semantics.rules.definitions.DefinitionsAlgebra
import aqua.semantics.rules.types.TypesAlgebra import aqua.semantics.rules.types.TypesAlgebra
import cats.syntax.functor.* import cats.Monad
import cats.syntax.applicative.* import cats.syntax.applicative.*
import cats.syntax.flatMap.* import cats.syntax.flatMap.*
import cats.Monad import cats.syntax.functor.*
class ArrowTypeSem[S[_]](val expr: ArrowTypeExpr[S]) extends AnyVal { class ArrowTypeSem[S[_]](val expr: ArrowTypeExpr[S]) extends AnyVal {
def program[Alg[_]: Monad](implicit def program[Alg[_]: Monad](implicit
T: TypesAlgebra[S, Alg], T: TypesAlgebra[S, Alg],
A: AbilitiesAlgebra[S, Alg],
D: DefinitionsAlgebra[S, Alg] D: DefinitionsAlgebra[S, Alg]
): Prog[Alg, Raw] = ): Prog[Alg, Raw] =
T.resolveArrowDef(expr.`type`).flatMap { T.resolveArrowDef(expr.`type`).flatMap {

View File

@ -1,11 +1,9 @@
package aqua.semantics.expr.func 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.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.Prog
import aqua.semantics.rules.ValuesAlgebra import aqua.semantics.rules.ValuesAlgebra
import aqua.semantics.rules.names.NamesAlgebra import aqua.semantics.rules.names.NamesAlgebra
@ -22,18 +20,10 @@ class AssignmentSem[S[_]](val expr: AssignmentExpr[S]) extends AnyVal {
): Prog[Alg, Raw] = ): Prog[Alg, Raw] =
V.valueToRaw(expr.value).flatMap { V.valueToRaw(expr.value).flatMap {
case Some(vm) => case Some(vm) =>
vm.`type` match { N.assign(expr.variable, vm) as (AssignmentTag(
case at @ ArrowType(_, _) => vm,
N.defineArrow(expr.variable, at, false) as (AssignmentTag( expr.variable.value
vm, ).funcOpLeaf: Raw)
expr.variable.value
).funcOpLeaf: Raw)
case _ =>
N.derive(expr.variable, vm.`type`, vm.varNames) as (AssignmentTag(
vm,
expr.variable.value
).funcOpLeaf: Raw)
}
case _ => Raw.error("Cannot resolve assignment type").pure[Alg] case _ => Raw.error("Cannot resolve assignment type").pure[Alg]
} }

View File

@ -1,8 +1,8 @@
package aqua.semantics.rules.names 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 aqua.types.{ArrowType, StreamType, Type}
import cats.InjectK
trait NamesAlgebra[S[_], Alg[_]] { trait NamesAlgebra[S[_], Alg[_]] {
@ -21,6 +21,8 @@ trait NamesAlgebra[S[_], Alg[_]] {
def defineConstant(name: Name[S], `type`: Type): Alg[Boolean] 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 defineArrow(name: Name[S], gen: ArrowType, isRoot: Boolean): Alg[Boolean]
def streamsDefinedWithinScope(): Alg[Map[String, StreamType]] def streamsDefinedWithinScope(): Alg[Map[String, StreamType]]

View File

@ -1,6 +1,7 @@
package aqua.semantics.rules.names package aqua.semantics.rules.names
import aqua.parser.lexer.{Name, Token} import aqua.parser.lexer.{Name, Token}
import aqua.raw.value.{ValueRaw, VarRaw}
import aqua.semantics.Levenshtein import aqua.semantics.Levenshtein
import aqua.semantics.rules.StackInterpreter import aqua.semantics.rules.StackInterpreter
import aqua.semantics.rules.report.ReportAlgebra import aqua.semantics.rules.report.ReportAlgebra
@ -131,6 +132,26 @@ class NamesInterpreter[S[_], X](using
).as(true) ).as(true)
}.flatTap(_ => locations.addToken(name.value, name)) }.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] = override def defineArrow(name: Name[S], arrowType: ArrowType, isRoot: Boolean): SX[Boolean] =
readName(name.value).flatMap { readName(name.value).flatMap {
case Some(_) => case Some(_) =>