Skip to content
Snippets Groups Projects
Commit 081c1e30 authored by Per's avatar Per
Browse files

refactored

parent f054aa2d
No related branches found
No related tags found
No related merge requests found
use crust::{ use crust::{
ast::{Expr, Func, Op, Span, SpanExpr}, ast::{Expr, Func, Op, Span, SpanExpr},
parse::parse_expr, parse::{parse_block, parse_expr},
}; };
use inkwell::{ use inkwell::{
...@@ -16,97 +16,45 @@ use inkwell::{ ...@@ -16,97 +16,45 @@ use inkwell::{
FloatPredicate, OptimizationLevel, FloatPredicate, OptimizationLevel,
}; };
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
type ExprFunc = unsafe extern "C" fn() -> i32; type ExprFunc = unsafe extern "C" fn() -> i32;
fn compile_expr( fn main() -> Result<(), Box<dyn Error>> {
expr: &SpanExpr, let context = Context::create();
context: &Context, let mut module = context.create_module("expr");
module: &Module, let builder = context.create_builder();
builder: &Builder, let fpm = PassManager::create(&module);
) -> IntValue { fpm.initialize();
match expr.1.clone() { let execution_engine =
Expr::Num(i) => context.i32_type().const_int(i as u64, false), module.create_jit_execution_engine(OptimizationLevel::None)?;
Expr::BinOp(op, l, r) => { // match parse_block(Span::new(
let lv = compile_expr(&l, context, module, builder); // "
let rv = compile_expr(&r, context, module, builder); // {
match op { // return = 2 + 3;
Op::Add => builder.build_int_add(lv, rv, "sum")
,
// Op::Sub => lv - rv,
// Op::Mul => lv * rv,
// Op::Div => lv / rv,
// Op::Pow => lv.pow(rv as u32),
_ => unimplemented!(),
}
}
// Expr::UnaryOp(op, e) => {
// let e = eval_expr(&e);
// match op {
// Op::Add => e,
// Op::Sub => -e,
// _ => unimplemented!(),
// }
// } // }
_ => unimplemented!(), // ",
} // ))
} match parse_expr(Span::new("2 + 3")) {
Ok((_, expr)) => {
fn jit_compile_sum( println!("{:?}", &expr);
expr: &SpanExpr,
context: &Context,
module: &Module,
builder: &Builder,
execution_engine: &ExecutionEngine,
) -> Option<JitFunction<ExprFunc>> {
let u32_type = context.i32_type(); let u32_type = context.i32_type();
let fn_type = u32_type.fn_type(&[], false); let fn_type = u32_type.fn_type(&[], false);
let function = module.add_function("expr", fn_type, None); let function = module.add_function("expr", fn_type, None);
let basic_block = context.append_basic_block(&function, "entry"); let basic_block = context.append_basic_block(&function, "entry");
builder.position_at_end(&basic_block); builder.position_at_end(&basic_block);
// let x = context.i32_type().const_int(1, false); let mut compiler = Compiler {
// let y = context.i32_type().const_int(42, false); context: &context,
// let z = context.i32_type().const_int(3, false); builder: &builder,
module: &module,
// let sum = builder.build_int_add(x, y, "sum"); //&fpm,
// let sum = builder.build_int_add(sum, z, "sum"); };
// builder.build_return(Some(&sum)); let res = compiler.compile_expr(&expr);
let res = compile_expr(expr, context, module, builder);
builder.build_return(Some(&res)); builder.build_return(Some(&res));
let fun_expr: JitFunction<ExprFunc> =
unsafe { execution_engine.get_function("expr").ok() } unsafe { execution_engine.get_function("expr").ok().unwrap() };
}
fn main() -> Result<(), Box<dyn Error>> {
let context = Context::create();
let mut module = context.create_module("expr");
let builder = context.create_builder();
let execution_engine =
module.create_jit_execution_engine(OptimizationLevel::None)?;
// let passmanager = PassManager::create(input: I)
match parse_expr(Span::new(
"
2 + 3
",
)) {
Ok((_, e)) => {
println!("{:?}", &e);
let fun_expr = jit_compile_sum(
&e,
&context,
&module,
&builder,
&execution_engine,
)
.ok_or("Unable to JIT compile `expr`")?;
unsafe { unsafe {
println!("{}", fun_expr.call()); println!("{}", fun_expr.call());
...@@ -119,31 +67,46 @@ fn main() -> Result<(), Box<dyn Error>> { ...@@ -119,31 +67,46 @@ fn main() -> Result<(), Box<dyn Error>> {
Ok(()) Ok(())
} }
pub fn eval_expr(e: &SpanExpr) -> i32 { pub struct Compiler<'a> {
match e.1.clone() { pub context: &'a Context,
Expr::Num(i) => i, pub builder: &'a Builder,
// pub fpm: &'a PassManager<FunctionValue>,
pub module: &'a Module,
// pub function: &'a Func<'a>,
// variables: HashMap<String, PointerValue>,
// fn_value_opt: Option<FunctionValue>,
}
impl<'a> Compiler<'a> {
fn compile_expr(&self, expr: &SpanExpr) -> IntValue {
match expr.1.clone() {
Expr::Num(i) => self.context.i32_type().const_int(i as u64, false),
Expr::BinOp(op, l, r) => { Expr::BinOp(op, l, r) => {
let lv = eval_expr(&l); let lv = self.compile_expr(&l);
let rv = eval_expr(&r); let rv = self.compile_expr(&r);
match op { match op {
Op::Add => lv + rv, Op::Add => self.builder.build_int_add(lv, rv, "sum")
Op::Sub => lv - rv, ,
Op::Mul => lv * rv, // Op::Sub => lv - rv,
Op::Div => lv / rv, // Op::Mul => lv * rv,
Op::Pow => lv.pow(rv as u32), // Op::Div => lv / rv,
// Op::Pow => lv.pow(rv as u32),
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
Expr::UnaryOp(op, e) => { // Expr::UnaryOp(op, e) => {
let e = eval_expr(&e); // let e = eval_expr(&e);
match op { // match op {
Op::Add => e, // Op::Add => e,
Op::Sub => -e, // Op::Sub => -e,
// _ => unimplemented!(),
// }
// }
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
_ => unimplemented!(),
}
} }
// fn main() { // fn main() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment