e0/bin/e0c.rs

95 lines
2.7 KiB
Rust
Raw Normal View History

2022-04-06 03:07:34 +00:00
use std::fs::{self, File};
2022-07-18 02:00:19 +00:00
use std::io::Write;
2022-04-06 02:33:16 +00:00
use std::path::PathBuf;
use std::process::ExitCode;
2022-04-06 02:33:16 +00:00
use anyhow::Result;
use clap::Parser;
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use codespan_reporting::term::{self, Config as CodespanConfig};
use e0::ast::typeck_bidi::TypeChecker;
2022-07-18 08:21:39 +00:00
use e0::codegen::llvm_ir::LlvmIrCodegen;
use e0::codegen::CodegenBackend;
2022-07-18 08:21:39 +00:00
use e0::parser::ProgramParser;
use lalrpop_util::ParseError;
2022-04-06 02:33:16 +00:00
#[derive(Debug, Parser)]
struct Opt {
2022-04-06 03:17:53 +00:00
path: PathBuf,
2022-04-06 03:07:34 +00:00
2022-04-06 04:32:37 +00:00
/// Path to output the bitcode to.
#[clap(short = 'o', long = "out", name = "bitcode-out")]
2022-04-06 03:17:53 +00:00
out_path: PathBuf,
2022-04-06 04:32:37 +00:00
/// Path to output the AST to, if at all.
#[clap(long = "emit-ast", name = "ast-out")]
emit_ast: Option<PathBuf>,
2022-04-06 02:33:16 +00:00
}
fn main() -> Result<ExitCode> {
2022-04-06 03:17:53 +00:00
let opts = Opt::parse();
2022-04-06 02:33:16 +00:00
// Set up reporting
let mut files = SimpleFiles::new();
let writer = StandardStream::stderr(ColorChoice::Always);
let config = CodespanConfig::default();
2022-04-06 11:20:47 +00:00
let contents = fs::read_to_string(&opts.path)?;
let file_id = files.add(opts.path.display().to_string(), &contents);
2022-04-06 02:33:16 +00:00
2022-04-06 03:17:53 +00:00
let parser = ProgramParser::new();
let ast = match parser.parse(&contents) {
Ok(v) => v,
Err(err) => {
let loc = match err {
ParseError::InvalidToken { location }
| ParseError::UnrecognizedEOF { location, .. } => (location, location),
ParseError::UnrecognizedToken { ref token, .. }
| ParseError::ExtraToken { ref token } => (token.0, token.2),
_ => todo!(),
};
let diagnostic = Diagnostic::error()
.with_labels(vec![Label::primary(file_id, loc.0..loc.1)])
.with_message(err.to_string());
term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
return Ok(ExitCode::FAILURE);
}
};
2022-04-06 02:33:16 +00:00
let type_checker = TypeChecker::default();
let typed_ast = match type_checker.convert(ast) {
Ok(v) => v,
Err(err) => {
let diagnostic = Diagnostic::error().with_message(err.to_string());
term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
return Ok(ExitCode::FAILURE);
}
};
2022-04-06 11:20:47 +00:00
2022-07-18 02:00:19 +00:00
if let Some(path) = opts.emit_ast {
let mut file = File::create(&path)?;
file.write(format!("{:#?}", typed_ast).as_bytes())?;
}
2022-04-06 03:07:34 +00:00
2022-04-06 03:17:53 +00:00
{
let file = File::create(&opts.out_path)?;
2022-07-18 02:00:19 +00:00
let mut codegen = LlvmIrCodegen::new(file);
codegen.convert(typed_ast)?;
2022-04-06 03:17:53 +00:00
}
2022-04-06 03:07:34 +00:00
2022-07-18 02:00:19 +00:00
// let ctx = ast::cranelift::convert(
// opts.path.display().to_string(),
// typed_ast,
// )?;
// {
// let file = File::create(&opts.out_path)?;
// ctx.compile_and_emit();
// println!("Emitted.");
// }
Ok(ExitCode::SUCCESS)
2022-04-06 02:33:16 +00:00
}