From bc2615a1edd4bd9e908d51f16fb8154d17e2acb3 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 29 Nov 2023 19:23:42 -0500 Subject: [PATCH] Begin changes for new type definitions --- grammar.js | 407 + src/abstract_tree/assignment.rs | 16 +- src/abstract_tree/block.rs | 8 +- src/abstract_tree/expression.rs | 17 +- src/abstract_tree/filter.rs | 77 - src/abstract_tree/for.rs | 10 +- src/abstract_tree/function_call.rs | 12 +- src/abstract_tree/identifier.rs | 12 +- src/abstract_tree/if_else.rs | 8 +- src/abstract_tree/index.rs | 8 +- src/abstract_tree/index_assignment.rs | 8 +- src/abstract_tree/logic.rs | 8 +- src/abstract_tree/match.rs | 8 +- src/abstract_tree/math.rs | 8 +- src/abstract_tree/mod.rs | 57 +- src/abstract_tree/statement.rs | 51 +- src/abstract_tree/type.rs | 117 - src/abstract_tree/type_defintion.rs | 170 + src/abstract_tree/use.rs | 8 +- src/abstract_tree/value_node.rs | 31 +- src/abstract_tree/while.rs | 8 +- src/abstract_tree/yield.rs | 8 +- src/error.rs | 4 +- src/{evaluator.rs => evaluate.rs} | 33 +- src/lib.rs | 4 +- src/main.rs | 24 +- src/value/function.rs | 67 +- src/value/mod.rs | 49 +- tree-sitter-dust/.prettierignore | 1 + tree-sitter-dust/.prettierrc | 5 + tree-sitter-dust/corpus/assignment.txt | 3 +- tree-sitter-dust/corpus/async.txt | 9 +- tree-sitter-dust/corpus/built_in_function.txt | 23 +- tree-sitter-dust/corpus/for.txt | 14 +- tree-sitter-dust/corpus/functions.txt | 35 +- tree-sitter-dust/corpus/tables.txt | 105 - tree-sitter-dust/corpus/while.txt | 9 +- tree-sitter-dust/corpus/yield.txt | 3 +- tree-sitter-dust/grammar.js | 648 +- tree-sitter-dust/grammar.js.new | 407 + tree-sitter-dust/package-lock.json | 18 +- tree-sitter-dust/package.json | 1 + tree-sitter-dust/src/grammar.json | 252 +- tree-sitter-dust/src/node-types.json | 120 +- tree-sitter-dust/src/parser.c | 20659 ++++++++-------- tree-sitter-dust/test_output.md | 14 - 46 files changed, 11666 insertions(+), 11898 deletions(-) create mode 100644 grammar.js delete mode 100644 src/abstract_tree/filter.rs delete mode 100644 src/abstract_tree/type.rs create mode 100644 src/abstract_tree/type_defintion.rs rename src/{evaluator.rs => evaluate.rs} (89%) create mode 100644 tree-sitter-dust/.prettierignore create mode 100644 tree-sitter-dust/.prettierrc delete mode 100644 tree-sitter-dust/corpus/tables.txt create mode 100644 tree-sitter-dust/grammar.js.new delete mode 100644 tree-sitter-dust/test_output.md diff --git a/grammar.js b/grammar.js new file mode 100644 index 0000000..3858355 --- /dev/null +++ b/grammar.js @@ -0,0 +1,407 @@ +module.exports = grammar({ + name: "dust", + + word: $ => $.identifier, + + extras: $ => [/\s/, $._comment], + + rules: { + root: $ => + prec(1, repeat1($.statement)), + + _comment: $ => /[#][^#\n]*[#|\n]/, + + block: $ => + seq( + optional("async"), + "{", + repeat1($.statement), + "}", + ), + + statement: $ => + prec.left( + seq( + choice( + $.assignment, + $.block, + $.expression, + $.for, + $.if_else, + $.index_assignment, + $.match, + $.return, + $.use, + $.while, + ), + optional(";"), + ), + ), + + expression: $ => + prec.right( + choice( + $._expression_kind, + seq( + "(", + $._expression_kind, + ")", + ), + ), + ), + + _expression_kind: $ => + prec.right( + choice( + $.function_call, + $.identifier, + $.index, + $.logic, + $.math, + $.value, + $.yield, + ), + ), + + _expression_list: $ => + repeat1( + prec.right( + seq( + $.expression, + optional(","), + ), + ), + ), + + identifier: $ => + /[_a-zA-Z]+[_a-zA-Z0-9]?/, + + value: $ => + choice( + $.integer, + $.float, + $.string, + $.boolean, + $.list, + $.function, + $.table, + $.map, + ), + + integer: $ => + token( + prec.left( + seq( + optional("-"), + repeat1( + choice( + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + ), + ), + ), + ), + ), + + float: $ => + token( + prec.left( + seq( + optional("-"), + repeat1( + choice( + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + ), + ), + ".", + repeat1( + choice( + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", + ), + ), + ), + ), + ), + + string: $ => + /("[^"]*?")|('[^']*?')|(`[^`]*?`)/, + + boolean: $ => + choice("true", "false"), + + list: $ => + seq( + "[", + repeat( + prec.left( + seq( + $.expression, + optional(","), + ), + ), + ), + "]", + ), + + map: $ => + seq( + "{", + repeat( + seq( + $.identifier, + "=", + $.statement, + optional(","), + ), + ), + "}", + ), + + index: $ => + prec.left( + 1, + seq( + $.expression, + ":", + $.expression, + optional( + seq("..", $.expression), + ), + ), + ), + + math: $ => + prec.left( + seq( + $.expression, + $.math_operator, + $.expression, + ), + ), + + math_operator: $ => + choice("+", "-", "*", "/", "%"), + + logic: $ => + prec.right( + seq( + $.expression, + $.logic_operator, + $.expression, + ), + ), + + logic_operator: $ => + choice( + "==", + "!=", + "&&", + "||", + ">", + "<", + ">=", + "<=", + ), + + assignment: $ => + seq( + field( + "identifier", + $.identifier, + ), + optional( + field( + "type", + $.type_definition, + ), + ), + field( + "assignment_operator", + $.assignment_operator, + ), + field("statement", $.statement), + ), + + index_assignment: $ => + seq( + $.index, + $.assignment_operator, + $.statement, + ), + + assignment_operator: $ => + prec.right( + choice("=", "+=", "-="), + ), + + if_else: $ => + prec.right( + seq( + $.if, + repeat($.else_if), + optional($.else), + ), + ), + + if: $ => + seq("if", $.expression, $.block), + + else_if: $ => + seq( + "else if", + $.expression, + $.block, + ), + + else: $ => seq("else", $.block), + + match: $ => + prec.right( + seq( + "match", + $.expression, + repeat1( + seq( + $.expression, + "=>", + $.block, + ), + ), + ), + ), + + while: $ => + seq( + "while", + $.expression, + $.block, + ), + + for: $ => + seq( + choice("for", "async for"), + $.identifier, + "in", + $.expression, + $.block, + ), + + identifier_list: $ => + prec.right( + choice( + seq( + "|", + repeat( + seq( + $.identifier, + optional(","), + ), + ), + "|", + ), + ), + ), + + table: $ => + prec.right( + seq( + "table", + $.identifier_list, + $.expression, + ), + ), + + return: $ => + seq("return", $.expression), + + use: $ => seq("use", $.string), + + type_definition: $ => + seq("<", $.type, ">"), + + type: $ => + prec.right( + choice( + "any", + "bool", + seq( + "fn", + repeat( + seq( + $.type, + optional(","), + ), + ), + optional(seq("->", $.type)), + ), + "int", + seq("list", $.type), + "map", + "num", + "str", + ), + ), + + function: $ => + seq( + "|", + repeat( + seq( + $.identifier, + optional(","), + ), + ), + "|", + $.block, + ), + + function_call: $ => + prec.right( + 1, + seq( + "(", + $.expression, + optional($._expression_list), + ")", + ), + ), + + yield: $ => + prec.left( + seq( + $.expression, + "->", + "(", + $.expression, + optional($._expression_list), + ")", + ), + ), + }, +}); diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index 4bd2699..fd3b676 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -1,12 +1,12 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Identifier, Map, Result, Statement, Type, Value}; +use crate::{AbstractTree, Error, Identifier, Map, Result, Statement, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Assignment { identifier: Identifier, - r#type: Option, + r#type: Option, operator: AssignmentOperator, statement: Statement, } @@ -27,7 +27,7 @@ impl AbstractTree for Assignment { let type_node = node.child_by_field_name("type"); let r#type = if let Some(type_node) = type_node { - Some(Type::from_syntax_node(source, type_node)?) + Some(TypeDefinition::from_syntax_node(source, type_node)?) } else { None }; @@ -62,7 +62,7 @@ impl AbstractTree for Assignment { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let key = self.identifier.inner(); let value = self.statement.run(source, context)?; @@ -86,12 +86,12 @@ impl AbstractTree for Assignment { AssignmentOperator::Equal => value, }; - if let Some(r#type) = &self.r#type { - r#type.check(&new_value)?; - } - context.variables_mut()?.insert(key.clone(), new_value); Ok(Value::Empty) } + + fn expected_type(&self, _context: &Map) -> Result { + Ok(TypeDefinition::Empty) + } } diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index d050e05..65b17e5 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -4,7 +4,7 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Map, Result, Statement, Value}; +use crate::{AbstractTree, Error, Map, Result, Statement, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Block { @@ -41,7 +41,7 @@ impl AbstractTree for Block { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { if self.is_async { let statements = &self.statements; let final_result = RwLock::new(Ok(Value::Empty)); @@ -81,4 +81,8 @@ impl AbstractTree for Block { prev_result.unwrap_or(Ok(Value::Empty)) } } + + fn expected_type(&self, context: &Map) -> Result { + self.statements.last().unwrap().expected_type(context) + } } diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index 011fe32..ed635b8 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -2,7 +2,8 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; use crate::{ - value_node::ValueNode, AbstractTree, Error, Identifier, Index, Map, Result, Value, Yield, + value_node::ValueNode, AbstractTree, Error, Identifier, Index, Map, Result, TypeDefinition, + Value, Yield, }; use super::{function_call::FunctionCall, logic::Logic, math::Math}; @@ -51,7 +52,7 @@ impl AbstractTree for Expression { Ok(expression) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { match self { Expression::Value(value_node) => value_node.run(source, context), Expression::Identifier(identifier) => identifier.run(source, context), @@ -62,4 +63,16 @@ impl AbstractTree for Expression { Expression::Yield(r#yield) => r#yield.run(source, context), } } + + fn expected_type(&self, context: &Map) -> Result { + match self { + Expression::Value(value_node) => value_node.expected_type(context), + Expression::Identifier(identifier) => identifier.expected_type(context), + Expression::Math(math) => math.expected_type(context), + Expression::Logic(logic) => logic.expected_type(context), + Expression::FunctionCall(function_call) => function_call.expected_type(context), + Expression::Index(index) => index.expected_type(context), + Expression::Yield(r#yield) => r#yield.expected_type(context), + } + } } diff --git a/src/abstract_tree/filter.rs b/src/abstract_tree/filter.rs deleted file mode 100644 index d34eb9d..0000000 --- a/src/abstract_tree/filter.rs +++ /dev/null @@ -1,77 +0,0 @@ -use rayon::prelude::*; -use serde::{Deserialize, Serialize}; -use tree_sitter::Node; - -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, - item_id: Identifier, - collection: Expression, - predicate: Block, -} - -impl AbstractTree for Filter { - fn from_syntax_node(source: &str, node: Node) -> Result { - let count = match node.child_by_field_name("count") { - Some(node) => Some(Expression::from_syntax_node(source, node)?), - None => None, - }; - - let item_id_node = node.child_by_field_name("item_id").unwrap(); - let item_id = Identifier::from_syntax_node(source, item_id_node)?; - - let collection_node = node.child_by_field_name("collection").unwrap(); - let collection = Expression::from_syntax_node(source, collection_node)?; - - let predicate_node = node.child_by_field_name("predicate").unwrap(); - let predicate = Block::from_syntax_node(source, predicate_node)?; - - Ok(Filter { - count, - item_id, - collection, - predicate, - }) - } - - fn run(&self, source: &str, context: &mut Map) -> Result { - let value = self.collection.run(source, context)?; - let values = value.as_list()?.items(); - let key = self.item_id.inner(); - let new_values = List::new(); - let count = match &self.count { - Some(expression) => Some(expression.run(source, context)?.as_integer()? as usize), - None => None, - }; - let loop_context = Map::clone_from(context)?; - - values.par_iter().try_for_each(|value| { - if let Some(max) = count { - if new_values.items().len() == max { - return Ok(()); - } - } - - let mut iter_context = loop_context.clone(); - - iter_context - .variables_mut()? - .insert(key.clone(), value.clone()); - - let should_include = self - .predicate - .run(source, &mut iter_context)? - .as_boolean()?; - - if should_include { - new_values.items_mut().push(value.clone()); - } - - Ok::<(), Error>(()) - })?; - - Ok(Value::List(new_values)) - } -} diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs index 7ca36f6..e01e5eb 100644 --- a/src/abstract_tree/for.rs +++ b/src/abstract_tree/for.rs @@ -2,7 +2,9 @@ use rayon::prelude::*; use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Value}; +use crate::{ + AbstractTree, Block, Error, Expression, Identifier, Map, Result, TypeDefinition, Value, +}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct For { @@ -47,7 +49,7 @@ impl AbstractTree for For { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let expression_run = self.collection.run(source, context)?; let values = expression_run.as_list()?.items(); let key = self.item_id.inner(); @@ -76,4 +78,8 @@ impl AbstractTree for For { Ok(Value::Empty) } + + fn expected_type(&self, _context: &Map) -> Result { + Ok(TypeDefinition::Empty) + } } diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index b5d7f02..5c83527 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Map, Result, Value, BUILT_IN_FUNCTIONS}; +use crate::{AbstractTree, Error, Map, Result, TypeDefinition, Value, BUILT_IN_FUNCTIONS}; use super::expression::Expression; @@ -45,7 +45,7 @@ impl AbstractTree for FunctionCall { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let function = if let Expression::Identifier(identifier) = &self.function { let key = identifier.inner(); @@ -77,15 +77,17 @@ impl AbstractTree for FunctionCall { let mut function_context = Map::clone_from(context)?; let parameter_expression_pairs = function.parameters().iter().zip(self.arguments.iter()); - for ((identifier, r#type), expression) in parameter_expression_pairs { + for (identifier, expression) in parameter_expression_pairs { let key = identifier.clone().take_inner(); let value = expression.run(source, context)?; - r#type.check(&value)?; - function_context.variables_mut()?.insert(key, value); } function.run(source, &mut function_context) } + + fn expected_type(&self, context: &Map) -> Result { + self.function.expected_type(context) + } } diff --git a/src/abstract_tree/identifier.rs b/src/abstract_tree/identifier.rs index 15689da..d4fc9ef 100644 --- a/src/abstract_tree/identifier.rs +++ b/src/abstract_tree/identifier.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Map, Result, Value}; +use crate::{AbstractTree, Error, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Identifier(String); @@ -29,11 +29,19 @@ impl AbstractTree for Identifier { Ok(Identifier(identifier.to_string())) } - fn run(&self, _source: &str, context: &mut Map) -> Result { + fn run(&self, _source: &str, context: &Map) -> Result { if let Some(value) = context.variables()?.get(&self.0) { Ok(value.clone()) } else { Err(Error::VariableIdentifierNotFound(self.inner().clone())) } } + + fn expected_type(&self, context: &Map) -> Result { + if let Some(value) = context.variables()?.get(&self.0) { + Ok(value.r#type(context)?) + } else { + Ok(TypeDefinition::Empty) + } + } } diff --git a/src/abstract_tree/if_else.rs b/src/abstract_tree/if_else.rs index 3e42770..1df79e2 100644 --- a/src/abstract_tree/if_else.rs +++ b/src/abstract_tree/if_else.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Block, Expression, Map, Result, Value}; +use crate::{AbstractTree, Block, Expression, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct IfElse { @@ -55,7 +55,7 @@ impl AbstractTree for IfElse { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let if_boolean = self.if_expression.run(source, context)?.as_boolean()?; if if_boolean { @@ -80,4 +80,8 @@ impl AbstractTree for IfElse { } } } + + fn expected_type(&self, context: &Map) -> Result { + self.if_block.expected_type(context) + } } diff --git a/src/abstract_tree/index.rs b/src/abstract_tree/index.rs index 4de72ad..ac72c02 100644 --- a/src/abstract_tree/index.rs +++ b/src/abstract_tree/index.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Expression, List, Map, Result, Value}; +use crate::{AbstractTree, Error, Expression, List, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Index { @@ -32,7 +32,7 @@ impl AbstractTree for Index { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let collection = self.collection.run(source, context)?; match collection { @@ -73,6 +73,10 @@ impl AbstractTree for Index { _ => Err(Error::ExpectedCollection { actual: collection }), } } + + fn expected_type(&self, context: &Map) -> Result { + self.collection.expected_type(context) + } } #[cfg(test)] diff --git a/src/abstract_tree/index_assignment.rs b/src/abstract_tree/index_assignment.rs index af71763..4d16c26 100644 --- a/src/abstract_tree/index_assignment.rs +++ b/src/abstract_tree/index_assignment.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Index, Map, Result, Statement, Value}; +use crate::{AbstractTree, Error, Index, Map, Result, Statement, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct IndexAssignment { @@ -49,7 +49,7 @@ impl AbstractTree for IndexAssignment { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let index_collection = self.index.collection.run(source, context)?; let index_context = index_collection.as_map().unwrap_or(&context); let index_key = if let crate::Expression::Identifier(identifier) = &self.index.index { @@ -90,4 +90,8 @@ impl AbstractTree for IndexAssignment { Ok(Value::Empty) } + + fn expected_type(&self, _context: &Map) -> Result { + Ok(TypeDefinition::Empty) + } } diff --git a/src/abstract_tree/logic.rs b/src/abstract_tree/logic.rs index 2ee4d3a..aac26b8 100644 --- a/src/abstract_tree/logic.rs +++ b/src/abstract_tree/logic.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Expression, Map, Result, Value}; +use crate::{AbstractTree, Error, Expression, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Logic { @@ -45,7 +45,7 @@ impl AbstractTree for Logic { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let left = self.left.run(source, context)?; let right = self.right.run(source, context)?; let result = match self.operator { @@ -73,6 +73,10 @@ impl AbstractTree for Logic { Ok(Value::Boolean(result)) } + + fn expected_type(&self, _context: &Map) -> Result { + Ok(TypeDefinition::Boolean) + } } #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] diff --git a/src/abstract_tree/match.rs b/src/abstract_tree/match.rs index 5c95eef..2c668c4 100644 --- a/src/abstract_tree/match.rs +++ b/src/abstract_tree/match.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Map, Result, Value}; +use crate::{AbstractTree, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Match {} @@ -16,7 +16,11 @@ impl AbstractTree for Match { todo!() } - fn run(&self, _source: &str, _context: &mut Map) -> Result { + fn run(&self, _source: &str, _context: &Map) -> Result { + todo!() + } + + fn expected_type(&self, _context: &Map) -> Result { todo!() } } diff --git a/src/abstract_tree/math.rs b/src/abstract_tree/math.rs index cbb93b6..8b5472b 100644 --- a/src/abstract_tree/math.rs +++ b/src/abstract_tree/math.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; -use crate::{AbstractTree, Error, Expression, Map, Result, Value}; +use crate::{AbstractTree, Error, Expression, Map, Result, TypeDefinition, Value}; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] pub struct Math { @@ -42,7 +42,7 @@ impl AbstractTree for Math { }) } - fn run(&self, source: &str, context: &mut Map) -> Result { + fn run(&self, source: &str, context: &Map) -> Result { let left = self.left.run(source, context)?; let right = self.right.run(source, context)?; let value = match self.operator { @@ -55,6 +55,10 @@ impl AbstractTree for Math { Ok(value) } + + fn expected_type(&self, _context: &Map) -> Result { + Ok(TypeDefinition::Number) + } } #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index 79035ad..35136de 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -9,38 +9,67 @@ pub mod assignment; pub mod block; pub mod expression; -pub mod filter; -pub mod find; pub mod r#for; pub mod function_call; pub mod identifier; pub mod if_else; pub mod index; pub mod index_assignment; -pub mod insert; pub mod logic; pub mod r#match; pub mod math; -pub mod remove; -pub mod select; pub mod statement; -pub mod transform; -pub mod r#type; +pub mod type_defintion; pub mod r#use; pub mod value_node; pub mod r#while; pub mod r#yield; pub use { - assignment::*, block::*, expression::*, filter::*, find::*, function_call::*, identifier::*, - if_else::*, index::*, index_assignment::IndexAssignment, insert::*, logic::*, math::*, - r#for::*, r#match::*, r#type::*, r#use::*, r#while::*, r#yield::*, remove::*, select::*, - statement::*, transform::*, value_node::*, + assignment::*, block::*, expression::*, function_call::*, identifier::*, if_else::*, index::*, + index_assignment::IndexAssignment, logic::*, math::*, r#for::*, r#match::*, r#use::*, + r#while::*, r#yield::*, statement::*, type_defintion::*, value_node::*, }; use tree_sitter::Node; -use crate::{Map, Result, Value}; +use crate::{Error, Map, Result, Value}; + +pub struct Root { + statements: Vec, +} + +impl AbstractTree for Root { + fn from_syntax_node(source: &str, node: Node) -> Result { + Error::expect_syntax_node(source, "root", node)?; + + let statement_count = node.child_count(); + let mut statements = Vec::with_capacity(statement_count); + + for index in 0..statement_count { + let statement_node = node.child(index).unwrap(); + let statement = Statement::from_syntax_node(source, statement_node)?; + + statements.push(statement); + } + + Ok(Root { statements }) + } + + fn run(&self, source: &str, context: &Map) -> Result { + let mut value = Value::Empty; + + for statement in &self.statements { + value = statement.run(source, context)?; + } + + Ok(value) + } + + fn expected_type(&self, context: &Map) -> Result { + self.statements.last().unwrap().expected_type(context) + } +} /// This trait is implemented by the Evaluator's internal types to form an /// executable tree that resolves to a single value. @@ -57,5 +86,7 @@ pub trait AbstractTree: Sized { fn from_syntax_node(source: &str, node: Node) -> Result; /// Execute dust code by traversing the tree. - fn run(&self, source: &str, context: &mut Map) -> Result; + fn run(&self, source: &str, context: &Map) -> Result; + + fn expected_type(&self, context: &Map) -> Result; } diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 4ed98c5..8c51d1b 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use tree_sitter::Node; use crate::{ - AbstractTree, Assignment, Block, Error, Expression, Filter, Find, For, IfElse, IndexAssignment, - Insert, Map, Match, Remove, Result, Select, Transform, Use, Value, While, + AbstractTree, Assignment, Block, Error, Expression, For, IfElse, IndexAssignment, Map, Match, + Result, TypeDefinition, Use, Value, While, }; /// Abstract representation of a statement. @@ -17,13 +17,7 @@ pub enum Statement { While(Box), Block(Box), For(Box), - Transform(Box), - Filter(Box), - Find(Box), - Remove(Box), Use(Use), - Select(Box