completed function returns
This commit is contained in:
parent
37671f4550
commit
d2e57ae72c
20
src/main.rs
20
src/main.rs
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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!();
|
||||||
}
|
}
|
||||||
|
@ -588,4 +599,4 @@ pub fn parse<'a>(tokens: &mut VecDeque<crate::Token<'a>>, source: &'a str) -> Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
funcs
|
funcs
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue