Skip to content
Snippets Groups Projects
Commit 134b920c authored by Per's avatar Per
Browse files

return command

parent 081c1e30
No related branches found
No related tags found
No related merge requests found
use crust::{
ast::{Expr, Func, Op, Span, SpanExpr},
ast::{Block, Cmd, Expr, Func, Op, Span, SpanExpr},
parse::{parse_block, parse_expr},
};
......@@ -11,7 +11,8 @@ use inkwell::{
passes::PassManager,
types::BasicTypeEnum,
values::{
BasicValueEnum, FloatValue, FunctionValue, IntValue, PointerValue,
BasicValueEnum, FloatValue, FunctionValue, InstructionValue, IntValue,
PointerValue,
},
FloatPredicate, OptimizationLevel,
};
......@@ -29,16 +30,15 @@ fn main() -> Result<(), Box<dyn Error>> {
let execution_engine =
module.create_jit_execution_engine(OptimizationLevel::None)?;
// match parse_block(Span::new(
// "
// {
// return = 2 + 3;
// }
// ",
// ))
match parse_expr(Span::new("2 + 3")) {
Ok((_, expr)) => {
println!("{:?}", &expr);
match parse_block(Span::new(
"
{
return 2 + 3
}
",
)) {
Ok((_, prog)) => {
println!("{:?}", &prog);
let u32_type = context.i32_type();
let fn_type = u32_type.fn_type(&[], false);
let function = module.add_function("expr", fn_type, None);
......@@ -49,10 +49,11 @@ fn main() -> Result<(), Box<dyn Error>> {
context: &context,
builder: &builder,
module: &module,
fn_value_opt: Some(function),
//&fpm,
};
let res = compiler.compile_expr(&expr);
builder.build_return(Some(&res));
let res = compiler.compile_block(prog);
// builder.build_return(Some(&res));
let fun_expr: JitFunction<ExprFunc> =
unsafe { execution_engine.get_function("expr").ok().unwrap() };
......@@ -75,10 +76,22 @@ pub struct Compiler<'a> {
// pub function: &'a Func<'a>,
// variables: HashMap<String, PointerValue>,
// fn_value_opt: Option<FunctionValue>,
fn_value_opt: Option<FunctionValue>,
}
impl<'a> Compiler<'a> {
/// Gets a defined function given its name.
#[inline]
fn get_function(&self, name: &str) -> Option<FunctionValue> {
self.module.get_function(name)
}
/// Returns the `FunctionValue` representing the function being compiled.
#[inline]
fn fn_value(&self) -> FunctionValue {
self.fn_value_opt.unwrap()
}
fn compile_expr(&self, expr: &SpanExpr) -> IntValue {
match expr.1.clone() {
Expr::Num(i) => self.context.i32_type().const_int(i as u64, false),
......@@ -87,26 +100,87 @@ impl<'a> Compiler<'a> {
let lv = self.compile_expr(&l);
let rv = self.compile_expr(&r);
match op {
Op::Add => self.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),
Op::Add => self.builder.build_int_add(lv, rv, "sum"),
_ => unimplemented!(),
}
}
// Expr::UnaryOp(op, e) => {
// let e = eval_expr(&e);
// match op {
// Op::Add => e,
// Op::Sub => -e,
// _ => unimplemented!(),
_ => unimplemented!(),
}
}
/// Creates a new stack allocation instruction in the entry block of the function.
fn create_entry_block_alloca(&self, name: &str) -> PointerValue {
let builder = self.context.create_builder();
let entry = self.fn_value().get_first_basic_block().unwrap();
match entry.get_first_instruction() {
Some(first_instr) => builder.position_before(&first_instr),
None => builder.position_at_end(&entry),
}
builder.build_alloca(self.context.f64_type(), name)
}
fn compile_cmd(&self, cmd: &Cmd) -> (InstructionValue, bool) {
println!("{:?}", cmd);
match cmd {
// Cmd::Assign(lexp, rexp) => {
// let rval = eval_expr(rexp, mem, venv, fenv);
// println!("val {:?}", rval);
// let addr = eval_lvalue(lexp, mem, venv, fenv);
// // println!("lval {:?}", lval);
// // let addr = venv.get(&lval).unwrap();
// mem.Menv.insert(addr, rval);
// None
// }
// Cmd::If(exp, then_block, opt_else) => {
// if get_bool(eval_expr(exp, mem, venv, fenv)) {
// eval_body(then_block.to_vec(), mem, venv, fenv)
// } else {
// if let Some(else_block) = opt_else {
// eval_body(else_block.to_vec(), mem, venv, fenv)
// } else {
// None
// }
// }
// }
// Cmd::Let(_, id, _, exp) => {
// let val = eval_expr(exp, stack, fenv);
// println!("val {:?}", val);
// // let addr = mem.alloc(); // get new allocation slot
// // mem.Menv.insert(addr, val); // write the new value
// // venv.insert(id.to_owned(), addr);
// // dump("after Let", mem, venv);
// None
// }
Cmd::Return(exp) => {
let expr = self.compile_expr(exp);
(self.builder.build_return(Some(&expr)), true)
}
// Cmd::While(exp, body) => {
// while get_bool(eval_expr(exp, mem, venv, fenv)) {
// if let Some(retv) = eval_body(body.to_vec(), mem, venv, fenv) {
// return Some(retv);
// }
// }
// None
// }
_ => unimplemented!(),
}
}
pub fn compile_block(&self, cmds: Vec<Cmd>) -> InstructionValue {
for c in &cmds {
let (cmd, ret) = self.compile_cmd(c);
if ret {
return cmd;
}
}
panic!();
}
}
// fn main() {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment