forked from M-Labs/nac3
support if/then/else
This commit is contained in:
parent
38cdab01cb
commit
aecf24c857
41
src/main.rs
41
src/main.rs
|
@ -127,7 +127,7 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &str,
|
name: &str,
|
||||||
args: &ast::Parameters,
|
args: &ast::Parameters,
|
||||||
body: &[ast::Statement],
|
body: &ast::Suite,
|
||||||
decorator_list: &[ast::Expression],
|
decorator_list: &[ast::Expression],
|
||||||
returns: &Option<ast::Expression>,
|
returns: &Option<ast::Expression>,
|
||||||
is_async: bool,
|
is_async: bool,
|
||||||
|
@ -185,9 +185,8 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
self.namespace.insert(arg.arg.clone(), alloca);
|
self.namespace.insert(arg.arg.clone(), alloca);
|
||||||
}
|
}
|
||||||
|
|
||||||
for statement in body.iter() {
|
self.compile_suite(body, return_type)?;
|
||||||
self.compile_statement(statement, return_type)?;
|
|
||||||
}
|
|
||||||
Ok(function)
|
Ok(function)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +397,30 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
return Err(self.compile_error(CompileErrorKind::Unsupported("assignment target must be an identifier")))
|
return Err(self.compile_error(CompileErrorKind::Unsupported("assignment target must be an identifier")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
If { test, body, orelse } => {
|
||||||
|
let test = self.compile_expression(test)?;
|
||||||
|
if test.get_type() != self.context.bool_type().into() {
|
||||||
|
return Err(self.compile_error(CompileErrorKind::IncompatibleTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let parent = self.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
|
let then_bb = self.context.append_basic_block(parent, "then");
|
||||||
|
let else_bb = self.context.append_basic_block(parent, "else");
|
||||||
|
let cont_bb = self.context.append_basic_block(parent, "ifcont");
|
||||||
|
self.builder.build_conditional_branch(test.into_int_value(), then_bb, else_bb);
|
||||||
|
|
||||||
|
self.builder.position_at_end(then_bb);
|
||||||
|
self.compile_suite(body, return_type)?;
|
||||||
|
self.builder.build_unconditional_branch(cont_bb);
|
||||||
|
|
||||||
|
self.builder.position_at_end(else_bb);
|
||||||
|
if let Some(orelse) = orelse {
|
||||||
|
self.compile_suite(orelse, return_type)?;
|
||||||
|
}
|
||||||
|
self.builder.build_unconditional_branch(cont_bb);
|
||||||
|
self.builder.position_at_end(cont_bb);
|
||||||
|
},
|
||||||
Return { value: Some(value) } => {
|
Return { value: Some(value) } => {
|
||||||
if let Some(return_type) = return_type {
|
if let Some(return_type) = return_type {
|
||||||
let value = self.compile_expression(value)?;
|
let value = self.compile_expression(value)?;
|
||||||
|
@ -422,6 +444,17 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compile_suite(
|
||||||
|
&mut self,
|
||||||
|
suite: &ast::Suite,
|
||||||
|
return_type: Option<types::BasicTypeEnum>
|
||||||
|
) -> CompileResult<()> {
|
||||||
|
for statement in suite.iter() {
|
||||||
|
self.compile_statement(statement, return_type)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn compile_toplevel(&mut self, statement: &ast::Statement) -> CompileResult<()> {
|
fn compile_toplevel(&mut self, statement: &ast::Statement) -> CompileResult<()> {
|
||||||
self.set_source_location(statement.location);
|
self.set_source_location(statement.location);
|
||||||
if let ast::StatementType::FunctionDef {
|
if let ast::StatementType::FunctionDef {
|
||||||
|
|
Loading…
Reference in New Issue