All Downloads are FREE. Search and download functionalities are using the official Maven repository.

miksilo.modularLanguages.deltas.statement.ForLoopDelta.scala Maven / Gradle / Ivy

The newest version!
package miksilo.modularLanguages.deltas.statement

import miksilo.modularLanguages.core.deltas._
import miksilo.modularLanguages.core.deltas.grammars.LanguageGrammars
import miksilo.modularLanguages.core.deltas.path.{NodePath, NodeSequenceElement, PathRoot}
import miksilo.modularLanguages.core.node._
import miksilo.languageServer.core.language.{Compilation, Language}
import miksilo.modularLanguages.deltas.expression.ExpressionDelta
import miksilo.modularLanguages.deltas.expression.ExpressionDelta.Expression
import miksilo.modularLanguages.deltas.javac.statements.ExpressionAsStatementDelta

object ForLoopDelta extends DeltaWithPhase with DeltaWithGrammar {

  override def description: String = "Enables using the non-iterator for loop."

  override def dependencies: Set[Contract] = Set(WhileLoopDelta, BlockAsStatementDelta)

  override def transformGrammars(grammars: LanguageGrammars, language: Language): Unit = {
    import grammars._

    val statementGrammar = find(StatementDelta.Grammar)
    val expressionGrammar = find(ExpressionDelta.FirstPrecedenceGrammar)
    val blockGrammar = find(BlockDelta.BlockOrStatementGrammar)
    val forLoopGrammar = "for" ~> (statementGrammar.as(Initializer) ~
      expressionGrammar.as(Condition) ~< ";" ~
      expressionGrammar.as(Increment)).inParenthesis %
      blockGrammar.as(Body) asNode Shape
    statementGrammar.addAlternative(forLoopGrammar)
  }

  override def transformProgram(program: Node, compilation: Compilation): Unit = {
    PathRoot(program).visitShape(Shape, path => transformForLoop(path))
  }

  def transformForLoop(forLoopPath: NodePath): Unit = {
    val forLoop: ForLoop[Node] = forLoopPath.current
    val whileBody = Seq(forLoop.body, ExpressionAsStatementDelta.create(forLoop.increment))
    val _while = WhileLoopDelta.create(forLoop.condition, BlockDelta.neww(whileBody))

    val newStatements = Seq[Node](forLoop.initializer, _while)
    val block = BlockDelta.Shape.create(BlockDelta.Statements -> newStatements)
    forLoopPath.asInstanceOf[NodeSequenceElement].replaceWith(block)
  }

  implicit class ForLoop[T <: NodeLike](val node: T) extends NodeWrapper[T] {
    def initializer: T = node(Initializer).asInstanceOf[T]
    def initializer_=(value: T): Unit = node(Initializer) = value

    def condition: Expression = node(Condition).asInstanceOf[Node]
    def condition_=(value: T): Unit = node(Condition) = value

    def increment: Expression = node(Increment).asInstanceOf[Node]
    def increment_=(value: Node): Unit = node(Increment) = value

    def body: T = node(Body).asInstanceOf[T]
    def body_=(value: Node): Unit = node(Body) = value
  }

  def forLoop(initializer: Node, condition: Node, increment: Node, body: Node) =
    new Node(Shape, Initializer -> initializer, Condition -> condition, Increment -> increment, Body -> body)

  object Shape extends NodeShape

  object Initializer extends NodeField

  object Condition extends NodeField

  object Increment extends NodeField

  object Body extends NodeField
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy