completed function returns
This commit is contained in:
parent
37671f4550
commit
d2e57ae72c
18
src/main.rs
18
src/main.rs
|
@ -22,17 +22,21 @@ r"
|
|||
pi = rat 3.1415926535
|
||||
|
||||
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 {
|
||||
|
||||
unless 3 > 4 {
|
||||
a = 4 - 5;
|
||||
b:rat = 0.3 + 7
|
||||
|
||||
t = foo(a, b)
|
||||
}
|
||||
}
|
||||
";
|
||||
|
||||
|
|
|
@ -87,8 +87,9 @@ pub struct Scope<'a> {
|
|||
pub func_return_typ: Option<Prim>,
|
||||
/// if we safely yielded sth
|
||||
pub yields: bool,
|
||||
/// if the current location in the scope is fixed in execution (no loop, no unless)
|
||||
pub cond_scope: bool
|
||||
/// if the last expr yielded a result
|
||||
pub expr_yield: bool,
|
||||
pub cond_count: usize
|
||||
}
|
||||
|
||||
impl<'a> Scope<'a> {
|
||||
|
|
|
@ -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);
|
||||
panic!();
|
||||
}
|
||||
if scope.cond_scope {
|
||||
scope.yields = true;
|
||||
}
|
||||
println!("{}", scope.cond_count);
|
||||
scope.yields = scope.cond_count == 1;
|
||||
} else {
|
||||
dbginf.print(MessageType::Error, format!("Function does not return anything").as_str(), source);
|
||||
panic!();
|
||||
|
@ -522,6 +521,15 @@ fn parse_term<'a>(term: &mut VecDeque<Token<'a>>, declrs: &Vec<Declr<'a>>, scope
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
scope.cond_count += 1;
|
||||
scope.alloc_scope();
|
||||
for expr in block.iter_mut() {
|
||||
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.cond_count -= 1;
|
||||
}
|
||||
|
||||
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,
|
||||
vars: vec![],
|
||||
func_return_typ: None,
|
||||
cond_scope: false,
|
||||
expr_yield: false,
|
||||
yields: false,
|
||||
cond_count: 0
|
||||
};
|
||||
|
||||
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) => {
|
||||
scope.args = declrs[x].args.as_ref();
|
||||
scope.func_return_typ = declrs[x].result_typ;
|
||||
scope.cond_scope = false;
|
||||
scope.yields = false;
|
||||
scope.cond_count = 0;
|
||||
|
||||
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]));
|
||||
panic!();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue