Skip to content
Snippets Groups Projects
Commit 4930f443 authored by Per Lindgren's avatar Per Lindgren
Browse files

wip 0.1

parent a0d0464c
No related branches found
No related tags found
No related merge requests found
......@@ -112,53 +112,61 @@ impl JIT {
// the_return: String,
// stmts: Vec<Expr>,
) -> Result<(), String> {
// // Our toy language currently only supports I64 values, though Cranelift
// // supports other types.
// let int = self.module.target_config().pointer_type();
// Our toy language currently only supports I64 values, though Cranelift
// supports other types.
// for _p in &params {
// self.ctx.func.signature.params.push(AbiParam::new(int));
// }
// Per: ok let i32 be an I64 for now, does not really matter
let int = self.module.target_config().pointer_type();
// // Our toy language currently only supports one return value, though
// // Cranelift is designed to support more.
// self.ctx.func.signature.returns.push(AbiParam::new(int));
println!("set params");
for _p in &f.params.0 {
println!("id {:?}", _p.id);
self.ctx.func.signature.params.push(AbiParam::new(int));
}
// // Create the builder to build a function.
// let mut builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_context);
println!("set return value");
// Our toy language currently only supports one return value, though
// Cranelift is designed to support more.
self.ctx.func.signature.returns.push(AbiParam::new(int));
// // Create the entry block, to start emitting code in.
// let entry_block = builder.create_block();
// Create the builder to build a function.
let mut builder = FunctionBuilder::new(&mut self.ctx.func, &mut self.builder_context);
// // Since this is the entry block, add block parameters corresponding to
// // the function's parameters.
// //
// // TODO: Streamline the API here.
// builder.append_block_params_for_function_params(entry_block);
// Create the entry block, to start emitting code in.
let entry_block = builder.create_block();
// Since this is the entry block, add block parameters corresponding to
// the function's parameters.
//
// TODO: Streamline the API here.
builder.append_block_params_for_function_params(entry_block);
// Tell the builder to emit code in this block.
builder.switch_to_block(entry_block);
// // Tell the builder to emit code in this block.
// builder.switch_to_block(entry_block);
// And, tell the builder that this block will have no further
// predecessors. Since it's the entry block, it won't have any
// predecessors.
builder.seal_block(entry_block);
// // And, tell the builder that this block will have no further
// // predecessors. Since it's the entry block, it won't have any
// // predecessors.
// builder.seal_block(entry_block);
// The toy language allows variables to be declared implicitly.
// Walk the AST and declare all implicitly-declared variables.
// // The toy language allows variables to be declared implicitly.
// // Walk the AST and declare all implicitly-declared variables.
// Per: Not sure how we deal with introducing variables on the fly
// let variables =
// declare_variables(int, &mut builder, &params, &the_return, &stmts, entry_block);
// // Now translate the statements of the function body.
// let mut trans = FunctionTranslator {
// int,
// builder,
// variables,
// module: &mut self.module,
// };
// for expr in stmts {
// trans.translate_expr(expr);
// }
let variables = HashMap::<Id, Variable>::new();
// Now translate the statements of the function body.
let mut trans = FunctionTranslator {
int,
builder,
variables,
module: &mut self.module,
};
for expr in stmts {
trans.translate_expr(expr);
}
// // Set up the return variable of the function. Above, we declared a
// // variable to hold the return value. Here, we just do a use of that
......@@ -173,26 +181,26 @@ impl JIT {
// trans.builder.finalize();
Ok(())
}
// }
// /// A collection of state used for translating from toy-language AST nodes
// /// into Cranelift IR.
// struct FunctionTranslator<'a> {
// int: types::Type,
// builder: FunctionBuilder<'a>,
// variables: HashMap<String, Variable>,
// module: &'a mut Module<SimpleJITBackend>,
// }
}
/// A collection of state used for translating from toy-language AST nodes
/// into Cranelift IR.
struct FunctionTranslator<'a> {
int: types::Type,
builder: FunctionBuilder<'a>,
variables: HashMap<String, Variable>,
module: &'a mut Module<SimpleJITBackend>,
}
// impl<'a> FunctionTranslator<'a> {
// /// When you write out instructions in Cranelift, you get back `Value`s. You
// /// can then use these references in other instructions.
// fn translate_expr(&mut self, expr: Expr) -> Value {
// match expr {
// Expr::Literal(literal) => {
// let imm: i32 = literal.parse().unwrap();
// self.builder.ins().iconst(self.int, i64::from(imm))
// }
impl<'a> FunctionTranslator<'a> {
/// When you write out instructions in Cranelift, you get back `Value`s. You
/// can then use these references in other instructions.
fn translate_expr(&mut self, expr: Expr) -> Value {
match expr {
Expr::Num(literal) => self.builder.ins().iconst(self.int, i64::from(literal)),
_ => unimplemented!(),
}
}
}
// Expr::Add(lhs, rhs) => {
// let lhs = self.translate_expr(*lhs);
......@@ -369,7 +377,6 @@ impl JIT {
// self.builder.ins().iconst(self.int, 0)
// }
// }
// }
// fn translate_call(&mut self, name: String, args: Vec<Expr>) -> Value {
// let mut sig = self.module.make_signature();
......@@ -411,46 +418,45 @@ impl JIT {
// let pointer = self.module.target_config().pointer_type();
// self.builder.ins().symbol_value(pointer, local_id)
// }
}
// fn declare_variables(
// int: types::Type,
// builder: &mut FunctionBuilder,
// params: &[String],
// the_return: &str,
// stmts: &[Expr],
// entry_block: Block,
// ) -> HashMap<String, Variable> {
// let mut variables = HashMap::new();
// let mut index = 0;
// for (i, name) in params.iter().enumerate() {
// // TODO: cranelift_frontend should really have an API to make it easy to set
// // up param variables.
// let val = builder.block_params(entry_block)[i];
// let var = declare_variable(int, builder, &mut variables, &mut index, name);
// builder.def_var(var, val);
// }
// let zero = builder.ins().iconst(int, 0);
// let return_variable = declare_variable(int, builder, &mut variables, &mut index, the_return);
// builder.def_var(return_variable, zero);
// for expr in stmts {
// declare_variables_in_stmt(int, builder, &mut variables, &mut index, expr);
// }
fn declare_variables(
int: types::Type,
builder: &mut FunctionBuilder,
params: &[String],
the_return: &str,
stmts: &[Expr],
entry_block: Block,
) -> HashMap<String, Variable> {
let mut variables = HashMap::new();
let mut index = 0;
for (i, name) in params.iter().enumerate() {
// TODO: cranelift_frontend should really have an API to make it easy to set
// up param variables.
let val = builder.block_params(entry_block)[i];
let var = declare_variable(int, builder, &mut variables, &mut index, name);
builder.def_var(var, val);
}
let zero = builder.ins().iconst(int, 0);
let return_variable = declare_variable(int, builder, &mut variables, &mut index, the_return);
builder.def_var(return_variable, zero);
for expr in stmts {
declare_variables_in_stmt(int, builder, &mut variables, &mut index, expr);
}
// variables
// }
variables
}
// /// Recursively descend through the AST, translating all implicit
// /// variable declarations.
// fn declare_variables_in_stmt(
// int: types::Type,
// builder: &mut FunctionBuilder,
// variables: &mut HashMap<String, Variable>,
// index: &mut usize,
// expr: &Expr,
// ) {
// match *expr {
/// Recursively descend through the AST, translating all implicit
/// variable declarations.
fn declare_variables_in_stmt(
int: types::Type,
builder: &mut FunctionBuilder,
variables: &mut HashMap<String, Variable>,
index: &mut usize,
expr: &Expr,
) {
match *expr {
// Expr::Assign(ref name, _) => {
// declare_variable(int, builder, variables, index, name);
// }
......@@ -467,23 +473,23 @@ impl JIT {
// declare_variables_in_stmt(int, builder, variables, index, &stmt);
// }
// }
// _ => (),
// }
// }
_ => (),
}
}
// /// Declare a single variable declaration.
// fn declare_variable(
// int: types::Type,
// builder: &mut FunctionBuilder,
// variables: &mut HashMap<String, Variable>,
// index: &mut usize,
// name: &str,
// ) -> Variable {
// let var = Variable::new(*index);
// if !variables.contains_key(name) {
// variables.insert(name.into(), var);
// builder.declare_var(var, int);
// *index += 1;
// }
// var
// }
/// Declare a single variable declaration.
fn declare_variable(
int: types::Type,
builder: &mut FunctionBuilder,
variables: &mut HashMap<String, Variable>,
index: &mut usize,
name: &str,
) -> Variable {
let var = Variable::new(*index);
if !variables.contains_key(name) {
variables.insert(name.into(), var);
builder.declare_var(var, int);
*index += 1;
}
var
}
......@@ -22,7 +22,10 @@ pub fn read(file_name: &str) -> std::io::Result<String> {
pub fn parse(file_name: &str) {
let p = read(file_name).expect("File not found");
let p = ProgramParser::new().parse(&p).unwrap();
println!("program {:?}", p);
println!("program {:?}", &p);
let mut jit = jit::JIT::new();
jit.compile(&p);
}
#[test]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment