Implement return statements
This commit is contained in:
parent
3ae7456758
commit
a3a2df552d
@ -37,8 +37,9 @@ impl AbstractTree for Block {
|
|||||||
for index in 1..node.child_count() - 1 {
|
for index in 1..node.child_count() - 1 {
|
||||||
let child_node = node.child(index).unwrap();
|
let child_node = node.child(index).unwrap();
|
||||||
|
|
||||||
if child_node.is_named() {
|
if child_node.kind() == "statement" {
|
||||||
let statement = Statement::from_syntax_node(source, child_node, context)?;
|
let statement = Statement::from_syntax_node(source, child_node, context)?;
|
||||||
|
|
||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,13 +60,25 @@ impl AbstractTree for Block {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map_first(|(index, statement)| {
|
.find_map_first(|(index, statement)| {
|
||||||
let result = statement.run(source, context);
|
let result = statement.run(source, context);
|
||||||
|
let is_last_statement = index == statements.len() - 1;
|
||||||
|
let is_return_statement = if let Statement::Return(_) = statement {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
if result.is_err() {
|
if is_return_statement || result.is_err() {
|
||||||
Some(result)
|
Some(result)
|
||||||
} else if index == statements.len() - 1 {
|
} else if is_last_statement {
|
||||||
let _ = final_result.write().unwrap().as_mut().map(|_| result);
|
let get_write_lock = final_result.write();
|
||||||
|
|
||||||
|
match get_write_lock {
|
||||||
|
Ok(mut final_result) => {
|
||||||
|
*final_result = result;
|
||||||
None
|
None
|
||||||
|
}
|
||||||
|
Err(error) => Some(Err(error.into())),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -75,6 +88,10 @@ impl AbstractTree for Block {
|
|||||||
let mut prev_result = None;
|
let mut prev_result = None;
|
||||||
|
|
||||||
for statement in &self.statements {
|
for statement in &self.statements {
|
||||||
|
if let Statement::Return(inner_statement) = statement {
|
||||||
|
return inner_statement.run(source, context);
|
||||||
|
}
|
||||||
|
|
||||||
prev_result = Some(statement.run(source, context));
|
prev_result = Some(statement.run(source, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
0
src/abstract_tree/return.rs
Normal file
0
src/abstract_tree/return.rs
Normal file
@ -15,6 +15,7 @@ pub enum Statement {
|
|||||||
Match(Match),
|
Match(Match),
|
||||||
While(Box<While>),
|
While(Box<While>),
|
||||||
Block(Box<Block>),
|
Block(Box<Block>),
|
||||||
|
Return(Box<Statement>),
|
||||||
For(Box<For>),
|
For(Box<For>),
|
||||||
IndexAssignment(Box<IndexAssignment>),
|
IndexAssignment(Box<IndexAssignment>),
|
||||||
}
|
}
|
||||||
@ -50,9 +51,14 @@ impl AbstractTree for Statement {
|
|||||||
"match" => Ok(Statement::Match(Match::from_syntax_node(
|
"match" => Ok(Statement::Match(Match::from_syntax_node(
|
||||||
source, child, context,
|
source, child, context,
|
||||||
)?)),
|
)?)),
|
||||||
|
"return" => {
|
||||||
|
let statement_node = child.child(1).unwrap();
|
||||||
|
|
||||||
|
Ok(Statement::Return(Box::new(Statement::from_syntax_node(source, statement_node, context)?)))
|
||||||
|
},
|
||||||
_ => Err(Error::UnexpectedSyntaxNode {
|
_ => Err(Error::UnexpectedSyntaxNode {
|
||||||
expected:
|
expected:
|
||||||
"assignment, expression, block, return, if...else, while, for, index_assignment or match".to_string(),
|
"assignment, index assignment, expression, block, return, if...else, while, for or match".to_string(),
|
||||||
actual: child.kind().to_string(),
|
actual: child.kind().to_string(),
|
||||||
location: child.start_position(),
|
location: child.start_position(),
|
||||||
relevant_source: source[child.byte_range()].to_string(),
|
relevant_source: source[child.byte_range()].to_string(),
|
||||||
@ -70,6 +76,7 @@ impl AbstractTree for Statement {
|
|||||||
Statement::Block(block) => block.run(source, context),
|
Statement::Block(block) => block.run(source, context),
|
||||||
Statement::For(r#for) => r#for.run(source, context),
|
Statement::For(r#for) => r#for.run(source, context),
|
||||||
Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context),
|
Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context),
|
||||||
|
Statement::Return(statement) => statement.run(source, context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +90,7 @@ impl AbstractTree for Statement {
|
|||||||
Statement::Block(block) => block.expected_type(context),
|
Statement::Block(block) => block.expected_type(context),
|
||||||
Statement::For(r#for) => r#for.expected_type(context),
|
Statement::For(r#for) => r#for.expected_type(context),
|
||||||
Statement::IndexAssignment(index_assignment) => index_assignment.expected_type(context),
|
Statement::IndexAssignment(index_assignment) => index_assignment.expected_type(context),
|
||||||
|
Statement::Return(statement) => statement.expected_type(context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -442,3 +442,38 @@ mod type_definition {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod blocks {
|
||||||
|
use dust_lang::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple() {
|
||||||
|
assert_eq!(interpret("{ 1 }"), Ok(Value::Integer(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested() {
|
||||||
|
assert_eq!(interpret("{ 1 { 1 + 1 } }"), Ok(Value::Integer(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_return() {
|
||||||
|
assert_eq!(interpret("{ return 1; 1 + 1; }"), Ok(Value::Integer(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn async_with_return() {
|
||||||
|
assert_eq!(
|
||||||
|
interpret(
|
||||||
|
"
|
||||||
|
async {
|
||||||
|
return 1
|
||||||
|
1 + 1
|
||||||
|
3
|
||||||
|
}
|
||||||
|
"
|
||||||
|
),
|
||||||
|
Ok(Value::Integer(1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
52
tree-sitter-dust/corpus/blocks.txt
Normal file
52
tree-sitter-dust/corpus/blocks.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
================================================================================
|
||||||
|
Simple Block
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
{
|
||||||
|
output(123)
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(root
|
||||||
|
(statement
|
||||||
|
(block
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(function_call
|
||||||
|
(function_expression
|
||||||
|
(identifier
|
||||||
|
(built_in_function)))
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer)))))))))
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
Block with Return
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
{
|
||||||
|
1
|
||||||
|
return 4
|
||||||
|
5
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(root
|
||||||
|
(statement
|
||||||
|
(block
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer))))
|
||||||
|
(statement
|
||||||
|
(return
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer))))))
|
||||||
|
(statement
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer)))))))
|
@ -2,7 +2,7 @@
|
|||||||
Anonymous Function
|
Anonymous Function
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
() -> <str> { "Hiya" }
|
() <str> { "Hiya" }
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ module.exports = grammar({
|
|||||||
|
|
||||||
return: $ =>
|
return: $ =>
|
||||||
prec.right(
|
prec.right(
|
||||||
seq('return', $.expression),
|
seq('return', $.statement),
|
||||||
),
|
),
|
||||||
|
|
||||||
type_definition: $ =>
|
type_definition: $ =>
|
||||||
|
@ -1022,7 +1022,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "SYMBOL",
|
||||||
"name": "expression"
|
"name": "statement"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -449,7 +449,7 @@
|
|||||||
"required": true,
|
"required": true,
|
||||||
"types": [
|
"types": [
|
||||||
{
|
{
|
||||||
"type": "expression",
|
"type": "statement",
|
||||||
"named": true
|
"named": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user