mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08:24 +00:00
fix double return
This commit is contained in:
parent
7e88b8fb12
commit
9d48259a13
|
@ -5,4 +5,5 @@ fn add(a: i64, b: i64) -> i64 {
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = 2 + 3;
|
let x = 2 + 3;
|
||||||
let y = add(x, 4);
|
let y = add(x, 4);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct StatementBody {
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Assignment(StatementBody),
|
Assignment(StatementBody),
|
||||||
Definition(StatementBody),
|
Definition(StatementBody),
|
||||||
Return(SpanValue<Box<Expr>>),
|
Return(Option<SpanValue<Box<Expr>>>),
|
||||||
Function(Function),
|
Function(Function),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,11 +142,16 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: check function has return?
|
// todo: check function has return?
|
||||||
|
let mut has_return = false;
|
||||||
|
|
||||||
for statement in &function.body {
|
for statement in &function.body {
|
||||||
|
if let Statement::Return(_) = statement.value {
|
||||||
|
has_return = true
|
||||||
|
}
|
||||||
self.compile_statement(&entry_block, statement, &mut variables)?;
|
self.compile_statement(&entry_block, statement, &mut variables)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if function.return_type.is_none() {
|
if !has_return {
|
||||||
self.builder.build_return(None);
|
self.builder.build_return(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,10 +181,14 @@ impl<'ctx> CodeGen<'ctx> {
|
||||||
variables.insert(body.ident.0.value.clone(), result);
|
variables.insert(body.ident.0.value.clone(), result);
|
||||||
}
|
}
|
||||||
Statement::Return(ret) => {
|
Statement::Return(ret) => {
|
||||||
let result = self
|
if let Some(ret) = ret {
|
||||||
.compile_expression(block, ret, variables)?
|
let result = self
|
||||||
.expect("should have result");
|
.compile_expression(block, ret, variables)?
|
||||||
self.builder.build_return(Some(&result));
|
.expect("should have result");
|
||||||
|
self.builder.build_return(Some(&result));
|
||||||
|
} else {
|
||||||
|
self.builder.build_return(None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Statement::Function(_function) => unreachable!(),
|
Statement::Function(_function) => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,7 +65,7 @@ Function: Function = {
|
||||||
BasicStatement: SpanValue<Statement> = {
|
BasicStatement: SpanValue<Statement> = {
|
||||||
<l:@L> "let" <i:Identifier> "=" <e:Expr> ";" <r:@R> => SpanValue::new(l, Statement::new_assignment(i, e), r),
|
<l:@L> "let" <i:Identifier> "=" <e:Expr> ";" <r:@R> => SpanValue::new(l, Statement::new_assignment(i, e), r),
|
||||||
<l:@L> <i:Identifier> "=" <e:Expr> ";" <r:@R> => SpanValue::new(l, Statement::new_definition(i, e), r),
|
<l:@L> <i:Identifier> "=" <e:Expr> ";" <r:@R> => SpanValue::new(l, Statement::new_definition(i, e), r),
|
||||||
<l:@L> "return" <e:Expr> ";" <r:@R> => SpanValue::new(l, Statement::Return(e), r),
|
<l:@L> "return" <e:Expr?> ";" <r:@R> => SpanValue::new(l, Statement::Return(e), r),
|
||||||
};
|
};
|
||||||
|
|
||||||
Statement: SpanValue<Statement> = {
|
Statement: SpanValue<Statement> = {
|
||||||
|
|
|
@ -40,7 +40,7 @@ enum Commands {
|
||||||
input: PathBuf,
|
input: PathBuf,
|
||||||
|
|
||||||
/// Output optimized llvm ir.
|
/// Output optimized llvm ir.
|
||||||
#[arg(short, long)]
|
#[arg(long)]
|
||||||
optimize: bool,
|
optimize: bool,
|
||||||
|
|
||||||
/// The output file. If not specified its output will be stdout.
|
/// The output file. If not specified its output will be stdout.
|
||||||
|
@ -98,7 +98,12 @@ fn main() -> Result<()> {
|
||||||
let program = ProgramData::new(&str_path, &code);
|
let program = ProgramData::new(&str_path, &code);
|
||||||
check_program(&program, &ast);
|
check_program(&program, &ast);
|
||||||
}
|
}
|
||||||
Commands::Compile { input, output, debug: _, optimize: _ } => {
|
Commands::Compile {
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
debug: _,
|
||||||
|
optimize: _,
|
||||||
|
} => {
|
||||||
let code = fs::read_to_string(&input)?;
|
let code = fs::read_to_string(&input)?;
|
||||||
|
|
||||||
let parser = grammar::ProgramParser::new();
|
let parser = grammar::ProgramParser::new();
|
||||||
|
|
Loading…
Reference in a new issue