Revise language syntax
This commit is contained in:
parent
42f0834d80
commit
df7cd0e972
@ -1,17 +1,18 @@
|
||||
count = 1
|
||||
|
||||
while count <= 15
|
||||
while count <= 15 {
|
||||
divides_by_3 = count % 3 == 0
|
||||
divides_by_5 = count % 5 == 0
|
||||
|
||||
if divides_by_3 && divides_by_5
|
||||
if divides_by_3 && divides_by_5 {
|
||||
output 'fizzbuzz'
|
||||
else if divides_by_3
|
||||
} else if divides_by_3 {
|
||||
output 'fizz'
|
||||
else if divides_by_5
|
||||
} else if divides_by_5 {
|
||||
output 'buzz'
|
||||
else
|
||||
} else {
|
||||
output count
|
||||
}
|
||||
|
||||
count += 1
|
||||
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ use tree_sitter::Node;
|
||||
use crate::{AbstractTree, Error, Expression, List, Map, Result, Table, Value, ValueType};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub enum Tool {
|
||||
pub enum BuiltInFunction {
|
||||
// General
|
||||
Assert(Vec<Expression>),
|
||||
AssertEqual(Vec<Expression>),
|
||||
@ -61,14 +61,14 @@ pub enum Tool {
|
||||
Reverse(Expression, Option<(Expression, Expression)>),
|
||||
}
|
||||
|
||||
impl AbstractTree for Tool {
|
||||
impl AbstractTree for BuiltInFunction {
|
||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||
debug_assert_eq!("tool", node.kind());
|
||||
debug_assert_eq!("built_in_function", node.kind());
|
||||
|
||||
fn parse_expressions(source: &str, node: Node) -> Result<Vec<Expression>> {
|
||||
let mut expressions = Vec::new();
|
||||
|
||||
for index in 2..node.child_count() - 1 {
|
||||
for index in 1..node.child_count() {
|
||||
let child_node = node.child(index).unwrap();
|
||||
|
||||
if child_node.kind() == "expression" {
|
||||
@ -81,23 +81,23 @@ impl AbstractTree for Tool {
|
||||
Ok(expressions)
|
||||
}
|
||||
|
||||
let tool_node = node.child(1).unwrap();
|
||||
let tool_node = node.child(0).unwrap();
|
||||
let tool = match tool_node.kind() {
|
||||
"assert" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Assert(expressions)
|
||||
BuiltInFunction::Assert(expressions)
|
||||
}
|
||||
"assert_equal" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::AssertEqual(expressions)
|
||||
BuiltInFunction::AssertEqual(expressions)
|
||||
}
|
||||
"download" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Download(expression)
|
||||
BuiltInFunction::Download(expression)
|
||||
}
|
||||
"help" => {
|
||||
let child_node = node.child(2).unwrap();
|
||||
@ -107,138 +107,138 @@ impl AbstractTree for Tool {
|
||||
None
|
||||
};
|
||||
|
||||
Tool::Help(expression)
|
||||
BuiltInFunction::Help(expression)
|
||||
}
|
||||
"length" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Length(expression)
|
||||
BuiltInFunction::Length(expression)
|
||||
}
|
||||
"output" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Output(expressions)
|
||||
BuiltInFunction::Output(expressions)
|
||||
}
|
||||
"output_error" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::OutputError(expressions)
|
||||
BuiltInFunction::OutputError(expressions)
|
||||
}
|
||||
"type" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Type(expression)
|
||||
BuiltInFunction::Type(expression)
|
||||
}
|
||||
"workdir" => Tool::Workdir,
|
||||
"workdir" => BuiltInFunction::Workdir,
|
||||
"append" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Error::expect_tool_argument_amount("append", 2, expressions.len())?;
|
||||
|
||||
Tool::Append(expressions)
|
||||
BuiltInFunction::Append(expressions)
|
||||
}
|
||||
"metadata" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Metadata(expression)
|
||||
BuiltInFunction::Metadata(expression)
|
||||
}
|
||||
"move" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Error::expect_tool_argument_amount("move", 2, expressions.len())?;
|
||||
|
||||
Tool::Move(expressions)
|
||||
BuiltInFunction::Move(expressions)
|
||||
}
|
||||
"read" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Read(expression)
|
||||
BuiltInFunction::Read(expression)
|
||||
}
|
||||
"remove" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Remove(expression)
|
||||
BuiltInFunction::Remove(expression)
|
||||
}
|
||||
"write" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Error::expect_tool_argument_amount("write", 2, expressions.len())?;
|
||||
|
||||
Tool::Write(expressions)
|
||||
BuiltInFunction::Write(expressions)
|
||||
}
|
||||
"from_json" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::FromJson(expression)
|
||||
BuiltInFunction::FromJson(expression)
|
||||
}
|
||||
"to_json" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::ToJson(expression)
|
||||
BuiltInFunction::ToJson(expression)
|
||||
}
|
||||
"to_string" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::ToString(expression)
|
||||
BuiltInFunction::ToString(expression)
|
||||
}
|
||||
"to_float" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::ToFloat(expression)
|
||||
BuiltInFunction::ToFloat(expression)
|
||||
}
|
||||
"bash" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Bash(expressions)
|
||||
BuiltInFunction::Bash(expressions)
|
||||
}
|
||||
"fish" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Fish(expressions)
|
||||
BuiltInFunction::Fish(expressions)
|
||||
}
|
||||
"raw" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Raw(expressions)
|
||||
BuiltInFunction::Raw(expressions)
|
||||
}
|
||||
"sh" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Sh(expressions)
|
||||
BuiltInFunction::Sh(expressions)
|
||||
}
|
||||
"zsh" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Zsh(expressions)
|
||||
BuiltInFunction::Zsh(expressions)
|
||||
}
|
||||
"random" => {
|
||||
let expressions = parse_expressions(source, node)?;
|
||||
|
||||
Tool::Random(expressions)
|
||||
BuiltInFunction::Random(expressions)
|
||||
}
|
||||
"random_boolean" => Tool::RandomBoolean,
|
||||
"random_float" => Tool::RandomFloat,
|
||||
"random_integer" => Tool::RandomInteger,
|
||||
"random_boolean" => BuiltInFunction::RandomBoolean,
|
||||
"random_float" => BuiltInFunction::RandomFloat,
|
||||
"random_integer" => BuiltInFunction::RandomInteger,
|
||||
"columns" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Columns(expression)
|
||||
BuiltInFunction::Columns(expression)
|
||||
}
|
||||
"rows" => {
|
||||
let expression_node = node.child(2).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Tool::Rows(expression)
|
||||
BuiltInFunction::Rows(expression)
|
||||
}
|
||||
"reverse" => {
|
||||
let list_node = node.child(2).unwrap();
|
||||
@ -254,11 +254,11 @@ impl AbstractTree for Tool {
|
||||
None
|
||||
};
|
||||
|
||||
Tool::Reverse(list_expression, slice_range_nodes)
|
||||
BuiltInFunction::Reverse(list_expression, slice_range_nodes)
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::UnexpectedSyntaxNode {
|
||||
expected: "built-in tool",
|
||||
expected: "built-in function",
|
||||
actual: tool_node.kind(),
|
||||
location: tool_node.start_position(),
|
||||
relevant_source: source[tool_node.byte_range()].to_string(),
|
||||
@ -271,7 +271,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||
match self {
|
||||
Tool::Assert(expressions) => {
|
||||
BuiltInFunction::Assert(expressions) => {
|
||||
for expression in expressions {
|
||||
let value = expression.run(source, context)?;
|
||||
|
||||
@ -284,7 +284,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::AssertEqual(expressions) => {
|
||||
BuiltInFunction::AssertEqual(expressions) => {
|
||||
let mut prev_value = None;
|
||||
for expression in expressions {
|
||||
let value = expression.run(source, context)?;
|
||||
@ -305,14 +305,14 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::Download(expression) => {
|
||||
BuiltInFunction::Download(expression) => {
|
||||
let value = expression.run(source, context)?;
|
||||
let url = value.as_string()?;
|
||||
let data = get(url)?.text()?;
|
||||
|
||||
Ok(Value::String(data))
|
||||
}
|
||||
Tool::Length(expression) => {
|
||||
BuiltInFunction::Length(expression) => {
|
||||
let value = expression.run(source, context)?;
|
||||
let length = match value {
|
||||
Value::List(list) => list.items().len(),
|
||||
@ -328,7 +328,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Integer(length as i64))
|
||||
}
|
||||
Tool::Help(_expression) => {
|
||||
BuiltInFunction::Help(_expression) => {
|
||||
let mut help_table =
|
||||
Table::new(vec!["tool".to_string(), "description".to_string()]);
|
||||
|
||||
@ -339,7 +339,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Table(help_table))
|
||||
}
|
||||
Tool::Output(expressions) => {
|
||||
BuiltInFunction::Output(expressions) => {
|
||||
for expression in expressions {
|
||||
let value = expression.run(source, context)?;
|
||||
|
||||
@ -348,7 +348,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::OutputError(expressions) => {
|
||||
BuiltInFunction::OutputError(expressions) => {
|
||||
for expression in expressions {
|
||||
let value = expression.run(source, context)?;
|
||||
|
||||
@ -357,7 +357,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::Type(expression) => {
|
||||
BuiltInFunction::Type(expression) => {
|
||||
let run_expression = expression.run(source, context);
|
||||
let value_type = if let Ok(value) = run_expression {
|
||||
value.value_type()
|
||||
@ -369,12 +369,12 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(value_type.to_string()))
|
||||
}
|
||||
Tool::Workdir => {
|
||||
BuiltInFunction::Workdir => {
|
||||
let workdir = current_dir()?.to_string_lossy().to_string();
|
||||
|
||||
Ok(Value::String(workdir))
|
||||
}
|
||||
Tool::Append(expressions) => {
|
||||
BuiltInFunction::Append(expressions) => {
|
||||
let path_value = expressions[0].run(source, context)?;
|
||||
let path = path_value.as_string()?;
|
||||
let data = expressions[1].run(source, context)?.to_string();
|
||||
@ -384,7 +384,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::Metadata(expression) => {
|
||||
BuiltInFunction::Metadata(expression) => {
|
||||
let path_value = expression.run(source, context)?;
|
||||
let path = path_value.as_string()?;
|
||||
let metadata = metadata(path)?;
|
||||
@ -415,7 +415,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Map(metadata_output))
|
||||
}
|
||||
Tool::Move(expressions) => {
|
||||
BuiltInFunction::Move(expressions) => {
|
||||
let from_value = expressions[0].run(source, context)?;
|
||||
let from = from_value.as_string()?;
|
||||
let to_value = expressions[1].run(source, context)?;
|
||||
@ -426,7 +426,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::Read(expression) => {
|
||||
BuiltInFunction::Read(expression) => {
|
||||
let path_value = expression.run(source, context)?;
|
||||
let path = PathBuf::from(path_value.as_string()?);
|
||||
let content = if path.is_dir() {
|
||||
@ -447,7 +447,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(content)
|
||||
}
|
||||
Tool::Remove(expression) => {
|
||||
BuiltInFunction::Remove(expression) => {
|
||||
let path_value = expression.run(source, context)?;
|
||||
let path = PathBuf::from(path_value.as_string()?);
|
||||
|
||||
@ -455,7 +455,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::Write(expressions) => {
|
||||
BuiltInFunction::Write(expressions) => {
|
||||
let path_value = expressions[0].run(source, context)?;
|
||||
let path = path_value.as_string()?;
|
||||
let data_value = expressions[1].run(source, context)?;
|
||||
@ -465,26 +465,26 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
Tool::FromJson(expression) => {
|
||||
BuiltInFunction::FromJson(expression) => {
|
||||
let json_value = expression.run(source, context)?;
|
||||
let json = json_value.as_string()?;
|
||||
let value = serde_json::from_str(json)?;
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
Tool::ToJson(expression) => {
|
||||
BuiltInFunction::ToJson(expression) => {
|
||||
let value = expression.run(source, context)?;
|
||||
let json = serde_json::to_string(&value)?;
|
||||
|
||||
Ok(Value::String(json))
|
||||
}
|
||||
Tool::ToString(expression) => {
|
||||
BuiltInFunction::ToString(expression) => {
|
||||
let value = expression.run(source, context)?;
|
||||
let string = value.to_string();
|
||||
|
||||
Ok(Value::String(string))
|
||||
}
|
||||
Tool::ToFloat(expression) => {
|
||||
BuiltInFunction::ToFloat(expression) => {
|
||||
let value = expression.run(source, context)?;
|
||||
let float = match value {
|
||||
Value::String(string) => string.parse()?,
|
||||
@ -495,7 +495,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::Float(float))
|
||||
}
|
||||
Tool::Bash(expressions) => {
|
||||
BuiltInFunction::Bash(expressions) => {
|
||||
let mut command = Command::new("bash");
|
||||
|
||||
for expression in expressions {
|
||||
@ -509,7 +509,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(String::from_utf8(output)?))
|
||||
}
|
||||
Tool::Fish(expressions) => {
|
||||
BuiltInFunction::Fish(expressions) => {
|
||||
let mut command = Command::new("fish");
|
||||
|
||||
for expression in expressions {
|
||||
@ -523,7 +523,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(String::from_utf8(output)?))
|
||||
}
|
||||
Tool::Raw(expressions) => {
|
||||
BuiltInFunction::Raw(expressions) => {
|
||||
let raw_command = expressions[0].run(source, context)?;
|
||||
let mut command = Command::new(raw_command.as_string()?);
|
||||
|
||||
@ -538,7 +538,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(String::from_utf8(output)?))
|
||||
}
|
||||
Tool::Sh(expressions) => {
|
||||
BuiltInFunction::Sh(expressions) => {
|
||||
let mut command = Command::new("sh");
|
||||
|
||||
for expression in expressions {
|
||||
@ -552,7 +552,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(String::from_utf8(output)?))
|
||||
}
|
||||
Tool::Zsh(expressions) => {
|
||||
BuiltInFunction::Zsh(expressions) => {
|
||||
let mut command = Command::new("zsh");
|
||||
|
||||
for expression in expressions {
|
||||
@ -566,7 +566,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::String(String::from_utf8(output)?))
|
||||
}
|
||||
Tool::Random(expressions) => {
|
||||
BuiltInFunction::Random(expressions) => {
|
||||
if expressions.len() == 1 {
|
||||
let value = expressions[0].run(source, context)?;
|
||||
let list = value.as_list()?.items();
|
||||
@ -594,10 +594,10 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
Tool::RandomBoolean => Ok(Value::Boolean(random())),
|
||||
Tool::RandomFloat => Ok(Value::Float(random())),
|
||||
Tool::RandomInteger => Ok(Value::Integer(random())),
|
||||
Tool::Columns(expression) => {
|
||||
BuiltInFunction::RandomBoolean => Ok(Value::Boolean(random())),
|
||||
BuiltInFunction::RandomFloat => Ok(Value::Float(random())),
|
||||
BuiltInFunction::RandomInteger => Ok(Value::Integer(random())),
|
||||
BuiltInFunction::Columns(expression) => {
|
||||
let column_names = expression
|
||||
.run(source, context)?
|
||||
.as_table()?
|
||||
@ -609,7 +609,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::List(List::with_items(column_names)))
|
||||
}
|
||||
Tool::Rows(expression) => {
|
||||
BuiltInFunction::Rows(expression) => {
|
||||
let rows = expression
|
||||
.run(source, context)?
|
||||
.as_table()?
|
||||
@ -621,7 +621,7 @@ impl AbstractTree for Tool {
|
||||
|
||||
Ok(Value::List(List::with_items(rows)))
|
||||
}
|
||||
Tool::Reverse(list_expression, slice_range) => {
|
||||
BuiltInFunction::Reverse(list_expression, slice_range) => {
|
||||
let expression_run = list_expression.run(source, context)?;
|
||||
let list = expression_run.as_list()?;
|
||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
value_node::ValueNode, AbstractTree, Error, Identifier, Index, Map, Result, Sublist, Tool,
|
||||
Value,
|
||||
value_node::ValueNode, AbstractTree, BuiltInFunction, Error, Identifier, Index, Map, Result,
|
||||
Sublist, Value,
|
||||
};
|
||||
|
||||
use super::{function_call::FunctionCall, logic::Logic, math::Math};
|
||||
@ -17,7 +17,7 @@ pub enum Expression {
|
||||
Math(Box<Math>),
|
||||
Logic(Box<Logic>),
|
||||
FunctionCall(FunctionCall),
|
||||
Tool(Box<Tool>),
|
||||
Tool(Box<BuiltInFunction>),
|
||||
}
|
||||
|
||||
impl AbstractTree for Expression {
|
||||
@ -40,7 +40,9 @@ impl AbstractTree for Expression {
|
||||
"function_call" => {
|
||||
Expression::FunctionCall(FunctionCall::from_syntax_node(source, child)?)
|
||||
}
|
||||
"tool" => Expression::Tool(Box::new(Tool::from_syntax_node(source, child)?)),
|
||||
"tool" => {
|
||||
Expression::Tool(Box::new(BuiltInFunction::from_syntax_node(source, child)?))
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
|
@ -1,49 +1,67 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{AbstractTree, Error, Map, Result, Value};
|
||||
use crate::{AbstractTree, BuiltInFunction, Error, Map, Result, Value};
|
||||
|
||||
use super::{expression::Expression, identifier::Identifier};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct FunctionCall {
|
||||
name: Identifier,
|
||||
arguments: Vec<Expression>,
|
||||
pub enum FunctionCall {
|
||||
BuiltIn(Box<BuiltInFunction>),
|
||||
ContextDefined {
|
||||
name: Identifier,
|
||||
arguments: Vec<Expression>,
|
||||
},
|
||||
}
|
||||
|
||||
impl AbstractTree for FunctionCall {
|
||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||
debug_assert_eq!("function_call", node.kind());
|
||||
|
||||
let name_node = node.child(1).unwrap();
|
||||
let name = Identifier::from_syntax_node(source, name_node)?;
|
||||
|
||||
let function_node = node.child(0).unwrap();
|
||||
let mut arguments = Vec::new();
|
||||
|
||||
for index in 2..node.child_count() - 1 {
|
||||
for index in 1..node.child_count() {
|
||||
let child = node.child(index).unwrap();
|
||||
|
||||
if child.is_named() {
|
||||
if child.kind() == "expression" {
|
||||
let expression = Expression::from_syntax_node(source, child)?;
|
||||
|
||||
arguments.push(expression);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(FunctionCall { name, arguments })
|
||||
let function_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(function_call)
|
||||
}
|
||||
|
||||
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
|
||||
let key = self.name.inner();
|
||||
let definition = if let Some(value) = context.variables().get(key) {
|
||||
let (name, arguments) = match self {
|
||||
FunctionCall::BuiltIn(function) => return function.run(source, context),
|
||||
FunctionCall::ContextDefined { name, arguments } => (name, arguments),
|
||||
};
|
||||
|
||||
let definition = if let Some(value) = context.variables().get(name.inner()) {
|
||||
value.as_function().cloned()?
|
||||
} else {
|
||||
return Err(Error::FunctionIdentifierNotFound(self.name.clone()));
|
||||
return Err(Error::FunctionIdentifierNotFound(name.clone()));
|
||||
};
|
||||
let id_expr_pairs = definition.identifiers().iter().zip(self.arguments.iter());
|
||||
let mut function_context = Map::clone_from(context);
|
||||
let identifier_expression_pairs = definition.identifiers().iter().zip(arguments.iter());
|
||||
|
||||
for (identifier, expression) in id_expr_pairs {
|
||||
for (identifier, expression) in identifier_expression_pairs {
|
||||
let key = identifier.inner().clone();
|
||||
let value = expression.run(source, context)?;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
pub mod assignment;
|
||||
pub mod r#async;
|
||||
pub mod block;
|
||||
pub mod built_in_function;
|
||||
pub mod expression;
|
||||
pub mod filter;
|
||||
pub mod find;
|
||||
@ -25,16 +26,15 @@ pub mod remove;
|
||||
pub mod select;
|
||||
pub mod statement;
|
||||
pub mod sublist;
|
||||
pub mod tool;
|
||||
pub mod transform;
|
||||
pub mod value_node;
|
||||
pub mod r#while;
|
||||
|
||||
pub use {
|
||||
assignment::*, block::*, expression::*, filter::*, find::*, function_call::*, identifier::*,
|
||||
if_else::*, index::*, insert::*, logic::*, math::*, r#async::*, r#for::*, r#match::*,
|
||||
r#while::*, remove::*, select::*, statement::*, sublist::*, tool::*, transform::*,
|
||||
value_node::*,
|
||||
assignment::*, block::*, built_in_function::*, expression::*, filter::*, find::*,
|
||||
function_call::*, identifier::*, if_else::*, index::*, insert::*, logic::*, math::*,
|
||||
r#async::*, r#for::*, r#match::*, r#while::*, remove::*, select::*, statement::*, sublist::*,
|
||||
transform::*, value_node::*,
|
||||
};
|
||||
|
||||
use tree_sitter::Node;
|
||||
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Table, Value,
|
||||
ValueType,
|
||||
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement,
|
||||
Table, Value, ValueType,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
@ -88,11 +88,11 @@ impl AbstractTree for ValueNode {
|
||||
Identifier::from_syntax_node(source, child_syntax_node)?.take_inner();
|
||||
}
|
||||
|
||||
if child_syntax_node.kind() == "expression" {
|
||||
if child_syntax_node.kind() == "statement" {
|
||||
let key = current_key.clone();
|
||||
let expression = Expression::from_syntax_node(source, child_syntax_node)?;
|
||||
let statement = Statement::from_syntax_node(source, child_syntax_node)?;
|
||||
|
||||
child_nodes.insert(key, expression);
|
||||
child_nodes.insert(key, statement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ mod tests {
|
||||
map.variables_mut()
|
||||
.insert("foo".to_string(), Value::String("bar".to_string()));
|
||||
|
||||
assert_eq!(evaluate("{ x = 1 foo = 'bar' }"), Ok(Value::Map(map)));
|
||||
assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -256,7 +256,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evaluate_tool_call() {
|
||||
fn evaluate_built_in_function_call() {
|
||||
assert_eq!(evaluate("(output 'Hiya')"), Ok(Value::Empty));
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{value_node::ValueNode, Expression, Function, Identifier, Value};
|
||||
use crate::{value_node::ValueNode, Expression, Function, Identifier, Statement, Value};
|
||||
|
||||
/// The type of a `Value`.
|
||||
#[derive(Clone, Serialize, Deserialize, PartialOrd, Ord)]
|
||||
@ -17,7 +17,7 @@ pub enum ValueType {
|
||||
Boolean,
|
||||
List(Vec<Expression>),
|
||||
Empty,
|
||||
Map(BTreeMap<String, Expression>),
|
||||
Map(BTreeMap<String, Statement>),
|
||||
Table {
|
||||
column_names: Vec<Identifier>,
|
||||
rows: Box<Expression>,
|
||||
@ -117,9 +117,9 @@ impl From<&Value> for ValueType {
|
||||
for (key, value) in map.variables().iter() {
|
||||
let value_type = value.value_type();
|
||||
let value_node = ValueNode::new(value_type, 0, 0);
|
||||
let expression = Expression::Value(value_node);
|
||||
let statement = Statement::Expression(Expression::Value(value_node));
|
||||
|
||||
value_nodes.insert(key.to_string(), expression);
|
||||
value_nodes.insert(key.to_string(), statement);
|
||||
}
|
||||
|
||||
ValueType::Map(value_nodes)
|
||||
|
@ -14,10 +14,10 @@ async { (output 'Whaddup') }
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(value
|
||||
(string)))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(value
|
||||
(string))))))))))))
|
||||
|
||||
==================
|
||||
Complex Async Statements
|
||||
|
49
tree-sitter-dust/corpus/built_in_function.txt
Normal file
49
tree-sitter-dust/corpus/built_in_function.txt
Normal file
@ -0,0 +1,49 @@
|
||||
==================
|
||||
Simple Function Call
|
||||
==================
|
||||
|
||||
(output 'hi')
|
||||
|
||||
---
|
||||
|
||||
(root
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function
|
||||
(expression
|
||||
(value
|
||||
(string)))))))))
|
||||
|
||||
==================
|
||||
Nested Function Call
|
||||
==================
|
||||
|
||||
(assert_equal (random_integer) 4)
|
||||
assert_equal random_integer 4
|
||||
|
||||
---
|
||||
|
||||
(root
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)))
|
||||
(expression
|
||||
(value
|
||||
(integer)))))))
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function
|
||||
(expression
|
||||
(value
|
||||
(integer))))))))))))
|
@ -1,12 +1,12 @@
|
||||
==================
|
||||
================================================================================
|
||||
Simple Find Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
find i in [1, 2, 3] {
|
||||
i <= 3
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -36,9 +36,9 @@ find i in [1, 2, 3] {
|
||||
(value
|
||||
(integer)))))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Nested Find Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
find i in ["one", "two", "three"] {
|
||||
found = find j in i {
|
||||
@ -53,7 +53,7 @@ find i in ["one", "two", "three"] {
|
||||
}
|
||||
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -99,9 +99,9 @@ find i in ["one", "two", "three"] {
|
||||
(logic
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier)))))
|
||||
(logic_operator)
|
||||
(expression
|
||||
(value
|
||||
|
@ -1,12 +1,10 @@
|
||||
==================
|
||||
================================================================================
|
||||
Simple For Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
for i in [1, 2, 3] {
|
||||
(output i)
|
||||
}
|
||||
for i in [1, 2, 3] output i
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -29,21 +27,17 @@ for i in [1, 2, 3] {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier)))))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Nested For Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
for list in list_of_lists {
|
||||
for item in list {
|
||||
(output item)
|
||||
}
|
||||
}
|
||||
for list in list_of_lists for item in list output item
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -62,6 +56,6 @@ for list in list_of_lists {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier)))))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier))))))))))))))
|
||||
|
@ -1,10 +1,10 @@
|
||||
==================
|
||||
================================================================================
|
||||
Simple Function
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
function { "Hiya" }
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -17,14 +17,14 @@ function { "Hiya" }
|
||||
(expression
|
||||
(value
|
||||
(string)))))))))))
|
||||
|
||||
==================
|
||||
|
||||
================================================================================
|
||||
Function Call
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
(foobar "Hiya")
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -36,16 +36,16 @@ Function Call
|
||||
(value
|
||||
(string))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Complex Function
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
function <message number> {
|
||||
(output message)
|
||||
(output number)
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -59,19 +59,19 @@ function <message number> {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier)))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier))))))
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier))))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier)))))))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Complex Function Call
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
(foobar
|
||||
"hi"
|
||||
@ -82,7 +82,7 @@ Complex Function Call
|
||||
}
|
||||
)
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
|
@ -1,49 +0,0 @@
|
||||
==================
|
||||
Simple Tool Call
|
||||
==================
|
||||
|
||||
(output 'hi')
|
||||
|
||||
---
|
||||
|
||||
(root
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(value
|
||||
(string))))))))
|
||||
|
||||
==================
|
||||
Nested Tool Call
|
||||
==================
|
||||
|
||||
(assert_equal (random_integer) 4)
|
||||
assert_equal random_integer 4
|
||||
|
||||
---
|
||||
|
||||
(root
|
||||
(block
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)))
|
||||
(expression
|
||||
(value
|
||||
(integer))))))
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(value
|
||||
(integer))))))))))
|
@ -1,12 +1,12 @@
|
||||
==================
|
||||
================================================================================
|
||||
Transform Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
transform i in [1, 2, 3] {
|
||||
(output i)
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -29,13 +29,13 @@ transform i in [1, 2, 3] {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(identifier))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(identifier)))))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Nested Transform Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
transform i in [['one'] ['two'] ['three']] {
|
||||
transform j in i {
|
||||
@ -43,7 +43,7 @@ transform i in [['one'] ['two'] ['three']] {
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
|
@ -1,12 +1,12 @@
|
||||
==================
|
||||
================================================================================
|
||||
While Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
while true {
|
||||
(output "This is a bad idea...")
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -19,14 +19,14 @@ while true {
|
||||
(statement
|
||||
(expression
|
||||
(function_call
|
||||
(built_in_function)
|
||||
(expression
|
||||
(value
|
||||
(string)))))))))))
|
||||
(built_in_function
|
||||
(expression
|
||||
(value
|
||||
(string))))))))))))
|
||||
|
||||
==================
|
||||
================================================================================
|
||||
Nested While Loop
|
||||
==================
|
||||
================================================================================
|
||||
|
||||
while (true) {
|
||||
while (x > 0) {
|
||||
@ -34,7 +34,7 @@ while (true) {
|
||||
}
|
||||
}
|
||||
|
||||
---
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(root
|
||||
(block
|
||||
@ -62,4 +62,4 @@ while (true) {
|
||||
(statement
|
||||
(expression
|
||||
(value
|
||||
(integer))))))))))))))
|
||||
(integer))))))))))))))
|
||||
|
@ -19,12 +19,7 @@ module.exports = grammar({
|
||||
seq('{', repeat1($.statement), '}'),
|
||||
)),
|
||||
|
||||
statement: $ => prec.right(seq(
|
||||
$._statement_kind,
|
||||
optional(';'),
|
||||
)),
|
||||
|
||||
_statement_kind: $ => prec.right(choice(
|
||||
statement: $ => prec.right(choice(
|
||||
$.assignment,
|
||||
$.async,
|
||||
$.expression,
|
||||
@ -68,14 +63,14 @@ module.exports = grammar({
|
||||
$.map,
|
||||
),
|
||||
|
||||
integer: $ => prec.left(token(seq(
|
||||
integer: $ => token(prec.left(seq(
|
||||
optional('-'),
|
||||
repeat1(
|
||||
choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')
|
||||
),
|
||||
))),
|
||||
|
||||
float: $ => prec.left(token(seq(
|
||||
float: $ => token(prec.left(seq(
|
||||
optional('-'),
|
||||
repeat1(choice('1', '2', '3', '4', '5', '6', '7', '8', '9', '0')),
|
||||
'.',
|
||||
@ -115,12 +110,6 @@ module.exports = grammar({
|
||||
$.expression,
|
||||
)),
|
||||
)),
|
||||
|
||||
function: $ => seq(
|
||||
'function',
|
||||
optional(seq('<', repeat(seq($.identifier, optional(','))), '>')),
|
||||
$.block,
|
||||
),
|
||||
|
||||
table: $ => prec.left(seq(
|
||||
'table',
|
||||
@ -194,11 +183,6 @@ module.exports = grammar({
|
||||
$.block,
|
||||
)),
|
||||
|
||||
function_call: $ => prec.right(seq(
|
||||
choice($.identifier, $.built_in_function),
|
||||
repeat(prec.right(seq($.expression, optional(',')))),
|
||||
)),
|
||||
|
||||
match: $ => prec.right(seq(
|
||||
'match',
|
||||
$.expression,
|
||||
@ -287,8 +271,29 @@ module.exports = grammar({
|
||||
'async',
|
||||
$.block,
|
||||
),
|
||||
|
||||
function: $ => seq(
|
||||
'function',
|
||||
optional(seq('<', repeat(seq($.identifier, optional(','))), '>')),
|
||||
$.block,
|
||||
),
|
||||
|
||||
built_in_function: $ => choice(
|
||||
function_call: $ => choice(
|
||||
$.built_in_function,
|
||||
$._context_defined_function,
|
||||
),
|
||||
|
||||
_context_defined_function: $ => prec.right(seq(
|
||||
$.identifier,
|
||||
repeat(prec.right(seq($.expression, optional(',')))),
|
||||
)),
|
||||
|
||||
built_in_function: $ => prec.right(seq(
|
||||
$._built_in_function_name,
|
||||
repeat(prec.right(seq($.expression, optional(',')))),
|
||||
)),
|
||||
|
||||
_built_in_function_name: $ => choice(
|
||||
// General
|
||||
'assert',
|
||||
'assert_equal',
|
||||
@ -298,13 +303,13 @@ module.exports = grammar({
|
||||
'output',
|
||||
'output_error',
|
||||
'type',
|
||||
'workdir',
|
||||
|
||||
// Filesystem
|
||||
'append',
|
||||
'metadata',
|
||||
'move',
|
||||
'read',
|
||||
'workdir',
|
||||
'write',
|
||||
|
||||
// Format conversion
|
||||
|
@ -50,31 +50,6 @@
|
||||
}
|
||||
},
|
||||
"statement": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_statement_kind"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ";"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_statement_kind": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
@ -244,10 +219,10 @@
|
||||
]
|
||||
},
|
||||
"integer": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"type": "TOKEN",
|
||||
"content": {
|
||||
"type": "TOKEN",
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
@ -316,10 +291,10 @@
|
||||
}
|
||||
},
|
||||
"float": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"type": "TOKEN",
|
||||
"content": {
|
||||
"type": "TOKEN",
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
@ -584,64 +559,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"function": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "function"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "block"
|
||||
}
|
||||
]
|
||||
},
|
||||
"table": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
@ -925,56 +842,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"function_call": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "built_in_function"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"match": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
@ -1318,7 +1185,160 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"function": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "function"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "<"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ">"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "block"
|
||||
}
|
||||
]
|
||||
},
|
||||
"function_call": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "built_in_function"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_context_defined_function"
|
||||
}
|
||||
]
|
||||
},
|
||||
"_context_defined_function": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"built_in_function": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_built_in_function_name"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT",
|
||||
"content": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ","
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_built_in_function_name": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
@ -1353,10 +1373,6 @@
|
||||
"type": "STRING",
|
||||
"value": "type"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "workdir"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "append"
|
||||
@ -1373,6 +1389,10 @@
|
||||
"type": "STRING",
|
||||
"value": "read"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "workdir"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "write"
|
||||
|
@ -65,7 +65,17 @@
|
||||
{
|
||||
"type": "built_in_function",
|
||||
"named": true,
|
||||
"fields": {}
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "expression",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "else",
|
||||
@ -205,11 +215,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"named": true,
|
||||
"fields": {}
|
||||
},
|
||||
{
|
||||
"type": "for",
|
||||
"named": true,
|
||||
@ -351,11 +356,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"named": true,
|
||||
"fields": {}
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"named": true,
|
||||
@ -768,10 +768,6 @@
|
||||
"type": ":",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": ";",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "<",
|
||||
"named": false
|
||||
@ -864,6 +860,10 @@
|
||||
"type": "fish",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "for",
|
||||
"named": false
|
||||
@ -900,6 +900,10 @@
|
||||
"type": "insert",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "into",
|
||||
"named": false
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user