Commit 78ee70ce authored by Arthur Bit-Monnot's avatar Arthur Bit-Monnot

[anml] Add support for parsing integer expressions.

parent d69f442b
......@@ -62,6 +62,7 @@ package object common {
case class IntLiteral(value: Int) extends Cst {
override def typ: Type = Type.Integers
override def id: Id = Id(RootScope + "_integers_", value.toString)
override def toString: String = value.toString
}
/** Variable declared locally */
......
......@@ -152,6 +152,8 @@ package object core {
}
final case class Minus(e: IntExpr) extends IntExpr
final case class Add(lhs: IntExpr, rhs: IntExpr) extends IntExpr
final case class Mul(lhs: IntExpr, rhs: IntExpr) extends IntExpr
final case class Div(lhs: IntExpr, rhs: IntExpr) extends IntExpr
/** A timepoint, declared when appearing in the root of a context.*/
final case class TPRef(id: Timepoint, delay: IntExpr = IntExpr(0)) {
......
......@@ -109,9 +109,12 @@ package object full {
case class GenIntExpr(e: StaticExpr) extends IntExpr {
require(e.typ.id.name == "integer")
override def toString: String = e.toString
}
case class Minus(e: IntExpr) extends IntExpr
case class Add(lhs: IntExpr, rhs: IntExpr) extends IntExpr
case class Mul(lhs: IntExpr, rhs: IntExpr) extends IntExpr
case class Div(lhs: IntExpr, rhs: IntExpr) extends IntExpr
case class Interval(start: TPRef, end: TPRef) {
override def toString: String = s"[$start, $end]"
......
......@@ -59,6 +59,18 @@ object FullToCore {
el <- f2c(lhs)
er <- f2c(rhs)
} yield core.Add(el, er)
case full.Mul(lhs, rhs) =>
for {
el <- f2c(lhs)
er <- f2c(rhs)
} yield core.Mul(el, er)
case full.Div(lhs, rhs) =>
for {
el <- f2c(lhs)
er <- f2c(rhs)
} yield core.Div(el, er)
}
private def f2c(tp: full.TPRef)(implicit ctx: Context): CoreM[core.TPRef] =
......
......@@ -11,6 +11,7 @@ import fastparse.core.Parsed.Failure
import copla.lang.model.common._
import copla.lang.model.full._
import scala.annotation.tailrec
import scala.util.Try
abstract class AnmlParser(val initialContext: Ctx) {
......@@ -246,8 +247,41 @@ abstract class AnmlParser(val initialContext: Ctx) {
int.map(i => CommonTerm(IntLiteral(i)))
}
val intExpr: Parser[IntExpr] =
staticExpr.namedFilter(_.typ == Type.Integers, "of-type-integer").map(full.GenIntExpr(_))
object IntOperators {
val expression: P[IntExpr] = additiveExpr
def primary: Parser[IntExpr] = P {
P("(").flatMap(_ => additiveExpr ~ ")") |
staticExpr.namedFilter(_.typ == Type.Integers, "of-type-integer").map(full.GenIntExpr) |
int.map(i => GenIntExpr(ConstantExpr(IntLiteral(i)))) |
"-" ~/ primary
}
def multiplicativeExpr: P[IntExpr] = P {
(primary ~ (("*" | "/").! ~/ primary).rep).map {
case (head, rest) => transform(head, rest)
}
}
def additiveExpr: P[IntExpr] = P {
(multiplicativeExpr ~ (("+" | "-").! ~/ multiplicativeExpr).rep).map {
case (head, rest) => transform(head, rest)
}
}
@tailrec def transform(lhs: IntExpr, tail: Seq[(String, IntExpr)]): IntExpr =
tail.toList match {
case Nil => lhs
case ("*", rhs) :: rest => transform(Mul(lhs, rhs), rest)
case ("/", rhs) :: rest => transform(Div(lhs, rhs), rest)
case ("+", rhs) :: rest => transform(Add(lhs, rhs), rest)
case ("-", rhs) :: rest => transform(Add(lhs, Minus(rhs)), rest)
case x :: _ => sys.error(s"Unrecognized term: $x")
}
}
lazy val intExpr: P[IntExpr] = IntOperators.expression
val expr: Parser[Expr] =
timedSymExpr | staticExpr
......
......@@ -32,8 +32,8 @@ class FullToCoreTest extends FunSuite {
case ParseSuccess(fullMod) =>
val m = FullToCore.trans(fullMod)
checkInvariantsInCore(m)
case _ =>
fail("Could not parse anml string")
case err =>
fail(s"Could not parse anml string: $err")
}
}
}
......
......@@ -72,7 +72,9 @@ object InputAnmlModels {
"type T; instance T t1; constant T sv(boolean b); action A() { constant T t; sv(true) != t; };",
"constant integer d;",
"constant boolean isTrue(integer x);",
"constant boolean isTrue(integer x); isTrue(1) := false;"
"constant boolean isTrue(integer x); isTrue(1) := false;",
"duration == 10 * 4 + 2;",
"constant integer i; duration == 10 * i + 2;",
)
val invalid = Seq(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment