From b82deb1ef1d0702529e002c477b17d779f7bc7be Mon Sep 17 00:00:00 2001 From: "Emmanouil (Manos) Koukoutos" <emmanouil.koukoutos@epfl.ch> Date: Mon, 17 Mar 2014 21:21:30 +0100 Subject: [PATCH] Pretty printing fixes/improvements --- .../frontends/scalac/CodeExtraction.scala | 2 +- .../scala/leon/purescala/PrettyPrinter.scala | 59 ++++++++++++++----- .../scala/leon/purescala/ScalaPrinter.scala | 15 +++++ .../verification/VerificationCondition.scala | 8 ++- .../verification/VerificationReport.scala | 1 + .../regression/frontends/Operators.scala | 9 +++ 6 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 src/test/resources/regression/frontends/Operators.scala diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala index 149e91bd4..a9502dff9 100644 --- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala @@ -108,7 +108,7 @@ trait CodeExtraction extends ASTExtractors { class Extraction(units: List[CompilationUnit]) { private var currentFunDef: FunDef = null - //This is a bit missleading, if an expr is not mapped then it has no owner, if it is mapped to None it means + //This is a bit misleading, if an expr is not mapped then it has no owner, if it is mapped to None it means //that it can have any owner private var owners: Map[Identifier, Option[FunDef]] = Map() diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala index 0973edddb..1c6c95cb1 100644 --- a/src/main/scala/leon/purescala/PrettyPrinter.scala +++ b/src/main/scala/leon/purescala/PrettyPrinter.scala @@ -125,27 +125,49 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe } } - def pp(tree: Tree)(implicit ctx: PrinterContext): Unit = { - - tree match { - case id: Identifier => - if (opts.printUniqueIds) { - p"${id.uniqueName}" + def pp(tree: Tree)(implicit ctx: PrinterContext): Unit = tree match { + + case id: Identifier => + val name = if (opts.printUniqueIds) { + id.uniqueName } else { - p"${id.toString}" + id.toString } - + val alphaNumDollar = "[\\w\\$]" + // FIXME this does not account for class names with operator symbols + def isLegalScalaId(id : String) = id.matches( + s"${alphaNumDollar}+|[${alphaNumDollar}+_]?[!@#%^&*+-\\|~/?><:]+" + ) + // Replace $opname with operator symbols + val candidate = scala.reflect.NameTransformer.decode(name) + + if (isLegalScalaId(candidate)) p"$candidate" else p"$name" + case Variable(id) => p"$id" case LetTuple(bs,d,e) => - p"""|val ($bs) = $d; - |$e""" - + e match { + case _:LetDef | _ : Let | _ : LetTuple => + p"""|val ($bs) = { + | $d + |} + |$e""" + case _ => + p"""|val ($bs) = $d; + |$e""" + } case Let(b,d,e) => - p"""|val $b = $d; - |$e""" - + e match { + case _:LetDef | _ : Let | _ : LetTuple => + p"""|val $b = { + | $d + |} + |$e""" + case _ => + p"""|val $b = $d; + |$e""" + } case LetDef(fd,body) => p"""|$fd |$body""" @@ -391,7 +413,11 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe } parent.foreach{ par => - p" extends ${par.id}" + if (par.tps.nonEmpty){ + p" extends ${par.id}[${par.tps}]" + } else { + p" extends ${par.id}" + } } if (ccd.methods.nonEmpty) { @@ -435,7 +461,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case (tree: PrettyPrintable) => tree.printWith(ctx) case _ => sb.append("Tree? (" + tree.getClass + ")") - } + } def requiresBraces(ex: Tree, within: Option[Tree]): Boolean = (ex, within) match { @@ -471,6 +497,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case (_, Some(_: MatchExpr | _: MatchCase | _: Let | _: LetTuple | _: LetDef | _: IfExpr)) => false case (_, Some(_: FunctionInvocation)) => false case (ie: IfExpr, _) => true + case (me: MatchExpr, _ ) => true case (e1: Expr, Some(e2: Expr)) if precedence(e1) > precedence(e2) => false case (_, _) => true } diff --git a/src/main/scala/leon/purescala/ScalaPrinter.scala b/src/main/scala/leon/purescala/ScalaPrinter.scala index 4807224e5..74ff651d1 100644 --- a/src/main/scala/leon/purescala/ScalaPrinter.scala +++ b/src/main/scala/leon/purescala/ScalaPrinter.scala @@ -12,8 +12,15 @@ import PrinterHelpers._ /** This pretty-printer only print valid scala syntax */ class ScalaPrinter(opts: PrinterOptions, sb: StringBuffer = new StringBuffer) extends PrettyPrinter(opts, sb) { + import Common._ + import Trees._ + import TypeTrees._ + import Definitions._ + + import java.lang.StringBuffer override def pp(tree: Tree)(implicit ctx: PrinterContext): Unit = { + tree match { case Not(Equals(l, r)) => p"$l != $r" case Iff(l,r) => p"$l == $r" @@ -27,6 +34,14 @@ class ScalaPrinter(opts: PrinterOptions, sb: StringBuffer = new StringBuffer) ex p"Set($rs)" } } + case m @ FiniteMap(els) => { + m.getType match { + case MapType(k,v) => + p"Map[$k,$v]($els)" + case _ => + p"Map($els)" + } + } case ElementOfSet(e,s) => p"$s.contains(e)" case SetUnion(l,r) => p"$l ++ $r" case MapUnion(l,r) => p"$l ++ $r" diff --git a/src/main/scala/leon/verification/VerificationCondition.scala b/src/main/scala/leon/verification/VerificationCondition.scala index fd03419d4..4e690547d 100644 --- a/src/main/scala/leon/verification/VerificationCondition.scala +++ b/src/main/scala/leon/verification/VerificationCondition.scala @@ -13,7 +13,7 @@ import leon.solvers._ class VerificationCondition(val condition: Expr, val funDef: FunDef, val kind: VCKind, val tactic: Tactic, val info: String = "") extends Positioned { // None = still unknown // Some(true) = valid - // Some(false) = valid + // Some(false) = invalid var hasValue = false var value : Option[Boolean] = None var solvedWith : Option[Solver] = None @@ -35,6 +35,12 @@ class VerificationCondition(val condition: Expr, val funDef: FunDef, val kind: V case Some(s) => s.name case None => "" } + + override def toString = { + kind.toString + " in function " + funDef.id.name + "\n" + + condition.toString + } + } abstract class VCKind(val name: String, val abbrv: String) { diff --git a/src/main/scala/leon/verification/VerificationReport.scala b/src/main/scala/leon/verification/VerificationReport.scala index b6522f5a6..59d4ef4e6 100644 --- a/src/main/scala/leon/verification/VerificationReport.scala +++ b/src/main/scala/leon/verification/VerificationReport.scala @@ -4,6 +4,7 @@ package leon package verification import purescala.Definitions.FunDef +import purescala.ScalaPrinter class VerificationReport(val fvcs: Map[FunDef, List[VerificationCondition]]) { import scala.math.Ordering.Implicits._ diff --git a/src/test/resources/regression/frontends/Operators.scala b/src/test/resources/regression/frontends/Operators.scala new file mode 100644 index 000000000..d91673051 --- /dev/null +++ b/src/test/resources/regression/frontends/Operators.scala @@ -0,0 +1,9 @@ +object Operators { + + case class HasOps(i : Int){ + def + (j : HasOps) = this.i + j.i + } + + def x = HasOps(12) + HasOps(30) + +} \ No newline at end of file -- GitLab