Skip to content

Commit

Permalink
Make ranged for working
Browse files Browse the repository at this point in the history
  • Loading branch information
bobismijnnaam committed Jun 22, 2023
1 parent deee303 commit 6b9476f
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/col/vct/col/ast/Node.scala
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ final case class Branch[G](branches: Seq[(Expr[G], Statement[G])])(implicit val
final case class IndetBranch[G](branches: Seq[Statement[G]])(implicit val o: Origin) extends CompositeStatement[G] with IndetBranchImpl[G]
final case class Switch[G](expr: Expr[G], body: Statement[G])(implicit val o: Origin) extends CompositeStatement[G] with SwitchImpl[G]
final case class Loop[G](init: Statement[G], cond: Expr[G], update: Statement[G], contract: LoopContract[G], body: Statement[G])(implicit val o: Origin) extends CompositeStatement[G] with LoopImpl[G]
final case class RangedFor[G](binder: Variable[G], from: Expr[G], to: Expr[G], contract: LoopContract[G], body: Statement[G])(implicit val o: Origin) extends CompositeStatement[G]
final case class RangedFor[G](iter: IterVariable[G], contract: LoopContract[G], body: Statement[G])(implicit val o: Origin) extends CompositeStatement[G] with Declarator[G] with RangedForImpl[G]
final case class TryCatchFinally[G](body: Statement[G], after: Statement[G], catches: Seq[CatchClause[G]])(implicit val o: Origin) extends CompositeStatement[G] with TryCatchFinallyImpl[G]
final case class Synchronized[G](obj: Expr[G], body: Statement[G])(val blame: Blame[LockRegionFailure])(implicit val o: Origin) extends CompositeStatement[G] with SynchronizedImpl[G]
final case class ParInvariant[G](decl: ParInvariantDecl[G], inv: Expr[G], content: Statement[G])(val blame: Blame[ParInvariantNotEstablished])(implicit val o: Origin) extends CompositeStatement[G] with ParInvariantImpl[G]
Expand Down
13 changes: 13 additions & 0 deletions src/col/vct/col/ast/statement/composite/RangedForImpl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package vct.col.ast.statement.composite

import vct.col.ast.{Declaration, RangedFor}
import vct.col.print._

trait RangedForImpl[G] { this: RangedFor[G] =>
override def declarations: Seq[Declaration[G]] = Seq(iter.variable)

override def layout(implicit ctx: Ctx): Doc =
Doc.stack(Seq(
Group(Text("for") <> "(" <> Doc.arg(iter) <> ")"),
)) <+> body.layoutAsBlock
}
1 change: 1 addition & 0 deletions src/col/vct/col/typerules/CoercingRewriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,7 @@ abstract class CoercingRewriter[Pre <: Generation]() extends AbstractRewriter[Pr
case bar @ ParBarrier(block, invs, requires, ensures, content) => ParBarrier(block, invs, res(requires), res(ensures), content)(bar.blame)
case p @ ParInvariant(decl, inv, content) => ParInvariant(decl, res(inv), content)(p.blame)
case ParStatement(impl) => ParStatement(impl)
case RangedFor(iter, contract, body) => RangedFor(iter, contract, body)
case Recv(ref) => Recv(ref)
case r @ Refute(assn) => Refute(res(assn))(r.blame)
case Return(result) => Return(result) // TODO coerce return, make AmbiguousReturn?
Expand Down
2 changes: 1 addition & 1 deletion src/colhelper/ColDefs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ object ColDefs {
"ModelDeclaration" -> Seq("Program"),
"EnumConstant" -> Seq("Program"),
"Variable" -> Seq(
"ParBlock", "VecBlock", "CatchClause", "Scope", "SignalsClause", // Explicit declarations
"ParBlock", "VecBlock", "CatchClause", "Scope", "SignalsClause", "RangedForLoop", // Explicit declarations
"AxiomaticDataType", "JavaClass", "JavaInterface", // Type arguments
"Predicate", "InstancePredicate", // Arguments
"ModelProcess", "ModelAction", "ADTFunction",
Expand Down
1 change: 1 addition & 0 deletions src/main/vct/main/stages/Transformation.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ case class SilverTransformation
// Normalize AST
Disambiguate, // Resolve overloaded operators (+, subscript, etc.)
DisambiguateLocation, // Resolve location type
EncodeRangedFor,

EncodeString, // Encode spec string as seq<int>
EncodeChar,
Expand Down
6 changes: 2 additions & 4 deletions src/parsers/vct/parsers/transform/PVLToCol.scala
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,9 @@ case class PVLToCol[G](override val originProvider: OriginProvider, override val
convert(body)
))
)
case PvlRangedFor(contract, _, _, Iter0(t, name, _, from, _, to), _, body) =>
case PvlRangedFor(contract, _, _, iter, _, body) =>
withContract(contract, contract =>
Scope(Nil, RangedFor(
new Variable(convert(t))(origin(name)),
convert(from), convert(to),
Scope(Nil, RangedFor(convert(iter),
contract.consumeLoopContract(stat),
convert(body))))
case PvlBlock(inner) => convert(inner)
Expand Down
30 changes: 28 additions & 2 deletions src/rewrite/vct/rewrite/EncodeRangedFor.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
package vct.col.rewrite

import vct.col.ast.{Statement, RangedFor}
import hre.util.ScopedStack
import vct.col.ast.{Block, Assign, Expr, IterVariable, Local, LocalDecl, Loop, LoopInvariant, IterationContract, Eval, LoopContract, PostAssignExpression, Range, RangedFor, SeqMember, Statement, Variable}
import vct.col.origin.AssignLocalOk
import vct.col.util.AstBuildHelpers.const
import vct.col.util.AstBuildHelpers._
import vct.col.ast.RewriteHelpers._

case object EncodeRangedFor extends RewriterBuilder {
override def key: String = "encodeRangedFor"
override def desc: String = "Encodes ranged for as a regular for loop"
}

case class EncodeRangedFor[Pre <: Generation]() extends Rewriter[Pre] {
val bounds = ScopedStack[(RangedFor[Pre], Expr[Post])]()

override def dispatch(stat: Statement[Pre]): Statement[Post] = stat match {
// case RangedFor(v, from, to, contract, body) => ???
case rf @ RangedFor(IterVariable(iVar, from, to), contract, body) =>
implicit val o = iVar.o
val i = Local[Post](anySucc[Variable[Post]](iVar))(iVar.o)
Loop(
Block(Seq(
LocalDecl(variables.collect(dispatch(iVar))._1.head),
Assign(i, dispatch(from))(AssignLocalOk)
))(iVar.o),
SeqMember(i, Range(dispatch(from), dispatch(to))),
Eval(PostAssignExpression(i, i + const(1))(AssignLocalOk)),
bounds.having((rf, SeqMember(i, Range(dispatch(from), dispatch(to) + const(1)))))(dispatch(contract)),
dispatch(body)
)(rf.o)
case stat => rewriteDefault(stat)
}

override def dispatch(contract: LoopContract[Pre]): LoopContract[Post] = (bounds.topOption, contract) match {
case (Some((rf, iBounds)), l: LoopInvariant[Pre]) =>
l.rewrite(invariant = (iBounds && dispatch(l.invariant))(rf.o))
case (Some((rf, iBounds)), ic: IterationContract[Pre]) =>
ic.rewrite(context_everywhere = (iBounds && dispatch(ic.context_everywhere))(rf.o))
case (None, c) => rewriteDefault(c)
}
}

0 comments on commit 6b9476f

Please sign in to comment.