Skip to content
Snippets Groups Projects
Commit ac74114e authored by Marco Antognini's avatar Marco Antognini Committed by Etienne Kneuss
Browse files

Update Leon's main function & command line options to generate C code

parent 4a2709e4
No related branches found
No related tags found
No related merge requests found
...@@ -27,7 +27,9 @@ object Main { ...@@ -27,7 +27,9 @@ object Main {
solvers.isabelle.AdaptationPhase, solvers.isabelle.AdaptationPhase,
solvers.isabelle.IsabellePhase, solvers.isabelle.IsabellePhase,
transformations.InstrumentationPhase, transformations.InstrumentationPhase,
invariant.engine.InferInvariantsPhase) invariant.engine.InferInvariantsPhase,
genc.GenerateCPhase,
genc.CFileOutputPhase)
} }
// Add whatever you need here. // Add whatever you need here.
...@@ -53,9 +55,10 @@ object Main { ...@@ -53,9 +55,10 @@ object Main {
val optHelp = LeonFlagOptionDef("help", "Show help message", false) val optHelp = LeonFlagOptionDef("help", "Show help message", false)
val optInstrument = LeonFlagOptionDef("instrument", "Instrument the code for inferring time/depth/stack bounds", false) val optInstrument = LeonFlagOptionDef("instrument", "Instrument the code for inferring time/depth/stack bounds", false)
val optInferInv = LeonFlagOptionDef("inferInv", "Infer invariants from (instrumented) the code", false) val optInferInv = LeonFlagOptionDef("inferInv", "Infer invariants from (instrumented) the code", false)
val optGenc = LeonFlagOptionDef("genc", "Generate C code", false)
override val definedOptions: Set[LeonOptionDef[Any]] = override val definedOptions: Set[LeonOptionDef[Any]] =
Set(optTermination, optRepair, optSynthesis, optIsabelle, optNoop, optHelp, optEval, optVerify, optInstrument, optInferInv) Set(optTermination, optRepair, optSynthesis, optIsabelle, optNoop, optHelp, optEval, optVerify, optInstrument, optInferInv, optGenc)
} }
lazy val allOptions: Set[LeonOptionDef[Any]] = allComponents.flatMap(_.definedOptions) lazy val allOptions: Set[LeonOptionDef[Any]] = allComponents.flatMap(_.definedOptions)
...@@ -151,6 +154,8 @@ object Main { ...@@ -151,6 +154,8 @@ object Main {
import repair.RepairPhase import repair.RepairPhase
import evaluators.EvaluationPhase import evaluators.EvaluationPhase
import solvers.isabelle.IsabellePhase import solvers.isabelle.IsabellePhase
import genc.GenerateCPhase
import genc.CFileOutputPhase
import MainComponent._ import MainComponent._
import invariant.engine.InferInvariantsPhase import invariant.engine.InferInvariantsPhase
import transformations.InstrumentationPhase import transformations.InstrumentationPhase
...@@ -163,11 +168,17 @@ object Main { ...@@ -163,11 +168,17 @@ object Main {
val isabelleF = ctx.findOptionOrDefault(optIsabelle) val isabelleF = ctx.findOptionOrDefault(optIsabelle)
val terminationF = ctx.findOptionOrDefault(optTermination) val terminationF = ctx.findOptionOrDefault(optTermination)
val verifyF = ctx.findOptionOrDefault(optVerify) val verifyF = ctx.findOptionOrDefault(optVerify)
val gencF = ctx.findOptionOrDefault(optGenc)
val evalF = ctx.findOption(optEval).isDefined val evalF = ctx.findOption(optEval).isDefined
val inferInvF = ctx.findOptionOrDefault(optInferInv) val inferInvF = ctx.findOptionOrDefault(optInferInv)
val instrumentF = ctx.findOptionOrDefault(optInstrument) val instrumentF = ctx.findOptionOrDefault(optInstrument)
val analysisF = verifyF && terminationF val analysisF = verifyF && terminationF
// Check consistency in options
if (gencF && !xlangF) {
ctx.reporter.fatalError("Generating C code with --genc requires --xlang")
}
if (helpF) { if (helpF) {
displayVersion(ctx.reporter) displayVersion(ctx.reporter)
displayHelp(ctx.reporter, error = false) displayHelp(ctx.reporter, error = false)
...@@ -175,7 +186,7 @@ object Main { ...@@ -175,7 +186,7 @@ object Main {
val pipeBegin: Pipeline[List[String], Program] = val pipeBegin: Pipeline[List[String], Program] =
ClassgenPhase andThen ClassgenPhase andThen
ExtractionPhase andThen ExtractionPhase andThen
new PreprocessingPhase(xlangF) new PreprocessingPhase(xlangF, gencF)
val verification = if (xlangF) VerificationPhase andThen FixReportLabels else VerificationPhase val verification = if (xlangF) VerificationPhase andThen FixReportLabels else VerificationPhase
...@@ -189,6 +200,7 @@ object Main { ...@@ -189,6 +200,7 @@ object Main {
else if (evalF) EvaluationPhase else if (evalF) EvaluationPhase
else if (inferInvF) InferInvariantsPhase else if (inferInvF) InferInvariantsPhase
else if (instrumentF) InstrumentationPhase andThen FileOutputPhase else if (instrumentF) InstrumentationPhase andThen FileOutputPhase
else if (gencF) GenerateCPhase andThen CFileOutputPhase
else verification else verification
} }
......
/* Copyright 2009-2015 EPFL, Lausanne */
package leon
package genc
import java.io.File
import java.io.FileWriter
import java.io.BufferedWriter
object CFileOutputPhase extends UnitPhase[CAST.Prog] {
val name = "C File Output"
val description = "Output converted C program to the specified file (default leon.c)"
val optOutputFile = new LeonOptionDef[String] {
val name = "o"
val description = "Output file"
val default = "leon.c"
val usageRhs = "file"
val parser = OptionParsers.stringParser
}
override val definedOptions: Set[LeonOptionDef[Any]] = Set(optOutputFile)
def apply(ctx: LeonContext, program: CAST.Prog) {
// Get the output file name from command line options, or use default
val outputFile = new File(ctx.findOptionOrDefault(optOutputFile))
val parent = outputFile.getParentFile()
try {
if (parent != null) {
parent.mkdirs()
}
} catch {
case _ : java.io.IOException => ctx.reporter.fatalError("Could not create directory " + parent)
}
// Output C code to the file
try {
val fstream = new FileWriter(outputFile)
val out = new BufferedWriter(fstream)
val p = new CPrinter
p.print(program)
out.write(p.toString)
out.close()
ctx.reporter.info(s"Output written to $outputFile")
} catch {
case _ : java.io.IOException => ctx.reporter.fatalError("Could not write on " + outputFile)
}
}
}
/* Copyright 2009-2015 EPFL, Lausanne */
package leon
package genc
import purescala.Definitions.Program
object GenerateCPhase extends SimpleLeonPhase[Program, CAST.Prog] {
val name = "Generate C"
val description = "Generate equivalent C code from Leon's AST"
def apply(ctx: LeonContext, program: Program) = {
ctx.reporter.debug("Running code conversion phase: " + name)(utils.DebugSectionLeon)
val cprogram = new CConverter(ctx, program).convert
cprogram
}
}
...@@ -24,6 +24,7 @@ case object DebugSectionXLang extends DebugSection("xlang", 1 << 1 ...@@ -24,6 +24,7 @@ case object DebugSectionXLang extends DebugSection("xlang", 1 << 1
case object DebugSectionTypes extends DebugSection("types", 1 << 13) case object DebugSectionTypes extends DebugSection("types", 1 << 13)
case object DebugSectionIsabelle extends DebugSection("isabelle", 1 << 14) case object DebugSectionIsabelle extends DebugSection("isabelle", 1 << 14)
case object DebugSectionReport extends DebugSection("report", 1 << 15) case object DebugSectionReport extends DebugSection("report", 1 << 15)
case object DebugSectionGenC extends DebugSection("genc", 1 << 16)
object DebugSections { object DebugSections {
val all = Set[DebugSection]( val all = Set[DebugSection](
...@@ -42,6 +43,7 @@ object DebugSections { ...@@ -42,6 +43,7 @@ object DebugSections {
DebugSectionXLang, DebugSectionXLang,
DebugSectionTypes, DebugSectionTypes,
DebugSectionIsabelle, DebugSectionIsabelle,
DebugSectionReport DebugSectionReport,
DebugSectionGenC
) )
} }
...@@ -9,7 +9,7 @@ import leon.solvers.isabelle.AdaptationPhase ...@@ -9,7 +9,7 @@ import leon.solvers.isabelle.AdaptationPhase
import leon.verification.InjectAsserts import leon.verification.InjectAsserts
import leon.xlang.{NoXLangFeaturesChecking, XLangDesugaringPhase} import leon.xlang.{NoXLangFeaturesChecking, XLangDesugaringPhase}
class PreprocessingPhase(desugarXLang: Boolean = false) extends LeonPhase[Program, Program] { class PreprocessingPhase(desugarXLang: Boolean = false, genc: Boolean = false) extends LeonPhase[Program, Program] {
val name = "preprocessing" val name = "preprocessing"
val description = "Various preprocessings on Leon programs" val description = "Various preprocessings on Leon programs"
...@@ -39,19 +39,27 @@ class PreprocessingPhase(desugarXLang: Boolean = false) extends LeonPhase[Progra ...@@ -39,19 +39,27 @@ class PreprocessingPhase(desugarXLang: Boolean = false) extends LeonPhase[Progra
CheckADTFieldsTypes andThen CheckADTFieldsTypes andThen
InliningPhase InliningPhase
val pipeX = if(desugarXLang) { val pipeX = if (!genc && desugarXLang) {
// Do not desugar when generating C code
XLangDesugaringPhase andThen XLangDesugaringPhase andThen
debugTrees("Program after xlang desugaring") debugTrees("Program after xlang desugaring")
} else { } else {
NoopPhase[Program]() NoopPhase[Program]()
} }
def pipeEnd = if (genc) {
// No InjectAsserts, FunctionClosure and AdaptationPhase phases
NoopPhase[Program]()
} else {
InjectAsserts andThen
FunctionClosure andThen
AdaptationPhase
}
val phases = val phases =
pipeBegin andThen pipeBegin andThen
pipeX andThen pipeX andThen
InjectAsserts andThen pipeEnd andThen
FunctionClosure andThen
AdaptationPhase andThen
debugTrees("Program after pre-processing") debugTrees("Program after pre-processing")
phases.run(ctx, p) phases.run(ctx, p)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment