Files
Will Hawkins e17533dfc8
Continuous Integration / Grammar Tests (push) Successful in 36s
Continuous Integration / Library Format Tests (push) Successful in 1m19s
Continuous Integration / Library Tests (push) Successful in 3m51s
Make Formatter Happy
Signed-off-by: Will Hawkins <hawkinsw@obs.cr>
2026-06-12 06:34:57 -04:00

156 lines
4.7 KiB
Swift

// p4rse, Copyright 2026, Will Hawkins
//
// This file is part of p4rse.
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import ArgumentParser
import Common
import P4Compiler
import P4Runtime
import SystemPackage
@main
struct Cli: ParsableCommand {
@Flag(help: "Disable ANSI-stylized output.") var plain: Int
static let configuration = CommandConfiguration(
abstract: "P4CE compiler, interpreter and debugger.",
subcommands: [Preprocess.self, Compile.self, CodeGen.self])
}
struct CliOptions: ParsableArguments {
@ArgumentParser.Argument(help: "File to compile.") // Have to be explicit because Common has an Argument, too!
var path: String
@Option(name: [.customShort("I")], help: "Search paths.")
var search: [String] = []
}
extension Cli {
struct Preprocess: ParsableCommand {
static let configuration = CommandConfiguration(abstract: "Compile P4CE code.")
@ParentCommand var parent: Cli
@OptionGroup var options: CliOptions
mutating func run() {
let sm = SourceManager(options.search.map { FilePath($0) })
let prep = SourceCodePreprocessor(sm)
let file = FilePath(options.path)
let formatter: any Formattable =
if parent.plain != 0 {
FormatterPlain()
} else {
FormatterAnsi()
}
let maybe_source = prep.preprocess(file)
guard case .Ok(let source) = maybe_source else {
print(ErrorWithLabel("Preprocessor Error", maybe_source.error()!).format(formatter))
return
}
print(source.getSource())
}
}
}
extension Cli {
struct Compile: ParsableCommand {
static let configuration = CommandConfiguration(abstract: "Compile P4CE code.")
@ParentCommand var parent: Cli
@OptionGroup var options: CliOptions
mutating func run() {
let sm = SourceManager(options.search.map { FilePath($0) })
let prep = SourceCodePreprocessor(sm)
let file = FilePath(options.path)
let formatter: any Formattable =
if parent.plain != 0 {
FormatterPlain()
} else {
FormatterAnsi()
}
let maybe_source = prep.preprocess(file)
guard case .Ok(let source) = maybe_source else {
print(ErrorWithLabel("Preprocessor Error", maybe_source.error()!).format(formatter))
return
}
let maybe_program = SpecialCompilers.ProgramCompiler.Compile(source.getSource())
guard case .Ok(_) = maybe_program else {
let feedback = CompilationFeedback(source, [maybe_program.error()!], formatter)
print(feedback.feedback)
return
}
print(
formatter.formatWithStyle(
"Success", Style(StyleColor.Green, [StyleFormat.Underline])))
}
}
}
extension Cli {
struct CodeGen: ParsableCommand {
static let configuration = CommandConfiguration(abstract: "Generate P4CE code.")
@ParentCommand var parent: Cli
@OptionGroup var options: CliOptions
mutating func run() {
let sm = SourceManager(options.search.map { FilePath($0) })
let prep = SourceCodePreprocessor(sm)
let file = FilePath(options.path)
let formatter: any Formattable =
if parent.plain != 0 {
FormatterPlain()
} else {
FormatterAnsi()
}
let maybe_source = prep.preprocess(file)
guard case .Ok(let source) = maybe_source else {
print(ErrorWithLabel("Preprocessor Error", maybe_source.error()!).format(formatter))
return
}
let maybe_program = SpecialCompilers.ProgramCompiler.Compile(source.getSource())
guard case .Ok(let program) = maybe_program else {
print(ErrorWithLabel("Compiler Error", maybe_source.error()!).format(formatter))
return
}
/*
let maybe_codegen = P4Runtime.CodeGenerator().codeGen(program)
guard case .Ok(let codegen) = maybe_codegen else {
let formatter = FormatterAnsi()
print(ErrorWithLabel("Code Generation Error", maybe_codegen.error()!).format(formatter))
return
}
print("\(codegen.getGeneratedCode())")
*/
}
}
}