1
0

Continue syntax revision

This commit is contained in:
Jeff 2023-10-31 13:04:22 -04:00
parent e582f3cad3
commit 42f0834d80
30 changed files with 56137 additions and 14065 deletions

View File

@ -1,18 +1,17 @@
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 {
(output 'fizzbuzz')
} else if divides_by_3 {
(output 'fizz')
} else if divides_by_5 {
(output 'buzz')
} else {
(output count)
}
if divides_by_3 && divides_by_5
output 'fizzbuzz'
else if divides_by_3
output 'fizz'
else if divides_by_5
output 'buzz'
else
output count
count += 1
}

View File

@ -2,11 +2,11 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Error, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Async {
statements: Vec<Statement>,
statements: Vec<Block>,
}
impl AbstractTree for Async {
@ -20,7 +20,7 @@ impl AbstractTree for Async {
let child = node.child(index).unwrap();
let statement = match child.kind() {
"statement" => Statement::from_syntax_node(source, child)?,
"statement" => Block::from_syntax_node(source, child)?,
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "comment or statement",

View File

@ -0,0 +1,40 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Result, Statement};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Block {
statements: Vec<Statement>,
}
impl AbstractTree for Block {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
debug_assert_eq!("block", node.kind());
let statement_count = node.child_count();
let mut statements = Vec::with_capacity(statement_count);
for index in 0..statement_count {
let child_node = node.child(index).unwrap();
if child_node.kind() == "statement" {
let statement = Statement::from_syntax_node(source, child_node)?;
statements.push(statement);
}
}
Ok(Block { statements })
}
fn run(&self, source: &str, context: &mut crate::Map) -> crate::Result<crate::Value> {
for statement in &self.statements[0..self.statements.len() - 1] {
statement.run(source, context)?;
}
let final_statement = self.statements.last().unwrap();
let final_value = final_statement.run(source, context)?;
Ok(final_value)
}
}

View File

@ -2,14 +2,14 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Identifier, List, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Error, Expression, Identifier, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Filter {
count: Option<Expression>,
item_id: Identifier,
collection: Expression,
predicate: Statement,
predicate: Block,
}
impl AbstractTree for Filter {
@ -26,7 +26,7 @@ impl AbstractTree for Filter {
let collection = Expression::from_syntax_node(source, collection_node)?;
let predicate_node = node.child(5).unwrap();
let predicate = Statement::from_syntax_node(source, predicate_node)?;
let predicate = Block::from_syntax_node(source, predicate_node)?;
Ok(Filter {
count,

View File

@ -1,13 +1,13 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Find {
identifier: Identifier,
expression: Expression,
item: Statement,
item: Block,
}
impl AbstractTree for Find {
@ -19,7 +19,7 @@ impl AbstractTree for Find {
let expression = Expression::from_syntax_node(source, expression_node)?;
let item_node = node.child(5).unwrap();
let item = Statement::from_syntax_node(source, item_node)?;
let item = Block::from_syntax_node(source, item_node)?;
Ok(Find {
identifier,

View File

@ -2,14 +2,14 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, Identifier, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct For {
is_async: bool,
identifier: Identifier,
expression: Expression,
item: Statement,
item: Block,
}
impl AbstractTree for For {
@ -34,7 +34,7 @@ impl AbstractTree for For {
let expression = Expression::from_syntax_node(source, expression_node)?;
let item_node = node.child(5).unwrap();
let item = Statement::from_syntax_node(source, item_node)?;
let item = Block::from_syntax_node(source, item_node)?;
Ok(For {
is_async,

View File

@ -41,7 +41,7 @@ impl AbstractTree for FunctionCall {
return Err(Error::FunctionIdentifierNotFound(self.name.clone()));
};
let id_expr_pairs = definition.identifiers().iter().zip(self.arguments.iter());
let mut function_context = context.clone();
let mut function_context = Map::clone_from(context);
for (identifier, expression) in id_expr_pairs {
let key = identifier.inner().clone();

View File

@ -1,59 +1,57 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Expression, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct IfElse {
if_expression: Expression,
then_statement: Statement,
if_block: Block,
else_if_expressions: Vec<Expression>,
else_if_statements: Vec<Statement>,
else_statement: Option<Statement>,
else_if_blocks: Vec<Block>,
else_block: Option<Block>,
}
impl AbstractTree for IfElse {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
let if_node = node.child(0).unwrap().child(1).unwrap();
let if_expression = Expression::from_syntax_node(source, if_node)?;
let if_expression_node = node.child(0).unwrap().child(1).unwrap();
let if_expression = Expression::from_syntax_node(source, if_expression_node)?;
let then_node = node.child(0).unwrap().child(3).unwrap();
let then_statement = Statement::from_syntax_node(source, then_node)?;
let if_block_node = node.child(0).unwrap().child(2).unwrap();
let if_block = Block::from_syntax_node(source, if_block_node)?;
let child_count = node.child_count();
let mut else_if_expressions = Vec::new();
let mut else_if_statements = Vec::new();
let mut else_statement = None;
let mut else_if_blocks = Vec::new();
let mut else_block = None;
for index in 1..child_count {
let child = node.child(index);
let child = node.child(index).unwrap();
if let Some(node) = child {
if node.kind() == "else_if" {
let expression_node = node.child(1).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
if child.kind() == "else_if" {
let expression_node = child.child(1).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
else_if_expressions.push(expression);
else_if_expressions.push(expression);
let statement_node = node.child(3).unwrap();
let statement = Statement::from_syntax_node(source, statement_node)?;
let block_node = child.child(2).unwrap();
let block = Block::from_syntax_node(source, block_node)?;
else_if_statements.push(statement);
}
else_if_blocks.push(block);
}
if node.kind() == "else" {
let else_node = node.child(2).unwrap();
else_statement = Some(Statement::from_syntax_node(source, else_node)?);
}
if child.kind() == "else" {
let else_node = child.child(1).unwrap();
else_block = Some(Block::from_syntax_node(source, else_node)?);
}
}
Ok(IfElse {
if_expression,
then_statement,
if_block,
else_if_expressions,
else_if_statements,
else_statement,
else_if_blocks,
else_block,
})
}
@ -61,7 +59,7 @@ impl AbstractTree for IfElse {
let if_boolean = self.if_expression.run(source, context)?.as_boolean()?;
if if_boolean {
self.then_statement.run(source, context)
self.if_block.run(source, context)
} else {
let expressions = &self.else_if_expressions;
@ -69,14 +67,14 @@ impl AbstractTree for IfElse {
let if_boolean = expression.run(source, context)?.as_boolean()?;
if if_boolean {
let statement = self.else_if_statements.get(index).unwrap();
let block = self.else_if_blocks.get(index).unwrap();
return statement.run(source, context);
return block.run(source, context);
}
}
if let Some(statement) = &self.else_statement {
statement.run(source, context)
if let Some(block) = &self.else_block {
block.run(source, context)
} else {
Ok(Value::Empty)
}

View File

@ -8,6 +8,7 @@
pub mod assignment;
pub mod r#async;
pub mod block;
pub mod expression;
pub mod filter;
pub mod find;
@ -30,9 +31,10 @@ pub mod value_node;
pub mod r#while;
pub use {
assignment::*, 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::*, 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::*,
};
use tree_sitter::Node;

View File

@ -1,13 +1,13 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Remove {
identifier: Identifier,
expression: Expression,
item: Statement,
item: Block,
}
impl AbstractTree for Remove {
@ -19,7 +19,7 @@ impl AbstractTree for Remove {
let expression = Expression::from_syntax_node(source, expression_node)?;
let item_node = node.child(5).unwrap();
let item = Statement::from_syntax_node(source, item_node)?;
let item = Block::from_syntax_node(source, item_node)?;
Ok(Remove {
identifier,

View File

@ -1,13 +1,13 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, Map, Result, Statement, Table, Value};
use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Table, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Select {
identifiers: Vec<Identifier>,
expression: Expression,
item: Option<Statement>,
item: Option<Block>,
}
impl AbstractTree for Select {
@ -33,7 +33,7 @@ impl AbstractTree for Select {
let item = if final_node.kind() == "}" {
let item_node = node.child(child_count - 2).unwrap();
Some(Statement::from_syntax_node(source, item_node)?)
Some(Block::from_syntax_node(source, item_node)?)
} else {
None
};

View File

@ -2,13 +2,13 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Identifier, List, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Expression, Identifier, List, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Transform {
identifier: Identifier,
expression: Expression,
item: Statement,
item: Block,
}
impl AbstractTree for Transform {
@ -20,7 +20,7 @@ impl AbstractTree for Transform {
let expression = Expression::from_syntax_node(source, expression_node)?;
let item_node = node.child(5).unwrap();
let item = Statement::from_syntax_node(source, item_node)?;
let item = Block::from_syntax_node(source, item_node)?;
Ok(Transform {
identifier,

View File

@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{
AbstractTree, Error, Expression, Function, Identifier, List, Map, Result, Statement, Table,
Value, ValueType,
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Table, Value,
ValueType,
};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -101,10 +101,10 @@ impl AbstractTree for ValueNode {
"function" => {
let mut identifiers = Vec::new();
let item_node = child.child(child.child_count() - 2).unwrap();
let item = Statement::from_syntax_node(source, item_node)?;
let block_node = child.child(child.child_count() - 1).unwrap();
let block = Block::from_syntax_node(source, block_node)?;
for index in 1..child.child_count() - 3 {
for index in 1..child.child_count() - 1 {
let child_node = child.child(index).unwrap();
if child_node.kind() == "identifier" {
@ -114,7 +114,7 @@ impl AbstractTree for ValueNode {
}
}
let function = Function::new(identifiers, item);
let function = Function::new(identifiers, block);
ValueType::Function(function)
}

View File

@ -1,12 +1,12 @@
use serde::{Deserialize, Serialize};
use tree_sitter::Node;
use crate::{AbstractTree, Expression, Map, Result, Statement, Value};
use crate::{AbstractTree, Block, Expression, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct While {
expression: Expression,
statement: Statement,
block: Block,
}
impl AbstractTree for While {
@ -16,18 +16,15 @@ impl AbstractTree for While {
let expression_node = node.child(1).unwrap();
let expression = Expression::from_syntax_node(source, expression_node)?;
let statement_node = node.child(3).unwrap();
let statement = Statement::from_syntax_node(source, statement_node)?;
let block_node = node.child(2).unwrap();
let block = Block::from_syntax_node(source, block_node)?;
Ok(While {
expression,
statement,
})
Ok(While { expression, block })
}
fn run(&self, source: &str, context: &mut Map) -> Result<Value> {
while self.expression.run(source, context)?.as_boolean()? {
self.statement.run(source, context)?;
self.block.run(source, context)?;
}
Ok(Value::Empty)

View File

@ -6,7 +6,7 @@ use std::fmt::{self, Debug, Formatter};
use tree_sitter::{Parser, Tree as TSTree};
use crate::{language, AbstractTree, Map, Result, Statement, Value};
use crate::{language, AbstractTree, Block, Map, Result, Value};
/// Evaluate the given source code.
///
@ -85,9 +85,9 @@ impl<'context, 'code> Evaluator<'context, 'code> {
let root_node = cursor.node();
let mut prev_result = Ok(Value::Empty);
for item_node in root_node.children(&mut cursor) {
let item = Statement::from_syntax_node(self.source, item_node)?;
prev_result = item.run(self.source, self.context);
for block_node in root_node.children(&mut cursor) {
let block = Block::from_syntax_node(self.source, block_node)?;
prev_result = block.run(self.source, self.context);
}
prev_result
@ -244,15 +244,12 @@ mod tests {
#[test]
fn evaluate_function_call() {
let mut context = Map::new();
assert_eq!(
evaluate_with_context(
evaluate(
"
foobar = function <message> { message }
(foobar 'Hiya')
",
&mut context
),
Ok(Value::String("Hiya".to_string()))
);

View File

@ -2,19 +2,19 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use crate::{Identifier, Statement};
use crate::{Block, Identifier};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Function {
parameters: Vec<Identifier>,
body: Box<Statement>,
body: Box<Block>,
}
impl Function {
pub fn new(identifiers: Vec<Identifier>, items: Statement) -> Self {
pub fn new(parameters: Vec<Identifier>, body: Block) -> Self {
Function {
parameters: identifiers,
body: Box::new(items),
parameters,
body: Box::new(body),
}
}
@ -22,7 +22,7 @@ impl Function {
&self.parameters
}
pub fn body(&self) -> &Statement {
pub fn body(&self) -> &Block {
&self.body
}
}

View File

@ -13,7 +13,8 @@ async { (output 'Whaddup') }
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(value
(string)))))))))))

View File

@ -98,7 +98,8 @@ find i in ["one", "two", "three"] {
(expression
(logic
(expression
(tool
(function_call
(built_in_function)
(expression
(identifier))))
(logic_operator)

View File

@ -28,9 +28,10 @@ for i in [1, 2, 3] {
(block
(statement
(expression
(tool
(expression
(identifier))))))))))
(function_call
(built_in_function)
(expression
(identifier))))))))))
==================
Nested For Loop
@ -60,6 +61,7 @@ for list in list_of_lists {
(block
(statement
(expression
(tool
(expression
(identifier)))))))))))))
(function_call
(built_in_function)
(expression
(identifier)))))))))))))

View File

@ -58,12 +58,14 @@ function <message number> {
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(identifier)))))
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(identifier))))))))))))
@ -98,10 +100,12 @@ Complex Function Call
(value
(map
(identifier)
(expression
(value
(integer)))
(statement
(expression
(value
(integer))))
(identifier)
(expression
(value
(integer)))))))))))
(statement
(expression
(value
(integer))))))))))))

View File

@ -123,7 +123,7 @@ if true {
If Else
==================
if false { "True" } else { "False" }
if false "True" else "False"
---
@ -198,15 +198,14 @@ if 1 == 1 {
If Else Else If Else
==================
if false {
if false
"no"
} else if false {
else if false
"no"
} else if 1 + 1 == 9 {
else if 1 + 1 == 9
"not the answer"
} else {
else
"42"
}
---

View File

@ -13,9 +13,10 @@ Simple Map
(value
(map
(identifier)
(expression
(value
(integer)))))))))
(statement
(expression
(value
(integer))))))))))
==================
Nested Maps
@ -44,22 +45,27 @@ x = {
(value
(map
(identifier)
(expression
(value
(map
(identifier)
(expression
(value
(string)))
(identifier)
(expression
(value
(map
(identifier)
(expression
(value
(string)))))))))
(statement
(expression
(value
(map
(identifier)
(statement
(expression
(value
(string))))
(identifier)
(statement
(expression
(value
(map
(identifier)
(statement
(expression
(value
(string))))))))))))
(identifier)
(expression
(value
(integer)))))))))))
(statement
(expression
(value
(integer))))))))))))

View File

@ -40,7 +40,7 @@ remove i from [1, 2, 3] {
Nested Remove
==================
removed = remove i from big_list {
remove i from big_list {
remove j from i {
j != 42
}
@ -51,27 +51,23 @@ removed = remove i from big_list {
(root
(block
(statement
(assignment
(remove
(identifier)
(assignment_operator)
(statement
(remove
(identifier)
(expression
(identifier))
(block
(statement
(remove
(identifier)
(expression
(identifier))
(block
(statement
(remove
(identifier)
(expression
(identifier))
(block
(statement
(expression
(identifier))
(block
(statement
(logic
(expression
(logic
(expression
(identifier))
(logic_operator)
(expression
(value
(integer))))))))))))))))
(identifier))
(logic_operator)
(expression
(value
(integer))))))))))))))

View File

@ -10,7 +10,8 @@ Simple Tool Call
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(value
(string))))))))
@ -19,7 +20,8 @@ Simple Tool Call
Nested Tool Call
==================
(assert_equal random_integer, 4)
(assert_equal (random_integer) 4)
assert_equal random_integer 4
---
@ -27,9 +29,21 @@ Nested Tool Call
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(identifier))
(function_call
(built_in_function)))
(expression
(value
(integer))))))))
(integer))))))
(statement
(expression
(function_call
(built_in_function)
(expression
(function_call
(built_in_function)
(expression
(value
(integer))))))))))

View File

@ -28,7 +28,8 @@ transform i in [1, 2, 3] {
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(identifier))))))))))

View File

@ -18,7 +18,8 @@ while true {
(block
(statement
(expression
(tool
(function_call
(built_in_function)
(expression
(value
(string)))))))))))

View File

@ -5,6 +5,10 @@ module.exports = grammar({
extras: $ => [ /\s/, $.comment ],
conflicts: $ => [
[$.map, $.assignment_operator],
],
rules: {
root: $ => repeat1($.block),
@ -15,7 +19,12 @@ module.exports = grammar({
seq('{', repeat1($.statement), '}'),
)),
statement: $ => prec.left(choice(
statement: $ => prec.right(seq(
$._statement_kind,
optional(';'),
)),
_statement_kind: $ => prec.right(choice(
$.assignment,
$.async,
$.expression,
@ -32,18 +41,17 @@ module.exports = grammar({
$.while,
)),
expression: $ => choice(
expression: $ => prec.left(choice(
$._expression_kind,
seq('(', $._expression_kind, ')'),
),
)),
_expression_kind: $ => prec.left(choice(
_expression_kind: $ => prec.left(1, choice(
$.function_call,
$.identifier,
$.index,
$.logic,
$.math,
$.tool,
$.value,
)),
@ -89,12 +97,12 @@ module.exports = grammar({
map: $ => seq(
'{',
repeat(prec(1, seq(
repeat(seq(
$.identifier,
'=',
$.expression,
"=",
$.statement,
optional(',')
))),
)),
'}',
),
@ -165,51 +173,41 @@ module.exports = grammar({
if_else: $ => prec.left(seq(
$.if,
repeat(seq($.else_if)),
repeat($.else_if),
optional($.else),
)),
if: $ => seq(
if: $ => prec.left(seq(
'if',
$.expression,
'{',
$.block,
'}',
),
)),
else_if: $ => seq(
else_if: $ => prec.left(seq(
'else if',
$.expression,
'{',
$.block,
'}',
),
)),
else: $ => seq(
else: $ => prec.left(seq(
'else',
'{',
$.block,
'}',
),
)),
function_call: $ => seq(
'(',
$.identifier,
repeat(prec.left(seq($.expression, optional(',')))),
')',
),
function_call: $ => prec.right(seq(
choice($.identifier, $.built_in_function),
repeat(prec.right(seq($.expression, optional(',')))),
)),
match: $ => seq(
match: $ => prec.right(seq(
'match',
$.expression,
'{',
repeat1(seq(
$.expression,
'=>',
$.block,
)),
'}',
),
)),
while: $ => seq(
'while',
@ -290,14 +288,7 @@ module.exports = grammar({
$.block,
),
tool: $ => seq(
'(',
$._tool_kind,
repeat(seq($.expression, optional(','))),
')',
),
_tool_kind: $ => choice(
built_in_function: $ => choice(
// General
'assert',
'assert_equal',

View File

@ -50,7 +50,32 @@
}
},
"statement": {
"type": "PREC_LEFT",
"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": {
"type": "CHOICE",
@ -115,34 +140,38 @@
}
},
"expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression_kind"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_expression_kind"
},
{
"type": "STRING",
"value": ")"
}
]
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_expression_kind"
},
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_expression_kind"
},
{
"type": "STRING",
"value": ")"
}
]
}
]
}
},
"_expression_kind": {
"type": "PREC_LEFT",
"value": 0,
"value": 1,
"content": {
"type": "CHOICE",
"members": [
@ -166,10 +195,6 @@
"type": "SYMBOL",
"name": "math"
},
{
"type": "SYMBOL",
"name": "tool"
},
{
"type": "SYMBOL",
"name": "value"
@ -482,37 +507,33 @@
{
"type": "REPEAT",
"content": {
"type": "PREC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": "="
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": "="
},
{
"type": "SYMBOL",
"name": "statement"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
@ -826,13 +847,8 @@
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "else_if"
}
]
"type": "SYMBOL",
"name": "else_if"
}
},
{
@ -851,92 +867,130 @@
}
},
"if": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "SYMBOL",
"name": "block"
},
{
"type": "STRING",
"value": "}"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"else_if": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "SYMBOL",
"name": "block"
},
{
"type": "STRING",
"value": "}"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else if"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"else": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "SYMBOL",
"name": "block"
},
{
"type": "STRING",
"value": "}"
}
]
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "else"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
"function_call": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "REPEAT",
"content": {
"type": "PREC_LEFT",
"value": 0,
"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,
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "match"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
@ -945,67 +999,18 @@
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
"type": "STRING",
"value": "=>"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"match": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "match"
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "{"
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "STRING",
"value": "=>"
},
{
"type": "SYMBOL",
"name": "block"
}
]
}
},
{
"type": "STRING",
"value": "}"
}
]
]
}
},
"while": {
"type": "SEQ",
@ -1313,48 +1318,7 @@
}
]
},
"tool": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "_tool_kind"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "BLANK"
}
]
}
]
}
},
{
"type": "STRING",
"value": ")"
}
]
},
"_tool_kind": {
"built_in_function": {
"type": "CHOICE",
"members": [
{
@ -1490,7 +1454,12 @@
"name": "comment"
}
],
"conflicts": [],
"conflicts": [
[
"map",
"assignment_operator"
]
],
"precedences": [],
"externals": [],
"inline": [],

View File

@ -62,6 +62,11 @@
"named": true,
"fields": {}
},
{
"type": "built_in_function",
"named": true,
"fields": {}
},
{
"type": "else",
"named": true,
@ -124,10 +129,6 @@
"type": "math",
"named": true
},
{
"type": "tool",
"named": true
},
{
"type": "value",
"named": true
@ -259,6 +260,10 @@
"multiple": true,
"required": true,
"types": [
{
"type": "built_in_function",
"named": true
},
{
"type": "expression",
"named": true
@ -399,11 +404,11 @@
"required": false,
"types": [
{
"type": "expression",
"type": "identifier",
"named": true
},
{
"type": "identifier",
"type": "statement",
"named": true
}
]
@ -622,21 +627,6 @@
]
}
},
{
"type": "tool",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "expression",
"named": true
}
]
}
},
{
"type": "transform",
"named": true,
@ -778,6 +768,10 @@
"type": ":",
"named": false
},
{
"type": ";",
"named": false
},
{
"type": "<",
"named": false

File diff suppressed because it is too large Load Diff