diff --git a/src/main.rs b/src/main.rs index 9d78edb..53a8e7e 100644 --- a/src/main.rs +++ b/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) - } + } "; diff --git a/src/parser/data.rs b/src/parser/data.rs index aff66bf..a5e6b5b 100644 --- a/src/parser/data.rs +++ b/src/parser/data.rs @@ -87,8 +87,9 @@ pub struct Scope<'a> { pub func_return_typ: Option, /// 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> { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 02678b1..0e4b046 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -352,9 +352,8 @@ fn process_keyword(keyword: Keyword, _: &Vec, 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>, declrs: &Vec>, 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>, 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>, scope: &mut S } } scope.pop_scope(); + scope.cond_count -= 1; } fn parse_exprs<'a>(funcs: &mut Vec>, declrs: &Vec>, source: &'a str) { @@ -550,8 +560,9 @@ fn parse_exprs<'a>(funcs: &mut Vec>, declrs: &Vec>, 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>, declrs: &Vec>, 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!(); } @@ -588,4 +599,4 @@ pub fn parse<'a>(tokens: &mut VecDeque>, source: &'a str) -> Ve } funcs -} \ No newline at end of file +}