Skip to content

Commit

Permalink
fix(compiler): Error on not arrow call after <- (#876)
Browse files Browse the repository at this point in the history
* Add error report

* Add tests
  • Loading branch information
InversionSpaces authored Sep 8, 2023
1 parent df111ad commit 69a808e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ class CallArrowSem[S[_]](val expr: CallArrowExpr[S]) extends AnyVal {
T: TypesAlgebra[S, Alg],
V: ValuesAlgebra[S, Alg]
): Alg[Option[FuncOp]] = for {
callArrowRaw <- V.valueToRaw(callArrow).map {
// TODO: Refactor this to support other results
case Some(car: CallArrowRaw) => car.some
case _ => none
}
// TODO: Accept other expressions
callArrowRaw <- V.valueToCallArrowRaw(expr.callArrow)
maybeOp <- callArrowRaw.traverse(car =>
variables
.drop(car.baseType.codomain.length)
Expand Down
18 changes: 15 additions & 3 deletions semantics/src/main/scala/aqua/semantics/rules/ValuesAlgebra.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import aqua.raw.value.*
import aqua.semantics.rules.abilities.AbilitiesAlgebra
import aqua.semantics.rules.names.NamesAlgebra
import aqua.semantics.rules.types.TypesAlgebra
import aqua.semantics.rules.errors.ErrorsAlgebra
import aqua.types.*

import cats.Monad
Expand All @@ -25,9 +26,10 @@ import scribe.Logging

import scala.collection.immutable.SortedMap

class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
class ValuesAlgebra[S[_], Alg[_]: Monad](using
N: NamesAlgebra[S, Alg],
T: TypesAlgebra[S, Alg],
E: ErrorsAlgebra[S, Alg],
A: AbilitiesAlgebra[S, Alg]
) extends Logging {

Expand Down Expand Up @@ -310,6 +312,15 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit
}
}

def valueToCallArrowRaw(v: ValueToken[S]): Alg[Option[CallArrowRaw]] =
valueToRaw(v).flatMap(
_.flatTraverse {
case ca: CallArrowRaw => ca.some.pure[Alg]
// TODO: better error message (`raw` formatting)
case raw => E.report(v, s"Expected arrow call, got $raw").as(none)
}
)

private def callArrowFromAbility(
ab: Name[S],
at: AbilityType,
Expand Down Expand Up @@ -402,10 +413,11 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](implicit

object ValuesAlgebra {

implicit def deriveValuesAlgebra[S[_], Alg[_]: Monad](implicit
given [S[_], Alg[_]: Monad](using
N: NamesAlgebra[S, Alg],
T: TypesAlgebra[S, Alg],
A: AbilitiesAlgebra[S, Alg]
A: AbilitiesAlgebra[S, Alg],
E: ErrorsAlgebra[S, Alg]
): ValuesAlgebra[S, Alg] =
new ValuesAlgebra[S, Alg]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ import aqua.parser.lexer.Token

trait ErrorsAlgebra[S[_], Alg[_]] {
def report(token: Token[S], hints: List[String]): Alg[Unit]

def report(token: Token[S], hint: String): Alg[Unit] =
report(token, hint :: Nil)
}
39 changes: 39 additions & 0 deletions semantics/src/test/scala/aqua/semantics/SemanticsSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -611,4 +611,43 @@ class SemanticsSpec extends AnyFlatSpec with Matchers with Inside {
atLeast(1, errors.toChain.toList) shouldBe a[RulesViolated[Span.S]]
}
}

it should "forbid not arrow calls after <-" in {
def scriptPush(prefix: String, what: String) =
s"""
|func main() -> []string:
| stream: *string
|${prefix.split("\n").map(" " + _).mkString("\n")}
| stream <- $what
| <- stream
|""".stripMargin

val scriptLiteral = scriptPush("", "\"a\"")

insideSemErrors(scriptLiteral) { errors =>
atLeast(1, errors.toChain.toList) shouldBe a[RulesViolated[Span.S]]
}

val scriptVar = scriptPush(
"""
|variable = "value"
|""".stripMargin,
"variable"
)

insideSemErrors(scriptVar) { errors =>
atLeast(1, errors.toChain.toList) shouldBe a[RulesViolated[Span.S]]
}

val scriptArrayElement = scriptPush(
"""
|arr = ["a", "b", "c"]
|""".stripMargin,
"arr[0]"
)

insideSemErrors(scriptArrayElement) { errors =>
atLeast(1, errors.toChain.toList) shouldBe a[RulesViolated[Span.S]]
}
}
}

0 comments on commit 69a808e

Please sign in to comment.