diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/interpret/operator.rs | 2 | ||||
| -rw-r--r-- | src/interpret/walker.rs | 10 | ||||
| -rw-r--r-- | src/parse/ast/statement.rs | 10 | ||||
| -rw-r--r-- | src/parse/parser.rs | 11 |
4 files changed, 23 insertions, 10 deletions
diff --git a/src/interpret/operator.rs b/src/interpret/operator.rs index 057f942..9a68a7f 100644 --- a/src/interpret/operator.rs +++ b/src/interpret/operator.rs @@ -280,7 +280,7 @@ impl<'t> ValueOperator<'t> { Err(WalkerError { kind: WalkerErrorKind::Return(returned_value), .. - }) => Ok(returned_value), + }) => Ok(returned_value.unwrap_or_else(|| Value::void(self.types))), Err(x) => Err(CallError::InsideFunction(x)), } } diff --git a/src/interpret/walker.rs b/src/interpret/walker.rs index 7c86780..07e127d 100644 --- a/src/interpret/walker.rs +++ b/src/interpret/walker.rs @@ -62,12 +62,16 @@ impl Walker { println!("{}", result); None } - // FIXME: Returns are always expected to have a return even though `return;` is valid. StatementKind::Return(node) => { + let returned = match node { + Some(e) => Some(self.walk_expression(e)?), + None => None, + }; + // If there's a function running above us it will catch this error. return Err(WalkerError::new( statement.at, - WalkerErrorKind::Return(self.walk_expression(node)?), + WalkerErrorKind::Return(returned), )); } StatementKind::Break(node) => { @@ -381,5 +385,5 @@ pub enum WalkerErrorKind { LoopBreak(Option<Value>), // Same as with the loop control errors, but for functions. #[error("Return statements are only valid inside functions.")] - Return(Value), + Return(Option<Value>), } diff --git a/src/parse/ast/statement.rs b/src/parse/ast/statement.rs index 7ed91dc..899190b 100644 --- a/src/parse/ast/statement.rs +++ b/src/parse/ast/statement.rs @@ -16,7 +16,7 @@ pub enum StatementKind { Print(Expression), Break(Option<Expression>), Continue, - Return(Expression), + Return(Option<Expression>), } impl Display for Statement { @@ -39,8 +39,12 @@ impl Statement { expression.nested_fmt(f, depth + 1)?; } StatementKind::Return(expression) => { - writeln!(f, "{}Return:", pad)?; - expression.nested_fmt(f, depth + 1)?; + if let Some(returned) = expression { + writeln!(f, "{}Return:", pad)?; + returned.nested_fmt(f, depth + 1)?; + } else { + writeln!(f, "{}Return", pad)?; + } } StatementKind::Break(expression) => { if let Some(returned_on_break) = expression { diff --git a/src/parse/parser.rs b/src/parse/parser.rs index f19dcf1..a9baf7a 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -51,11 +51,16 @@ impl<T: Iterator<Item = Token>> Parser<T> { fn return_statement(&mut self) -> Result<Statement, ParserError> { let return_token = consume!(self, KeywordReturn)?; - let expression = self.expression()?; - consume!(self, SemiColon)?; + let returned = if consume_if!(self, SemiColon).is_none() { + let expression = self.expression()?; + consume!(self, SemiColon)?; + Some(expression) + } else { + None + }; Ok(Statement { at: return_token.location, - kind: StatementKind::Return(expression), + kind: StatementKind::Return(returned), }) } |
