Skip to content

Commit

Permalink
Add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
InversionSpaces committed Feb 28, 2024
1 parent 97038c2 commit 4c52234
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 17 deletions.
22 changes: 18 additions & 4 deletions parser/src/main/scala/aqua/parser/lexer/PropertyOp.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package aqua.parser.lexer

import aqua.parser.lexer.CallArrowToken.CallBraces
import aqua.parser.lexer.NamedArg.namedArgs
import aqua.parser.lexer.Token.*
import aqua.parser.lift.LiftParser
import aqua.parser.lift.LiftParser.*
import aqua.parser.lift.Span
import aqua.parser.lift.Span.{P0ToSpan, PToSpan}
import aqua.types.LiteralType
import aqua.parser.lexer.CallArrowToken.CallBraces
import aqua.parser.lexer.NamedArg.namedArgs

import cats.~>
import cats.data.{NonEmptyList, NonEmptyMap}
import cats.parse.{Numbers, Parser as P, Parser0 as P0}
import cats.syntax.comonad.*
import cats.syntax.functor.*
import cats.{Comonad, Functor}
import cats.~>
import scala.language.postfixOps

sealed trait PropertyOp[F[_]] extends Token[F] {
Expand Down Expand Up @@ -62,6 +62,12 @@ case class IntoCopy[F[_]: Comonad](
override def toString: String = s".copy(${args.map(_.toString).toList.mkString(", ")})"
}

/**
* WARNING: This is parsed when we have parens after a name, but `IntoArrow` failed to parse.
* This is a case of imported named type, e.g. `Some.Imported.Module.DefinedAbility(...)`
* It is transformed into `NamedTypeValue` in `ValuesAlgebra`
* TODO: Eliminate `IntoArrow`, unify it with this property
*/
case class IntoApply[F[_]: Comonad](
argsF: F[NonEmptyList[NamedArg[F]]]
) extends PropertyOp[F] {
Expand Down Expand Up @@ -108,7 +114,15 @@ object PropertyOp {
namedArgs.lift.map(IntoApply.apply)

private val parseOp: P[PropertyOp[Span.S]] =
P.oneOf(parseCopy.backtrack :: parseArrow.backtrack :: parseField :: parseIdx :: parseApply.backtrack :: Nil)
P.oneOf(
// NOTE: order is important here
// intoApply has lower priority than intoArrow
parseCopy.backtrack ::
parseArrow.backtrack ::
parseField ::
parseIdx ::
parseApply.backtrack :: Nil
)

val ops: P[NonEmptyList[PropertyOp[Span.S]]] =
parseOp.rep
Expand Down
59 changes: 47 additions & 12 deletions parser/src/main/scala/aqua/parser/lexer/ValueToken.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,32 +41,61 @@ case class PropertyToken[F[_]: Comonad](
private def isConst(name: String): Boolean =
name.forall(c => !c.isLetter || c.isUpper)

/**
* Try to transform this token to imported ability access
* e.g. in `Some.Imported.Module.Ab.innerAb.call(...)`:
* - `Some.Imported.Module` is imported module name
* - `Ab.innerAb.call(...)` is ability access
* so it should be handled as `(Some.Imported.Module.Ab).innerAb.call(...)`
* ^^^^^^^^^^^^^^^^^^^^^^^
* ability name inside `VarToken` as one string
* but we don't this in advance, so this method returns
* a list of all possible (imported module name, ability access value token) pairs
* so calling code can check what prefix is valid imported module name and
* handle the corresponding ability access value token.
*/
def toAbility: List[(NamedTypeToken[F], ValueToken[F])] =
value match {
// NOTE: guard against recursion: if dot is alredy in the name, do not transform
case VarToken(name) if !name.value.contains(".") =>
val fields = properties.toList.takeWhile {
case IntoField(_) => true
case _ => false
}.collect { case f @ IntoField(_) => f.value }.toList
val names = name.value +: fields

fields.inits.drop(1).map { init =>
val importLength = init.length + 1
val nameLength = importLength + 1
val newProps = NonEmptyList.fromList(
properties.toList.drop(importLength)
)
val newName = name.rename(names.take(nameLength).mkString("."))
val importAbility = name.rename(names.take(importLength).mkString(".")).asTypeToken
fields.inits
// do not use the last field
// those cases are handled in `toCallArrow` and `toNamedValue`
.drop(1)
.map { init =>
// Length of the import name
val importLength = init.length + 1
// Length of the imported name
val nameLength = importLength + 1
val newProps = NonEmptyList.fromList(
properties.toList.drop(importLength)
)
val newName = name.rename(names.take(nameLength).mkString("."))
val importAbility = name.rename(names.take(importLength).mkString(".")).asTypeToken

val varToken = VarToken(newName)
val token = newProps.fold(varToken)(ps => PropertyToken(varToken, ps))
val varToken = VarToken(newName)
val token = newProps.fold(varToken)(ps => PropertyToken(varToken, ps))

importAbility -> token
}.toList.reverse
importAbility -> token
}
.toList
// test shorter prefixes first
.reverse
case _ => Nil
}

/**
* Try to convert this token into `CallArrowToken`
* e.g. `Some.Imported.Module.call(...)`
* ^^^^^^^^^^^^^^^^^^^^ ^^^^
* ability name function name
*/
def toCallArrow: Option[CallArrowToken[F]] = (
value,
properties.last
Expand All @@ -91,6 +120,12 @@ case class PropertyToken[F[_]: Comonad](
case _ => none
}

/**
* Try to convert this token into `NamedValueToken`,
* e.g. `Some.Imported.Module.DefinedAbility(...)`
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* type name
*/
def toNamedValue: Option[NamedValueToken[F]] =
(value, properties.last) match {
case (v @ VarToken(name), IntoApply(args)) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package aqua.semantics.rules

import aqua.errors.Errors.internalError
import aqua.helpers.syntax.optiont.*
import aqua.parser.lexer.*
import aqua.parser.lexer.InfixToken.{BoolOp, CmpOp, EqOp, MathOp, Op as InfOp}
Expand Down Expand Up @@ -85,7 +86,8 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](using
idx <- OptionT(op.idx.fold(LiteralRaw.Zero.some.pure)(valueToRaw))
valueType <- OptionT(T.resolveIntoIndex(op, rootType, idx.`type`))
} yield IntoIndexRaw(idx, valueType)).value
case op: IntoApply[S] => ???
case op: IntoApply[S] =>
internalError("Unexpected. `IntoApply` expected to be transformed into `NamedValueToken`")
}

def valueToRaw(v: ValueToken[S]): Alg[Option[ValueRaw]] =
Expand Down Expand Up @@ -142,6 +144,7 @@ class ValuesAlgebra[S[_], Alg[_]: Monad](using

val ability = OptionT(
prop.toAbility.findM { case (ab, _) =>
// Test if name is an import
A.isDefinedAbility(ab)
}
).map { case (_, token) => token }
Expand Down

0 comments on commit 4c52234

Please sign in to comment.