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 count = 1
while count <= 15 { while count <= 15
divides_by_3 = count % 3 == 0 divides_by_3 = count % 3 == 0
divides_by_5 = count % 5 == 0 divides_by_5 = count % 5 == 0
if divides_by_3 && divides_by_5 { if divides_by_3 && divides_by_5
(output 'fizzbuzz') output 'fizzbuzz'
} else if divides_by_3 { else if divides_by_3
(output 'fizz') output 'fizz'
} else if divides_by_5 { else if divides_by_5
(output 'buzz') output 'buzz'
} else { else
(output count) output count
}
count += 1 count += 1
}

View File

@ -2,11 +2,11 @@ use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; 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)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Async { pub struct Async {
statements: Vec<Statement>, statements: Vec<Block>,
} }
impl AbstractTree for Async { impl AbstractTree for Async {
@ -20,7 +20,7 @@ impl AbstractTree for Async {
let child = node.child(index).unwrap(); let child = node.child(index).unwrap();
let statement = match child.kind() { let statement = match child.kind() {
"statement" => Statement::from_syntax_node(source, child)?, "statement" => Block::from_syntax_node(source, child)?,
_ => { _ => {
return Err(Error::UnexpectedSyntaxNode { return Err(Error::UnexpectedSyntaxNode {
expected: "comment or statement", 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 serde::{Deserialize, Serialize};
use tree_sitter::Node; 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)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Filter { pub struct Filter {
count: Option<Expression>, count: Option<Expression>,
item_id: Identifier, item_id: Identifier,
collection: Expression, collection: Expression,
predicate: Statement, predicate: Block,
} }
impl AbstractTree for Filter { impl AbstractTree for Filter {
@ -26,7 +26,7 @@ impl AbstractTree for Filter {
let collection = Expression::from_syntax_node(source, collection_node)?; let collection = Expression::from_syntax_node(source, collection_node)?;
let predicate_node = node.child(5).unwrap(); 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 { Ok(Filter {
count, count,

View File

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

View File

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

View File

@ -41,7 +41,7 @@ impl AbstractTree for FunctionCall {
return Err(Error::FunctionIdentifierNotFound(self.name.clone())); return Err(Error::FunctionIdentifierNotFound(self.name.clone()));
}; };
let id_expr_pairs = definition.identifiers().iter().zip(self.arguments.iter()); 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 { for (identifier, expression) in id_expr_pairs {
let key = identifier.inner().clone(); let key = identifier.inner().clone();

View File

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

View File

@ -8,6 +8,7 @@
pub mod assignment; pub mod assignment;
pub mod r#async; pub mod r#async;
pub mod block;
pub mod expression; pub mod expression;
pub mod filter; pub mod filter;
pub mod find; pub mod find;
@ -30,9 +31,10 @@ pub mod value_node;
pub mod r#while; pub mod r#while;
pub use { pub use {
assignment::*, expression::*, filter::*, find::*, function_call::*, identifier::*, if_else::*, assignment::*, block::*, expression::*, filter::*, find::*, function_call::*, identifier::*,
index::*, insert::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, if_else::*, index::*, insert::*, logic::*, math::*, r#async::*, r#for::*, r#match::*,
remove::*, select::*, statement::*, sublist::*, tool::*, transform::*, value_node::*, r#while::*, remove::*, select::*, statement::*, sublist::*, tool::*, transform::*,
value_node::*,
}; };
use tree_sitter::Node; use tree_sitter::Node;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -123,7 +123,7 @@ if true {
If Else 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 Else Else If Else
================== ==================
if false { if false
"no" "no"
} else if false { else if false
"no" "no"
} else if 1 + 1 == 9 { else if 1 + 1 == 9
"not the answer" "not the answer"
} else { else
"42" "42"
}
--- ---

View File

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

View File

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

View File

@ -10,7 +10,8 @@ Simple Tool Call
(block (block
(statement (statement
(expression (expression
(tool (function_call
(built_in_function)
(expression (expression
(value (value
(string)))))))) (string))))))))
@ -19,7 +20,8 @@ Simple Tool Call
Nested 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 (block
(statement (statement
(expression (expression
(tool (function_call
(built_in_function)
(expression (expression
(identifier)) (function_call
(built_in_function)))
(expression (expression
(value (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 (block
(statement (statement
(expression (expression
(tool (function_call
(built_in_function)
(expression (expression
(identifier)))))))))) (identifier))))))))))

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff