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