completed function returns

This commit is contained in:
Sven Vogel 2022-10-31 13:58:09 +01:00
parent 37671f4550
commit d2e57ae72c
3 changed files with 33 additions and 17 deletions

View File

@ -22,17 +22,21 @@ r"
pi = rat 3.1415926535 pi = rat 3.1415926535
foo(x :int, y: rat) = bool { foo(x :int, y: rat) = bool {
yield maybe x:int = 5 + 6
unless(x < 6) {
yield true
unless(x < 6) {
yield true
}
}
yield false
} }
main { main {
unless 3 > 4 {
a = 4 - 5;
b:rat = 0.3 + 7
t = foo(a, b)
}
} }
"; ";

View File

@ -87,8 +87,9 @@ pub struct Scope<'a> {
pub func_return_typ: Option<Prim>, pub func_return_typ: Option<Prim>,
/// if we safely yielded sth /// if we safely yielded sth
pub yields: bool, pub yields: bool,
/// if the current location in the scope is fixed in execution (no loop, no unless) /// if the last expr yielded a result
pub cond_scope: bool pub expr_yield: bool,
pub cond_count: usize
} }
impl<'a> Scope<'a> { impl<'a> Scope<'a> {

View File

@ -352,9 +352,8 @@ fn process_keyword(keyword: Keyword, _: &Vec<Declr>, scope: &mut Scope, operands
dbginf.print(MessageType::Error, format!("Expected {:?} but got {:?}", typ, operand).as_str(), source); dbginf.print(MessageType::Error, format!("Expected {:?} but got {:?}", typ, operand).as_str(), source);
panic!(); panic!();
} }
if scope.cond_scope { println!("{}", scope.cond_count);
scope.yields = true; scope.yields = scope.cond_count == 1;
}
} else { } else {
dbginf.print(MessageType::Error, format!("Function does not return anything").as_str(), source); dbginf.print(MessageType::Error, format!("Function does not return anything").as_str(), source);
panic!(); panic!();
@ -522,6 +521,15 @@ fn parse_term<'a>(term: &mut VecDeque<Token<'a>>, declrs: &Vec<Declr<'a>>, scope
panic!(); panic!();
} }
scope.expr_yield = value_stack.len() == 1;
if scope.expr_yield {
let yielded = value_stack.pop().unwrap();
if !yielded.is_equal(scope.func_return_typ.unwrap()) {
output[0].print(MessageType::Error, format!("expected {:?} but got {:?}", scope.func_return_typ.unwrap(), yielded).as_str(), source);
panic!();
}
}
term.append(&mut output); term.append(&mut output);
} }
@ -535,6 +543,7 @@ fn is_func(declrs: &[Declr], text: &str) -> bool {
} }
fn parse_block<'a>(block: &mut Block<'a>, declrs: &Vec<Declr<'a>>, scope: &mut Scope, source: &str) { fn parse_block<'a>(block: &mut Block<'a>, declrs: &Vec<Declr<'a>>, scope: &mut Scope, source: &str) {
scope.cond_count += 1;
scope.alloc_scope(); scope.alloc_scope();
for expr in block.iter_mut() { for expr in block.iter_mut() {
match expr { match expr {
@ -543,6 +552,7 @@ fn parse_block<'a>(block: &mut Block<'a>, declrs: &Vec<Declr<'a>>, scope: &mut S
} }
} }
scope.pop_scope(); scope.pop_scope();
scope.cond_count -= 1;
} }
fn parse_exprs<'a>(funcs: &mut Vec<Func<'a>>, declrs: &Vec<Declr<'a>>, source: &'a str) { fn parse_exprs<'a>(funcs: &mut Vec<Func<'a>>, declrs: &Vec<Declr<'a>>, source: &'a str) {
@ -550,8 +560,9 @@ fn parse_exprs<'a>(funcs: &mut Vec<Func<'a>>, declrs: &Vec<Declr<'a>>, source: &
args: None, args: None,
vars: vec![], vars: vec![],
func_return_typ: None, func_return_typ: None,
cond_scope: false, expr_yield: false,
yields: false, yields: false,
cond_count: 0
}; };
for (x, func) in funcs.iter_mut().enumerate() { for (x, func) in funcs.iter_mut().enumerate() {
@ -559,12 +570,12 @@ fn parse_exprs<'a>(funcs: &mut Vec<Func<'a>>, declrs: &Vec<Declr<'a>>, source: &
Expr::Block(block) => { Expr::Block(block) => {
scope.args = declrs[x].args.as_ref(); scope.args = declrs[x].args.as_ref();
scope.func_return_typ = declrs[x].result_typ; scope.func_return_typ = declrs[x].result_typ;
scope.cond_scope = false;
scope.yields = false; scope.yields = false;
scope.cond_count = 0;
parse_block(block, declrs, &mut scope, source); parse_block(block, declrs, &mut scope, source);
if scope.func_return_typ.is_some() && !scope.yields { if scope.func_return_typ.is_some() && !scope.yields && !scope.expr_yield {
crate::message(MessageType::Error, format!("Function {} missing return value at some point", declrs[x])); crate::message(MessageType::Error, format!("Function {} missing return value at some point", declrs[x]));
panic!(); panic!();
} }