mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 22:50:18 +00:00
Verifies (with bugs)
This commit is contained in:
parent
401b7a31df
commit
e33b499c42
@ -35,9 +35,9 @@ object Aqua {
|
||||
.map(pe => NonEmptyList.one[AquaError](SyntaxError(pe.failedAtOffset, pe.expected)))
|
||||
)
|
||||
.andThen { blocks =>
|
||||
step1.walkValidate(blocks).leftMap(_.map(_.toStringF).map(sv => WalkerError(sv._1, sv._2)))
|
||||
step1.walkValidate(blocks).leftMap(_.map(_.toStringF).map(sv => CompilerError(sv._1, sv._2)))
|
||||
}
|
||||
.andThen { blocks =>
|
||||
step2.walkValidate(blocks).leftMap(_.map(_.toStringF).map(sv => WalkerError(sv._1, sv._2)))
|
||||
step2.walkValidate(blocks).leftMap(_.map(_.toStringF).map(sv => CompilerError(sv._1, sv._2)))
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ case class SyntaxError(offset: Int, expectations: NonEmptyList[Expectation]) ext
|
||||
) + Console.RESET + "\n"
|
||||
}
|
||||
|
||||
case class WalkerError(span: Span, hint: String) extends AquaError {
|
||||
case class CompilerError(span: Span, hint: String) extends AquaError {
|
||||
|
||||
override def showForConsole(script: String): String =
|
||||
span
|
||||
@ -27,12 +27,3 @@ case class WalkerError(span: Span, hint: String) extends AquaError {
|
||||
.map(_.toConsoleStr(hint, Console.CYAN))
|
||||
.getOrElse("(Dup error, but offset is beyond the script)") + "\n"
|
||||
}
|
||||
|
||||
case class GetTypeError(span: Span, hint: String) extends AquaError {
|
||||
|
||||
override def showForConsole(script: String): String =
|
||||
span
|
||||
.focus(script, 3)
|
||||
.map(_.toConsoleStr(hint, Console.MAGENTA))
|
||||
.getOrElse("(Get type error, but offset is beyond the script)") + "\n"
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package aqua
|
||||
|
||||
import aqua.ast.algebra.ReportError
|
||||
import aqua.ast.expr.{
|
||||
AbilityIdExpr,
|
||||
AliasExpr,
|
||||
@ -13,19 +14,26 @@ import aqua.ast.expr.{
|
||||
RootExpr,
|
||||
ServiceExpr
|
||||
}
|
||||
import aqua.ast.algebra.abilities.{AbilitiesAlgebra, AbilityOp}
|
||||
import aqua.ast.algebra.names.{NameOp, NamesAlgebra}
|
||||
import aqua.ast.algebra.scope.{PeerIdAlgebra, PeerIdOp}
|
||||
import aqua.ast.algebra.types.{TypeOp, TypesAlgebra}
|
||||
import aqua.ast.algebra.abilities.{AbilitiesAlgebra, AbilitiesInterpreter, AbilitiesState, AbilityOp}
|
||||
import aqua.ast.algebra.names.{NameOp, NamesAlgebra, NamesInterpreter, NamesState}
|
||||
import aqua.ast.algebra.scope.{PeerIdAlgebra, PeerIdInterpreter, PeerIdOp, PeerIdState}
|
||||
import aqua.ast.algebra.types.{TypeOp, TypesAlgebra, TypesInterpreter, TypesState}
|
||||
import aqua.ast.{Ast, Expr, Gen, Prog}
|
||||
import cats.data.EitherK
|
||||
import aqua.parser.lexer.Token
|
||||
import cats.arrow.FunctionK
|
||||
import cats.data.Validated.{Invalid, Valid}
|
||||
import cats.data.{EitherK, NonEmptyList, State, ValidatedNel}
|
||||
import cats.{Comonad, Eval}
|
||||
import cats.free.Free
|
||||
import cats.syntax.flatMap._
|
||||
import monocle.Lens
|
||||
import monocle.macros.GenLens
|
||||
|
||||
import scala.collection.immutable.Queue
|
||||
|
||||
object Compiler {
|
||||
|
||||
private def exprToProg[F[_]: Comonad, G[_]](
|
||||
private def exprToProg[F[_], G[_]](
|
||||
expr: Expr[F]
|
||||
)(implicit
|
||||
A: AbilitiesAlgebra[F, G],
|
||||
@ -47,7 +55,7 @@ object Compiler {
|
||||
case _: RootExpr[F] => Free.pure[G, Gen](Gen("Root expr"))
|
||||
}
|
||||
|
||||
def folder[F[_]: Comonad, G[_]](implicit
|
||||
def folder[F[_], G[_]](implicit
|
||||
A: AbilitiesAlgebra[F, G],
|
||||
N: NamesAlgebra[F, G],
|
||||
P: PeerIdAlgebra[F, G],
|
||||
@ -65,7 +73,52 @@ object Compiler {
|
||||
type Alg1[F[_], A] = EitherK[PeerIdOp[F, *], Alg0[F, *], A]
|
||||
type Alg[F[_], A] = EitherK[TypeOp[F, *], Alg1[F, *], A]
|
||||
|
||||
def transpile[F[_]: Comonad](ast: Ast[F]): Free[Alg[F, *], Gen] =
|
||||
def transpile[F[_]](ast: Ast[F]): Free[Alg[F, *], Gen] =
|
||||
ast.cata(folder[F, Alg[F, *]]).value
|
||||
|
||||
case class CompilerState[F[_]](
|
||||
errors: Queue[(Token[F], String)] = Queue.empty[(Token[F], String)],
|
||||
names: NamesState[F] = NamesState[F](),
|
||||
abilities: AbilitiesState[F] = AbilitiesState[F](),
|
||||
peerId: PeerIdState[F] = PeerIdState[F](),
|
||||
types: TypesState[F] = TypesState[F]()
|
||||
)
|
||||
|
||||
def interpret[F[_]](free: Free[Alg[F, *], Gen]): State[CompilerState[F], Gen] = {
|
||||
import monocle.macros.syntax.all._
|
||||
|
||||
implicit val re: ReportError[F, CompilerState[F]] =
|
||||
(st: CompilerState[F], token: Token[F], hint: String) => st.focus(_.errors).modify(_.enqueue(token -> hint))
|
||||
|
||||
implicit val ns: Lens[CompilerState[F], NamesState[F]] = GenLens[CompilerState[F]](_.names)
|
||||
|
||||
val names = new NamesInterpreter[F, CompilerState[F]]()
|
||||
|
||||
implicit val as: Lens[CompilerState[F], AbilitiesState[F]] = GenLens[CompilerState[F]](_.abilities)
|
||||
|
||||
val abilities = new AbilitiesInterpreter[F, CompilerState[F]]()
|
||||
|
||||
implicit val ps: Lens[CompilerState[F], PeerIdState[F]] = GenLens[CompilerState[F]](_.peerId)
|
||||
|
||||
val peerId = new PeerIdInterpreter[F, CompilerState[F]]()
|
||||
|
||||
implicit val ts: Lens[CompilerState[F], TypesState[F]] = GenLens[CompilerState[F]](_.types)
|
||||
|
||||
val types = new TypesInterpreter[F, CompilerState[F]]()
|
||||
|
||||
val interpreter0: FunctionK[Alg0[F, *], State[CompilerState[F], *]] = abilities or names
|
||||
val interpreter1: FunctionK[Alg1[F, *], State[CompilerState[F], *]] = peerId or interpreter0
|
||||
val interpreter: FunctionK[Alg[F, *], State[CompilerState[F], *]] = types or interpreter1
|
||||
|
||||
free.foldMap[State[CompilerState[F], *]](interpreter)
|
||||
}
|
||||
|
||||
def compile[F[_]](ast: Ast[F]): ValidatedNel[(Token[F], String), Gen] =
|
||||
(transpile[F] _ andThen interpret[F])(ast)
|
||||
.run(CompilerState[F]())
|
||||
.map {
|
||||
case (state, gen) =>
|
||||
NonEmptyList.fromList(state.errors.toList).fold[ValidatedNel[(Token[F], String), Gen]](Valid(gen))(Invalid(_))
|
||||
}
|
||||
.value
|
||||
}
|
||||
|
@ -24,14 +24,19 @@ object Main extends IOApp.Simple {
|
||||
println(Console.RED + s"Aqua script errored, total ${errs.length} problems found" + Console.RESET)
|
||||
}
|
||||
|
||||
val experimental = Source.fromResource("experimental.aqua").mkString
|
||||
val script = Source.fromResource("typecheck.aqua").mkString
|
||||
//tryParse(experimental)
|
||||
|
||||
val ast = Ast
|
||||
.fromString[Span.F](experimental)
|
||||
.leftMap(_.map(_.showForConsole(experimental)))
|
||||
.fromString[Span.F](script)
|
||||
.andThen(
|
||||
Compiler
|
||||
.compile[Span.F](_)
|
||||
.leftMap(_.map(ts => CompilerError(ts._1.unit._1, ts._2)))
|
||||
)
|
||||
.leftMap(_.map(_.showForConsole(script)).map(println))
|
||||
|
||||
ast.map(Compiler.transpile(_)).map(println(_))
|
||||
ast.map(println(_))
|
||||
|
||||
}
|
||||
|
||||
|
@ -44,11 +44,6 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
_.focus(_.names).index(dn.name.value).replace(dn.`type`) -> true
|
||||
)
|
||||
}
|
||||
mapStackHeadE(report(dn.name, "Cannot define in the root scope"))(fr =>
|
||||
fr.names.get(dn.name.value) match {
|
||||
case Some(_) => Left((dn.name, "Variable with this name was already defined", false))
|
||||
}
|
||||
)
|
||||
case bs: BeginScope[F] =>
|
||||
beginScope(NamesFrame(bs.token))
|
||||
case _: EndScope[F] =>
|
||||
@ -56,6 +51,6 @@ class NamesInterpreter[F[_], X](implicit lens: Lens[X, NamesState[F]], error: Re
|
||||
}).asInstanceOf[State[X, A]]
|
||||
}
|
||||
|
||||
case class NamesState[F[_]](stack: List[NamesFrame[F]])
|
||||
case class NamesState[F[_]](stack: List[NamesFrame[F]] = Nil)
|
||||
|
||||
case class NamesFrame[F[_]](token: Token[F], names: Map[String, Type] = Map.empty)
|
||||
|
@ -22,4 +22,4 @@ class PeerIdInterpreter[F[_], X](implicit lens: Lens[X, PeerIdState[F]], error:
|
||||
}).asInstanceOf[State[X, A]]
|
||||
}
|
||||
|
||||
case class PeerIdState[F[_]](stack: List[Value[F]])
|
||||
case class PeerIdState[F[_]](stack: List[Value[F]] = Nil)
|
||||
|
@ -97,8 +97,8 @@ class TypesInterpreter[F[_], X](implicit lens: Lens[X, TypesState[F]], error: Re
|
||||
}
|
||||
|
||||
case class TypesState[F[_]](
|
||||
fields: Map[String, (Name[F], Type)],
|
||||
strict: Map[String, Type]
|
||||
fields: Map[String, (Name[F], Type)] = Map.empty[String, (Name[F], Type)],
|
||||
strict: Map[String, Type] = Map.empty[String, Type]
|
||||
) {
|
||||
def isDefined(t: String): Boolean = strict.contains(t)
|
||||
|
||||
|
@ -22,8 +22,7 @@ case class FuncExpr[F[_]](name: Name[F], args: List[Arg[F]], ret: Option[DataTyp
|
||||
T: TypesAlgebra[F, Alg],
|
||||
N: NamesAlgebra[F, Alg],
|
||||
P: PeerIdAlgebra[F, Alg],
|
||||
A: AbilitiesAlgebra[F, Alg],
|
||||
F: Comonad[F]
|
||||
A: AbilitiesAlgebra[F, Alg]
|
||||
): Prog[Alg, Gen] =
|
||||
Prog.around(
|
||||
A.beginScope(name) >> Applicative[Free[Alg, *]]
|
||||
|
Loading…
Reference in New Issue
Block a user