fmt
This commit is contained in:
parent
fdb0a266b1
commit
0eb2b9ec04
6 changed files with 94 additions and 75 deletions
2
build.rs
2
build.rs
|
@ -1,3 +1,3 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
lalrpop::process_root().unwrap();
|
lalrpop::process_root().unwrap();
|
||||||
}
|
}
|
||||||
|
|
2
rustfmt.toml
Normal file
2
rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
max_width = 80
|
||||||
|
tab_spaces = 2
|
58
src/ast.rs
58
src/ast.rs
|
@ -1,58 +0,0 @@
|
||||||
use anyhow::Result;
|
|
||||||
use inkwell::{context::Context, module::Module};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Decl {
|
|
||||||
Func(Func),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Decl {
|
|
||||||
pub fn unwrap_func(&self) -> Option<&Func> {
|
|
||||||
match self {
|
|
||||||
Decl::Func(func) => Some(func),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Func {
|
|
||||||
pub name: String,
|
|
||||||
pub return_ty: Type,
|
|
||||||
pub stmts: Vec<Stmt>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Stmt {
|
|
||||||
Return(Option<Expr>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Expr {
|
|
||||||
Int(i64),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Type {
|
|
||||||
Int,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn convert(context: &mut Context, program: Vec<Decl>) -> Result<Module> {
|
|
||||||
let module = context.create_module("program");
|
|
||||||
let builder = context.create_builder();
|
|
||||||
|
|
||||||
for func in program.iter().filter_map(Decl::unwrap_func) {
|
|
||||||
// TODO: hardcoded void -> int function
|
|
||||||
let i64_ty = context.i64_type();
|
|
||||||
let llvm_func_ty = i64_ty.fn_type(&[], false);
|
|
||||||
|
|
||||||
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
|
||||||
let entry_block = context.append_basic_block(llvm_func, "entry");
|
|
||||||
|
|
||||||
builder.position_at_end(entry_block);
|
|
||||||
|
|
||||||
builder.build_return(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(module)
|
|
||||||
}
|
|
38
src/ast/llvm.rs
Normal file
38
src/ast/llvm.rs
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use inkwell::{
|
||||||
|
context::Context,
|
||||||
|
module::Module,
|
||||||
|
types::{AnyType, AnyTypeEnum},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{Decl, Type};
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
pub fn into_llvm_type<'ctx>(
|
||||||
|
&self,
|
||||||
|
context: &'ctx Context,
|
||||||
|
) -> AnyTypeEnum<'ctx> {
|
||||||
|
match self {
|
||||||
|
Type::Int => AnyTypeEnum::IntType(context.i64_type()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert(context: &mut Context, program: Vec<Decl>) -> Result<Module> {
|
||||||
|
let module = context.create_module("program");
|
||||||
|
let builder = context.create_builder();
|
||||||
|
|
||||||
|
for func in program.iter().filter_map(Decl::unwrap_func) {
|
||||||
|
let return_ty = func.return_ty.into_llvm_type(context);
|
||||||
|
let llvm_func_ty = return_ty.fn_type();
|
||||||
|
|
||||||
|
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
||||||
|
let entry_block = context.append_basic_block(llvm_func, "entry");
|
||||||
|
|
||||||
|
builder.position_at_end(entry_block);
|
||||||
|
|
||||||
|
builder.build_return(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(module)
|
||||||
|
}
|
37
src/ast/mod.rs
Normal file
37
src/ast/mod.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
pub mod llvm;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Decl {
|
||||||
|
Func(Func),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decl {
|
||||||
|
pub fn unwrap_func(&self) -> Option<&Func> {
|
||||||
|
match self {
|
||||||
|
Decl::Func(func) => Some(func),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Func {
|
||||||
|
pub name: String,
|
||||||
|
pub return_ty: Type,
|
||||||
|
pub stmts: Vec<Stmt>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Stmt {
|
||||||
|
Return(Option<Expr>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Expr {
|
||||||
|
Int(i64),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Type {
|
||||||
|
Int,
|
||||||
|
}
|
32
src/main.rs
32
src/main.rs
|
@ -18,29 +18,29 @@ use crate::parser::ProgramParser;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
|
||||||
#[clap(short = 'o', long = "out")]
|
#[clap(short = 'o', long = "out")]
|
||||||
out_path: PathBuf,
|
out_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let opts = Opt::parse();
|
let opts = Opt::parse();
|
||||||
|
|
||||||
let contents = fs::read_to_string(opts.path)?;
|
let contents = fs::read_to_string(opts.path)?;
|
||||||
|
|
||||||
let parser = ProgramParser::new();
|
let parser = ProgramParser::new();
|
||||||
let ast = parser.parse(&contents).unwrap();
|
let ast = parser.parse(&contents).unwrap();
|
||||||
println!("AST: {ast:?}");
|
println!("AST: {ast:?}");
|
||||||
|
|
||||||
let mut context = Context::create();
|
let mut context = Context::create();
|
||||||
let module = ast::convert(&mut context, ast)?;
|
let module = ast::llvm::convert(&mut context, ast)?;
|
||||||
|
|
||||||
{
|
{
|
||||||
let file = File::create(&opts.out_path)?;
|
let file = File::create(&opts.out_path)?;
|
||||||
module.write_bitcode_to_file(&file, true, true);
|
module.write_bitcode_to_file(&file, true, true);
|
||||||
println!("Emitted.");
|
println!("Emitted.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue