verilization_compiler_cli_core/
lib.rs

1use verilization_compiler::*;
2
3use std::env;
4use std::ffi::OsString;
5use lang::{Language, LanguageRegistry, LanguageHandler};
6
7
8fn command_version() -> Result<i32, VError> {
9	let version = env!("CARGO_PKG_VERSION");
10	println!("verilization compiler version {} (native)", version);
11	Ok(0)
12}
13
14fn command_help() -> Result<i32, VError> {
15	let help_message = include_str!("help.txt");
16	println!("{}", help_message);
17	Ok(0)
18}
19
20fn command_generate<Lang: Language>(input_files: Vec<OsString>, options: Lang::Options) -> Result<i32, VError> {
21	let model = load_files(input_files)?;
22
23	Lang::generate(&model, options, &mut FileOutputHandler {})?;
24	Ok(0)
25}
26
27struct ParseGenerateCommand<Args: Iterator<Item = OsString>> {
28	args: Args,
29}
30
31impl <Args: Iterator<Item = OsString>> LanguageHandler for ParseGenerateCommand<Args> {
32	type Result = Result<i32, VError>;
33
34	fn run<Lang: Language>(&mut self) -> Self::Result {
35		let mut input_files = Vec::new();
36		let mut lang_options = Lang::empty_options();
37	
38	
39		while let Some(arg) = self.args.next() {
40			match arg.to_str().unwrap() {
41				"-i" => {
42					if let Some(filename) = self.args.next() {
43						input_files.push(filename)
44					}
45					else {
46						println!("Missing value for input file");
47						return Ok(1);
48					}
49				},
50	
51				arg => {
52					if let Some(option) = arg.strip_prefix("-o:") {
53						if let Some(value) = self.args.next() {
54							Lang::add_option(&mut lang_options, option, value)?;
55						}
56						else {
57							println!("Missing value for option {}", option);
58							return Ok(1);
59						}
60					}
61					else {
62						println!("Unknown argument: {}", arg);
63						return Ok(1);
64					}
65				}
66			}
67		}
68	
69		let lang_options = Lang::finalize_options(lang_options)?;
70	
71		command_generate::<Lang>(input_files, lang_options)
72	}
73}
74
75fn parse_args<Args, Registry: LanguageRegistry>(mut args: Args, registry: &Registry) -> Result<i32, VError> where Args : Iterator<Item = OsString> {
76	while let Some(arg) = args.next() {
77		match arg.to_str().unwrap() {
78			"version" | "--version" | "-v" => return command_version(),
79			"help" | "--help" | "-h" => return command_help(),
80			"generate" => {
81				let lang = match args.next() {
82					Some(lang) => lang,
83					None => {
84						println!("Language not specified");
85						return Ok(1);
86					},
87				};
88
89				let lang = lang.to_str().unwrap();
90
91				match registry.handle_language(lang, &mut ParseGenerateCommand { args }) {
92					Some(result) => return result,
93					None => {
94						println!("Unknown language: {}", lang);
95						return Ok(1);
96					}
97				}
98			},
99				
100			arg => {
101				println!("Unexpected argument: {}", arg);
102				return Ok(1);
103			},
104		}
105	}
106
107	println!("No command specified");
108	Ok(1)
109}
110
111
112pub fn main_impl<Registry: LanguageRegistry>(registry: &Registry) {
113	let mut args = env::args_os();
114	args.next();
115
116	match parse_args(args, registry) {
117		Ok(exit_code) => std::process::exit(exit_code),
118		Err(err) => {
119			println!("{:?}", err);
120			std::process::exit(1)
121		},
122	}
123}