116 lines
3.6 KiB
Rust
116 lines
3.6 KiB
Rust
use std::{io::Read, path::PathBuf};
|
|
|
|
use clap::Command;
|
|
use compiler::{
|
|
lexer::Tokenizer,
|
|
parser::Tree,
|
|
triples::{MirBuilder, IR},
|
|
};
|
|
|
|
fn main() {
|
|
let cmd = clap::Command::new("sea")
|
|
.bin_name("sea")
|
|
.arg(
|
|
clap::Arg::new("input")
|
|
.short('i')
|
|
.help("sea source file.")
|
|
.value_parser(clap::builder::PathBufValueParser::new()),
|
|
)
|
|
.subcommands([
|
|
Command::new("ast").about("output AST."),
|
|
Command::new("ast2").about("output AST."),
|
|
Command::new("mir").about("output machine-level intermediate representation."),
|
|
Command::new("ir").about("output intermediate representation."),
|
|
Command::new("asm").about("output x86-64 assembly (intel syntax)."),
|
|
]);
|
|
|
|
let matches = cmd.get_matches();
|
|
let path = matches.get_one::<PathBuf>("input");
|
|
let source = path
|
|
.and_then(|p| std::fs::read(p).ok())
|
|
.or_else(|| {
|
|
let mut buf = Vec::new();
|
|
std::io::stdin().read(&mut buf).ok()?;
|
|
Some(buf)
|
|
})
|
|
.expect("no source bytes.");
|
|
|
|
let tokens = Tokenizer::new(&source).unwrap();
|
|
|
|
let mut tree = Tree::new();
|
|
tree.parse(tokens.iter()).unwrap();
|
|
tree.fold_comptime();
|
|
|
|
if let Some((cmd, _matches)) = matches.subcommand() {
|
|
match cmd {
|
|
"ast" => {
|
|
let mut buf = String::new();
|
|
tree.render(&mut buf).unwrap();
|
|
println!("AST:\n{buf}");
|
|
}
|
|
"ast2" => {
|
|
let mut tree2 = compiler::ast2::ast_gen::Parser::new();
|
|
tree2.parse(tokens.iter());
|
|
eprintln!("{tree2:#?}");
|
|
println!("AST (new):\n{tree2}");
|
|
}
|
|
"ir" => {
|
|
let mut ir = IR::new();
|
|
let builder = ir.build(&mut tree);
|
|
let mut buf = String::new();
|
|
builder.render(&mut buf).unwrap();
|
|
println!("IR:\n{buf}");
|
|
}
|
|
"mir" => {
|
|
let mut ir = IR::new();
|
|
ir.build(&mut tree);
|
|
|
|
let mut mir = MirBuilder::new(&ir, tree.strings);
|
|
mir.build();
|
|
|
|
let MirBuilder {
|
|
strings, functions, ..
|
|
} = mir;
|
|
|
|
for (name, mir) in functions {
|
|
println!("{}:\n{}", strings.get_str(name), mir.display(&strings));
|
|
}
|
|
}
|
|
"asm" => {
|
|
let mut ir = IR::new();
|
|
ir.build(&mut tree);
|
|
|
|
let mut mir = MirBuilder::new(&ir, tree.strings);
|
|
mir.build();
|
|
|
|
let MirBuilder {
|
|
globals,
|
|
strings,
|
|
functions,
|
|
..
|
|
} = mir;
|
|
|
|
println!(".intel_syntax");
|
|
println!(".text");
|
|
for (_name, mir) in globals {
|
|
let assembly = mir
|
|
.assemble(&strings)
|
|
.unwrap()
|
|
.finish_constants(&strings)
|
|
.unwrap();
|
|
println!("{assembly}");
|
|
}
|
|
for (_name, mir) in functions {
|
|
let assembly = mir
|
|
.assemble(&strings)
|
|
.unwrap()
|
|
.finish_as_function(&strings)
|
|
.unwrap();
|
|
println!("{assembly}");
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|