Implement yield logic; Reform yield syntax
This commit is contained in:
parent
274891d96e
commit
2876f50822
@ -1,9 +1,12 @@
|
||||
1 -> (output)
|
||||
|
||||
add_one = |list| {
|
||||
add_one = |list| => {
|
||||
transform number in list {
|
||||
number + 1
|
||||
}
|
||||
}
|
||||
|
||||
[1, 2, 3] -> (add_one)
|
||||
foo = [1, 2, 3] -> (add_one)
|
||||
|
||||
(assert_equal [2 3 4] foo)
|
||||
|
||||
|
@ -3,7 +3,7 @@ use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
value_node::ValueNode, AbstractTree, BuiltInFunction, Error, Identifier, Index, Map, Result,
|
||||
Value,
|
||||
Value, Yield,
|
||||
};
|
||||
|
||||
use super::{function_call::FunctionCall, logic::Logic, math::Math};
|
||||
@ -17,42 +17,41 @@ pub enum Expression {
|
||||
Logic(Box<Logic>),
|
||||
FunctionCall(FunctionCall),
|
||||
Tool(Box<BuiltInFunction>),
|
||||
Yield(Yield),
|
||||
}
|
||||
|
||||
impl AbstractTree for Expression {
|
||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||
Error::expect_syntax_node(source, "expression", node)?;
|
||||
|
||||
for index in 0..node.child_count() {
|
||||
let child = node.child(index).unwrap();
|
||||
let expression = match child.kind() {
|
||||
"value" => Expression::Value(ValueNode::from_syntax_node(source, child)?),
|
||||
"identifier" => {
|
||||
Expression::Identifier(Identifier::from_syntax_node(source, child)?)
|
||||
}
|
||||
"index" => Expression::Index(Box::new(Index::from_syntax_node(source, child)?)),
|
||||
"math" => Expression::Math(Box::new(Math::from_syntax_node(source, child)?)),
|
||||
"logic" => Expression::Logic(Box::new(Logic::from_syntax_node(source, child)?)),
|
||||
"function_call" => {
|
||||
Expression::FunctionCall(FunctionCall::from_syntax_node(source, child)?)
|
||||
}
|
||||
"tool" => {
|
||||
Expression::Tool(Box::new(BuiltInFunction::from_syntax_node(source, child)?))
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
let child = if node.child(0).unwrap().is_named() {
|
||||
node.child(0).unwrap()
|
||||
} else {
|
||||
node.child(1).unwrap()
|
||||
};
|
||||
|
||||
return Ok(expression);
|
||||
}
|
||||
let expression = match child.kind() {
|
||||
"value" => Expression::Value(ValueNode::from_syntax_node(source, child)?),
|
||||
"identifier" => Expression::Identifier(Identifier::from_syntax_node(source, child)?),
|
||||
"index" => Expression::Index(Box::new(Index::from_syntax_node(source, child)?)),
|
||||
"math" => Expression::Math(Box::new(Math::from_syntax_node(source, child)?)),
|
||||
"logic" => Expression::Logic(Box::new(Logic::from_syntax_node(source, child)?)),
|
||||
"function_call" => {
|
||||
Expression::FunctionCall(FunctionCall::from_syntax_node(source, child)?)
|
||||
}
|
||||
"tool" => Expression::Tool(Box::new(BuiltInFunction::from_syntax_node(source, child)?)),
|
||||
"yield" => Expression::Yield(Yield::from_syntax_node(source, child)?),
|
||||
_ => {
|
||||
return Err(Error::UnexpectedSyntaxNode {
|
||||
expected: "value, identifier, index, math, logic, function_call or yield",
|
||||
actual: child.kind(),
|
||||
location: child.start_position(),
|
||||
relevant_source: source[child.byte_range()].to_string(),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let child = node.child(0).unwrap();
|
||||
|
||||
Err(Error::UnexpectedSyntaxNode {
|
||||
expected: "value, identifier, sublist, index, math or function_call",
|
||||
actual: child.kind(),
|
||||
location: child.start_position(),
|
||||
relevant_source: source[child.byte_range()].to_string(),
|
||||
})
|
||||
Ok(expression)
|
||||
}
|
||||
|
||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||
@ -64,6 +63,7 @@ impl AbstractTree for Expression {
|
||||
Expression::FunctionCall(function_call) => function_call.run(source, context),
|
||||
Expression::Tool(tool) => tool.run(source, context),
|
||||
Expression::Index(index) => index.run(source, context),
|
||||
Expression::Yield(r#yield) => r#yield.run(source, context),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,13 @@ pub mod statement;
|
||||
pub mod transform;
|
||||
pub mod value_node;
|
||||
pub mod r#while;
|
||||
pub mod r#yield;
|
||||
|
||||
pub use {
|
||||
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
|
||||
function_call::*, identifier::*, if_else::*, index::*, index_assignment::*, insert::*,
|
||||
logic::*, math::*, r#for::*, r#match::*, r#while::*, remove::*, select::*, statement::*,
|
||||
transform::*, value_node::*,
|
||||
logic::*, math::*, r#for::*, r#match::*, r#while::*, r#yield::*, remove::*, select::*,
|
||||
statement::*, transform::*, value_node::*,
|
||||
};
|
||||
|
||||
use tree_sitter::Node;
|
||||
|
@ -78,7 +78,7 @@ impl AbstractTree for Statement {
|
||||
source, child,
|
||||
)?))),
|
||||
_ => Err(Error::UnexpectedSyntaxNode {
|
||||
expected: "assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select, insert or index_assignment",
|
||||
expected: "assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select, insert, index_assignment or yield",
|
||||
actual: child.kind(),
|
||||
location: child.start_position(),
|
||||
relevant_source: source[child.byte_range()].to_string(),
|
||||
|
@ -1,11 +1,10 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{AbstractTree, Expression, Function, FunctionCall, Result, Value, ValueNode};
|
||||
use crate::{AbstractTree, BuiltInFunction, Expression, FunctionCall, Identifier, Result, Value};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct Yield {
|
||||
input: Expression,
|
||||
call: FunctionCall,
|
||||
}
|
||||
|
||||
@ -14,15 +13,38 @@ impl AbstractTree for Yield {
|
||||
let input_node = node.child(0).unwrap();
|
||||
let input = Expression::from_syntax_node(source, input_node)?;
|
||||
|
||||
let call_node = node.child(1).unwrap();
|
||||
let call = FunctionCall::from_syntax_node(source, call_node)?;
|
||||
let function_node = node.child(3).unwrap();
|
||||
let mut arguments = Vec::new();
|
||||
|
||||
Ok(Yield { input, call })
|
||||
arguments.push(input);
|
||||
|
||||
for index in 4..node.child_count() - 1 {
|
||||
let node = node.child(index).unwrap();
|
||||
|
||||
if node.is_named() {
|
||||
let expression = Expression::from_syntax_node(source, node)?;
|
||||
|
||||
arguments.push(expression);
|
||||
}
|
||||
}
|
||||
|
||||
let call = if function_node.kind() == "built_in_function" {
|
||||
let function = BuiltInFunction::from_syntax_node(source, function_node)?;
|
||||
|
||||
FunctionCall::BuiltIn(Box::new(function))
|
||||
} else {
|
||||
let identifier = Identifier::from_syntax_node(source, function_node)?;
|
||||
|
||||
FunctionCall::ContextDefined {
|
||||
name: identifier,
|
||||
arguments,
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Yield { call })
|
||||
}
|
||||
|
||||
fn run(&self, source: &str, context: &mut crate::Map) -> Result<Value> {
|
||||
let target = self.input.run(source, context)?.as_function()?;
|
||||
|
||||
self.call.run(, )
|
||||
self.call.run(source, context)
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,7 @@ Simple Yield
|
||||
(expression
|
||||
(value
|
||||
(integer)))
|
||||
(function_call
|
||||
(built_in_function))))))
|
||||
(built_in_function)))))
|
||||
|
||||
================================================================================
|
||||
Yield Chain
|
||||
@ -34,9 +33,6 @@ x -> (foo) -> (bar) -> (abc)
|
||||
(yield
|
||||
(expression
|
||||
(identifier))
|
||||
(function_call
|
||||
(identifier))))
|
||||
(function_call
|
||||
(identifier))))
|
||||
(function_call
|
||||
(identifier))))))
|
||||
(identifier)))
|
||||
(identifier)))
|
||||
(identifier)))))
|
||||
|
@ -45,7 +45,12 @@ module.exports = grammar({
|
||||
yield: $ => prec.left(seq(
|
||||
$.expression,
|
||||
'->',
|
||||
$.function_call,
|
||||
'(',
|
||||
choice(
|
||||
$.built_in_function,
|
||||
$._context_defined_function,
|
||||
),
|
||||
')',
|
||||
)),
|
||||
|
||||
expression: $ => prec.right(choice(
|
||||
|
@ -150,8 +150,25 @@
|
||||
"value": "->"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "function_call"
|
||||
"type": "STRING",
|
||||
"value": "("
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "built_in_function"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_context_defined_function"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ")"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -758,12 +758,16 @@
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "built_in_function",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "function_call",
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user