-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfpp-to-json.scala
More file actions
108 lines (95 loc) · 2.99 KB
/
fpp-to-json.scala
File metadata and controls
108 lines (95 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package fpp.compiler
import fpp.compiler.analysis._
import fpp.compiler.ast._
import fpp.compiler.codegen._
import fpp.compiler.syntax._
import fpp.compiler.transform._
import fpp.compiler.util._
import scopt.OParser
object FPPtoJson {
case class Options(
syntaxOnly: Boolean = false,
dir: Option[String] = None,
files: List[File] = Nil
)
def command(options: Options) = {
fpp.compiler.util.Error.setTool(Tool(name))
val files = options.files.reverse match {
case Nil => List(File.StdIn)
case list => list
}
for {
tul <- Result.map(files, Parser.parseFile(Parser.transUnit)(None) _)
tul <- resolveIncludes(tul)
_ <- writeAst (options) (tul)
_ <- writeLocMap (options)
_ <- writeAnalysis (options) (tul)
} yield ()
}
def main(args: Array[String]) =
Tool(name).mainMethod(args, oparser, Options(), command)
def writeJson (
options: Options,
fileName: String,
json: io.circe.Json
): Result.Result[Unit] = {
val path =
java.nio.file.Paths.get(options.dir.getOrElse("."), fileName)
val file = File.Path(path)
for (writer <- file.openWrite()) yield {
writer.println(json)
writer.close()
}
}
def writeAst (options: Options) (tul: List[Ast.TransUnit]):
Result.Result[Unit] =
writeJson(options, "fpp-ast.json", AstJsonEncoder.astToJson(tul))
def writeLocMap (options: Options): Result.Result[Unit] =
writeJson(options, "fpp-loc-map.json", LocMapJsonEncoder.locMapToJson)
def writeAnalysis (options: Options) (tul: List[Ast.TransUnit]):
Result.Result[Unit] =
options.syntaxOnly match {
case false =>
val files = options.files.reverse match {
case Nil => List(File.StdIn)
case list => list
}
val a = Analysis(inputFileSet = options.files.toSet)
for {
a <- CheckSemantics.tuList(a, tul)
_ <- writeJson(options, "fpp-analysis.json", AnalysisJsonEncoder.analysisToJson(a))
} yield ()
case true => Right(())
}
def resolveIncludes(tul: List[Ast.TransUnit]):
Result.Result[List[Ast.TransUnit]] =
for {
result <- ResolveSpecInclude.transformList(
Analysis(),
tul,
ResolveSpecInclude.transUnit
)
} yield result._2
val builder = OParser.builder[Options]
val name = "fpp-to-json"
val oparser = {
import builder._
OParser.sequence(
programName(name),
head(name, Version.v),
opt[Unit]('s', "syntax only")
.action((_, c) => c.copy(syntaxOnly = true))
.text("emit syntax only (location map and abstract syntax tree)"),
opt[String]('d', "directory")
.valueName("<dir>")
.action((d, c) => c.copy(dir = Some(d)))
.text("output directory"),
help('h', "help").text("print this message and exit"),
arg[String]("file ...")
.unbounded()
.optional()
.action((f, c) => c.copy(files = File.fromString(f) :: c.files))
.text("input files")
)
}
}