forked from M-Labs/nac3
Add CodeGenerator::gen_block and refactor to use it
This commit is contained in:
parent
fd787ca3f5
commit
0a84f7ac31
@ -1,7 +1,7 @@
|
|||||||
use nac3core::{
|
use nac3core::{
|
||||||
codegen::{
|
codegen::{
|
||||||
expr::gen_call,
|
expr::gen_call,
|
||||||
stmt::{gen_block, gen_with},
|
stmt::gen_with,
|
||||||
CodeGenContext, CodeGenerator,
|
CodeGenContext, CodeGenerator,
|
||||||
},
|
},
|
||||||
symbol_resolver::ValueEnum,
|
symbol_resolver::ValueEnum,
|
||||||
@ -225,7 +225,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
self.end = Some(end_expr);
|
self.end = Some(end_expr);
|
||||||
self.name_counter += 1;
|
self.name_counter += 1;
|
||||||
|
|
||||||
gen_block(self, ctx, body.iter())?;
|
self.gen_block(ctx, body.iter())?;
|
||||||
|
|
||||||
let current = ctx.builder.get_insert_block().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap();
|
||||||
|
|
||||||
@ -268,7 +268,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
} else if id == &"sequential".into() {
|
} else if id == &"sequential".into() {
|
||||||
let start = self.start.take();
|
let start = self.start.take();
|
||||||
gen_block(self, ctx, body.iter())?;
|
self.gen_block(ctx, body.iter())?;
|
||||||
self.start = start;
|
self.start = start;
|
||||||
|
|
||||||
// Reset the timeline when we are exiting the sequential block
|
// Reset the timeline when we are exiting the sequential block
|
||||||
|
@ -169,6 +169,7 @@ pub trait CodeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate code for a statement
|
/// Generate code for a statement
|
||||||
|
///
|
||||||
/// Return true if the statement must early return
|
/// Return true if the statement must early return
|
||||||
fn gen_stmt<'ctx, 'a>(
|
fn gen_stmt<'ctx, 'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -181,6 +182,18 @@ pub trait CodeGenerator {
|
|||||||
gen_stmt(self, ctx, stmt)
|
gen_stmt(self, ctx, stmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates code for a block statement.
|
||||||
|
fn gen_block<'ctx, 'a, 'b, I: Iterator<Item = &'b Stmt<Option<Type>>>>(
|
||||||
|
&mut self,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, 'a>,
|
||||||
|
stmts: I,
|
||||||
|
) -> Result<(), String>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
gen_block(self, ctx, stmts)
|
||||||
|
}
|
||||||
|
|
||||||
/// See [bool_to_i1].
|
/// See [bool_to_i1].
|
||||||
fn bool_to_i1<'ctx, 'a>(
|
fn bool_to_i1<'ctx, 'a>(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
codegen::stmt::gen_block,
|
|
||||||
symbol_resolver::{StaticValue, SymbolResolver},
|
symbol_resolver::{StaticValue, SymbolResolver},
|
||||||
toplevel::{TopLevelContext, TopLevelDef},
|
toplevel::{TopLevelContext, TopLevelDef},
|
||||||
typecheck::{
|
typecheck::{
|
||||||
@ -859,7 +858,7 @@ pub fn gen_func<'ctx, G: CodeGenerator>(
|
|||||||
) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> {
|
) -> Result<(Builder<'ctx>, Module<'ctx>, FunctionValue<'ctx>), (Builder<'ctx>, String)> {
|
||||||
let body = task.body.clone();
|
let body = task.body.clone();
|
||||||
gen_func_impl(context, generator, registry, builder, module, task, |generator, ctx| {
|
gen_func_impl(context, generator, registry, builder, module, task, |generator, ctx| {
|
||||||
gen_block(generator, ctx, body.iter())
|
generator.gen_block(ctx, body.iter())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||||||
|
|
||||||
ctx.builder.position_at_end(body_bb);
|
ctx.builder.position_at_end(body_bb);
|
||||||
ctx.builder.build_store(target_i, ctx.builder.build_load(i, "").into_int_value());
|
ctx.builder.build_store(target_i, ctx.builder.build_load(i, "").into_int_value());
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
} else {
|
} else {
|
||||||
let index_addr = generator.gen_var_alloc(ctx, size_t.into(), Some("for.index.addr"))?;
|
let index_addr = generator.gen_var_alloc(ctx, size_t.into(), Some("for.index.addr"))?;
|
||||||
ctx.builder.build_store(index_addr, size_t.const_zero());
|
ctx.builder.build_store(index_addr, size_t.const_zero());
|
||||||
@ -353,7 +353,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||||||
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
|
let index = ctx.builder.build_load(index_addr, "for.index").into_int_value();
|
||||||
let val = ctx.build_gep_and_load(arr_ptr, &[index], Some("val"));
|
let val = ctx.build_gep_and_load(arr_ptr, &[index], Some("val"));
|
||||||
generator.gen_assign(ctx, target, val.into())?;
|
generator.gen_assign(ctx, target, val.into())?;
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k, (_, _, counter)) in var_assignment.iter() {
|
for (k, (_, _, counter)) in var_assignment.iter() {
|
||||||
@ -369,7 +369,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
|||||||
|
|
||||||
if !orelse.is_empty() {
|
if !orelse.is_empty() {
|
||||||
ctx.builder.position_at_end(orelse_bb);
|
ctx.builder.position_at_end(orelse_bb);
|
||||||
gen_block(generator, ctx, orelse.iter())?;
|
generator.gen_block(ctx, orelse.iter())?;
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
}
|
}
|
||||||
@ -423,7 +423,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
ctx.builder.position_at_end(body_bb);
|
ctx.builder.position_at_end(body_bb);
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
for (k, (_, _, counter)) in var_assignment.iter() {
|
for (k, (_, _, counter)) in var_assignment.iter() {
|
||||||
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
||||||
if counter != counter2 {
|
if counter != counter2 {
|
||||||
@ -435,7 +435,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
|||||||
}
|
}
|
||||||
if !orelse.is_empty() {
|
if !orelse.is_empty() {
|
||||||
ctx.builder.position_at_end(orelse_bb);
|
ctx.builder.position_at_end(orelse_bb);
|
||||||
gen_block(generator, ctx, orelse.iter())?;
|
generator.gen_block(ctx, orelse.iter())?;
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
}
|
}
|
||||||
@ -487,7 +487,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
ctx.builder.position_at_end(body_bb);
|
ctx.builder.position_at_end(body_bb);
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
for (k, (_, _, counter)) in var_assignment.iter() {
|
for (k, (_, _, counter)) in var_assignment.iter() {
|
||||||
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
||||||
if counter != counter2 {
|
if counter != counter2 {
|
||||||
@ -503,7 +503,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
|||||||
}
|
}
|
||||||
if !orelse.is_empty() {
|
if !orelse.is_empty() {
|
||||||
ctx.builder.position_at_end(orelse_bb);
|
ctx.builder.position_at_end(orelse_bb);
|
||||||
gen_block(generator, ctx, orelse.iter())?;
|
generator.gen_block(ctx, orelse.iter())?;
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
if cont_bb.is_none() {
|
if cont_bb.is_none() {
|
||||||
cont_bb = Some(ctx.ctx.append_basic_block(current, "cont"));
|
cont_bb = Some(ctx.ctx.append_basic_block(current, "cont"));
|
||||||
@ -792,9 +792,9 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
|||||||
}
|
}
|
||||||
let old_clauses = ctx.outer_catch_clauses.replace((all_clauses, dispatcher, exn));
|
let old_clauses = ctx.outer_catch_clauses.replace((all_clauses, dispatcher, exn));
|
||||||
let old_unwind = ctx.unwind_target.replace(landingpad);
|
let old_unwind = ctx.unwind_target.replace(landingpad);
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
if ctx.builder.get_insert_block().unwrap().get_terminator().is_none() {
|
if ctx.builder.get_insert_block().unwrap().get_terminator().is_none() {
|
||||||
gen_block(generator, ctx, orelse.iter())?;
|
generator.gen_block(ctx, orelse.iter())?;
|
||||||
}
|
}
|
||||||
let body = ctx.builder.get_insert_block().unwrap();
|
let body = ctx.builder.get_insert_block().unwrap();
|
||||||
// reset old_clauses and old_unwind
|
// reset old_clauses and old_unwind
|
||||||
@ -896,7 +896,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
|||||||
ctx.var_assignment.insert(*name, (exn_store, None, 0));
|
ctx.var_assignment.insert(*name, (exn_store, None, 0));
|
||||||
ctx.builder.build_store(exn_store, exn.as_basic_value());
|
ctx.builder.build_store(exn_store, exn.as_basic_value());
|
||||||
}
|
}
|
||||||
gen_block(generator, ctx, body.iter())?;
|
generator.gen_block(ctx, body.iter())?;
|
||||||
let current = ctx.builder.get_insert_block().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap();
|
||||||
// only need to call end catch if not terminated
|
// only need to call end catch if not terminated
|
||||||
// otherwise, we already handled in return/break/continue/raise
|
// otherwise, we already handled in return/break/continue/raise
|
||||||
@ -979,7 +979,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
|||||||
// exception path
|
// exception path
|
||||||
let cleanup = cleanup.unwrap();
|
let cleanup = cleanup.unwrap();
|
||||||
ctx.builder.position_at_end(cleanup);
|
ctx.builder.position_at_end(cleanup);
|
||||||
gen_block(generator, ctx, finalbody.iter())?;
|
generator.gen_block(ctx, finalbody.iter())?;
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
ctx.build_call_or_invoke(resume, &[], "resume");
|
ctx.build_call_or_invoke(resume, &[], "resume");
|
||||||
ctx.builder.build_unreachable();
|
ctx.builder.build_unreachable();
|
||||||
@ -991,7 +991,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
|
|||||||
final_targets.push(tail);
|
final_targets.push(tail);
|
||||||
let finalizer = ctx.ctx.append_basic_block(current_fun, "try.finally");
|
let finalizer = ctx.ctx.append_basic_block(current_fun, "try.finally");
|
||||||
ctx.builder.position_at_end(finalizer);
|
ctx.builder.position_at_end(finalizer);
|
||||||
gen_block(generator, ctx, finalbody.iter())?;
|
generator.gen_block(ctx, finalbody.iter())?;
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
let dest = ctx.builder.build_load(final_state, "final_dest");
|
let dest = ctx.builder.build_load(final_state, "final_dest");
|
||||||
ctx.builder.build_indirect_branch(dest, &final_targets);
|
ctx.builder.build_indirect_branch(dest, &final_targets);
|
||||||
|
Loading…
Reference in New Issue
Block a user