From d997bbd08aa7c1bcdf3013f569cdb0bdee2b0e84 Mon Sep 17 00:00:00 2001 From: Jeff Date: Sat, 10 Feb 2024 19:31:47 -0500 Subject: [PATCH] Continue implementing context --- src/abstract_tree/assignment.rs | 14 +++--- src/abstract_tree/assignment_operator.rs | 10 ++-- src/abstract_tree/block.rs | 21 ++++---- src/abstract_tree/built_in_value.rs | 14 ++++-- src/abstract_tree/command.rs | 13 ++--- src/abstract_tree/expression.rs | 24 +++++---- src/abstract_tree/for.rs | 26 +++++----- src/abstract_tree/function_call.rs | 17 +++---- src/abstract_tree/function_expression.rs | 22 +++------ src/abstract_tree/function_node.rs | 38 ++++---------- src/abstract_tree/identifier.rs | 20 +++++--- src/abstract_tree/if_else.rs | 10 ++-- src/abstract_tree/index.rs | 10 ++-- src/abstract_tree/index_assignment.rs | 23 ++++----- src/abstract_tree/index_expression.rs | 10 ++-- src/abstract_tree/logic.rs | 10 ++-- src/abstract_tree/logic_operator.rs | 14 ++++-- src/abstract_tree/match.rs | 10 ++-- src/abstract_tree/math.rs | 10 ++-- src/abstract_tree/math_operator.rs | 14 ++++-- src/abstract_tree/mod.rs | 7 ++- src/abstract_tree/new.rs | 10 ++-- src/abstract_tree/statement.rs | 12 ++--- src/abstract_tree/type.rs | 14 ++++-- src/abstract_tree/type_specification.rs | 10 ++-- src/abstract_tree/value_node.rs | 12 ++--- src/abstract_tree/while.rs | 10 ++-- src/abstract_tree/yield.rs | 63 ------------------------ src/built_in_functions/fs.rs | 4 +- src/built_in_functions/json.rs | 4 +- src/built_in_functions/mod.rs | 6 +-- src/built_in_functions/str.rs | 4 +- src/context.rs | 12 ++--- src/interpret.rs | 12 ++--- src/lib.rs | 3 +- src/value/function.rs | 6 +-- 36 files changed, 217 insertions(+), 302 deletions(-) delete mode 100644 src/abstract_tree/yield.rs diff --git a/src/abstract_tree/assignment.rs b/src/abstract_tree/assignment.rs index 8bd5771..a08575a 100644 --- a/src/abstract_tree/assignment.rs +++ b/src/abstract_tree/assignment.rs @@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::{ context::Context, error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, AssignmentOperator, Format, Identifier, Map, SourcePosition, Statement, - SyntaxNode, Type, TypeSpecification, Value, + AbstractTree, AssignmentOperator, Format, Identifier, SourcePosition, Statement, SyntaxNode, + Type, TypeSpecification, Value, }; /// Variable assignment, including add-assign and subtract-assign operations. @@ -130,13 +130,13 @@ impl AbstractTree for Assignment { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let key = self.identifier.inner(); let value = self.statement.run(source, context)?; let new_value = match self.operator { AssignmentOperator::PlusEqual => { - if let Some((mut previous_value, _)) = context.variables()?.get(key).cloned() { + if let Some(mut previous_value) = context.get_value(key)? { previous_value += value; previous_value } else { @@ -144,7 +144,7 @@ impl AbstractTree for Assignment { } } AssignmentOperator::MinusEqual => { - if let Some((mut previous_value, _)) = context.variables()?.get(key).cloned() { + if let Some(mut previous_value) = context.get_value(key)? { previous_value -= value; previous_value } else { @@ -154,12 +154,12 @@ impl AbstractTree for Assignment { AssignmentOperator::Equal => value, }; - context.set(key.clone(), new_value)?; + context.set_value(key.clone(), new_value)?; Ok(Value::none()) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } } diff --git a/src/abstract_tree/assignment_operator.rs b/src/abstract_tree/assignment_operator.rs index 2963509..b94c92d 100644 --- a/src/abstract_tree/assignment_operator.rs +++ b/src/abstract_tree/assignment_operator.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, SyntaxNode, Type, Value, }; /// Operators that be used in an assignment statement. @@ -17,7 +17,7 @@ impl AbstractTree for AssignmentOperator { fn from_syntax( node: SyntaxNode, source: &str, - _context: &crate::Map, + _context: &Context, ) -> Result { SyntaxError::expect_syntax_node(source, "assignment_operator", node)?; @@ -39,15 +39,15 @@ impl AbstractTree for AssignmentOperator { Ok(operator) } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { Ok(Value::none()) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } } diff --git a/src/abstract_tree/block.rs b/src/abstract_tree/block.rs index b00c34f..0189862 100644 --- a/src/abstract_tree/block.rs +++ b/src/abstract_tree/block.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{rw_lock_error::RwLockError, RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, Statement, SyntaxNode, Type, Value, + AbstractTree, Context, Format, Statement, SyntaxNode, Type, Value, }; /// Abstract representation of a block. @@ -20,11 +20,10 @@ use crate::{ pub struct Block { is_async: bool, statements: Vec, - context: Map, } impl AbstractTree for Block { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "block", node)?; let first_child = node.child(0).unwrap(); @@ -36,13 +35,12 @@ impl AbstractTree for Block { node.child_count() - 2 }; let mut statements = Vec::with_capacity(statement_count); - let block_context = Map::clone_from(context)?; for index in 1..node.child_count() - 1 { let child_node = node.child(index).unwrap(); if child_node.kind() == "statement" { - let statement = Statement::from_syntax(child_node, source, &block_context)?; + let statement = Statement::from_syntax(child_node, source, &context)?; statements.push(statement); } @@ -51,23 +49,22 @@ impl AbstractTree for Block { Ok(Block { is_async, statements, - context: block_context, }) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { for statement in &self.statements { if let Statement::Return(inner_statement) = statement { - return inner_statement.validate(_source, &self.context); + return inner_statement.validate(_source, _context); } else { - statement.validate(_source, &self.context)?; + statement.validate(_source, _context)?; } } Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { if self.is_async { let statements = &self.statements; let final_result = RwLock::new(Ok(Value::none())); @@ -76,7 +73,7 @@ impl AbstractTree for Block { .into_par_iter() .enumerate() .find_map_first(|(index, statement)| { - let result = statement.run(source, &self.context); + let result = statement.run(source, context); let is_last_statement = index == statements.len() - 1; let is_return_statement = if let Statement::Return(_) = statement { true @@ -116,7 +113,7 @@ impl AbstractTree for Block { } } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { if let Some(statement) = self.statements.iter().find(|statement| { if let Statement::Return(_) = statement { true diff --git a/src/abstract_tree/built_in_value.rs b/src/abstract_tree/built_in_value.rs index c3abf97..d0d8e1e 100644 --- a/src/abstract_tree/built_in_value.rs +++ b/src/abstract_tree/built_in_value.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::{ built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable}, error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, BuiltInFunction, Format, Function, List, Map, SyntaxNode, Type, Value, + AbstractTree, BuiltInFunction, Context, Format, Function, List, Map, SyntaxNode, Type, Value, }; static ARGS: OnceLock = OnceLock::new(); @@ -175,7 +175,11 @@ impl BuiltInValue { } impl AbstractTree for BuiltInValue { - fn from_syntax(node: SyntaxNode, _source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + _source: &str, + _context: &Context, + ) -> Result { let built_in_value = match node.kind() { "args" => BuiltInValue::Args, "assert_equal" => BuiltInValue::AssertEqual, @@ -191,15 +195,15 @@ impl AbstractTree for BuiltInValue { Ok(built_in_value) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(self.r#type()) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { Ok(self.get().clone()) } } diff --git a/src/abstract_tree/command.rs b/src/abstract_tree/command.rs index 4aed217..88c9c67 100644 --- a/src/abstract_tree/command.rs +++ b/src/abstract_tree/command.rs @@ -1,10 +1,11 @@ use std::process; use serde::{Deserialize, Serialize}; +use tree_sitter::Node as SyntaxNode; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, Type, Value, + AbstractTree, Context, Format, Type, Value, }; /// An external program invokation. @@ -16,9 +17,9 @@ pub struct Command { impl AbstractTree for Command { fn from_syntax( - node: tree_sitter::Node, + node: SyntaxNode, source: &str, - _context: &crate::Map, + _context: &Context, ) -> Result { SyntaxError::expect_syntax_node(source, "command", node)?; @@ -47,15 +48,15 @@ impl AbstractTree for Command { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::String) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { todo!() } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { let output = process::Command::new(&self.command_text) .args(&self.command_arguments) .spawn()? diff --git a/src/abstract_tree/expression.rs b/src/abstract_tree/expression.rs index ed8fe48..47e1da9 100644 --- a/src/abstract_tree/expression.rs +++ b/src/abstract_tree/expression.rs @@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, value_node::ValueNode, - AbstractTree, Command, Format, FunctionCall, Identifier, Index, Logic, Map, Math, New, - SyntaxNode, Type, Value, Yield, + AbstractTree, Command, Context, Format, FunctionCall, Identifier, Index, Logic, Math, New, + SyntaxNode, Type, Value, }; /// Abstract representation of an expression statement. @@ -20,13 +20,16 @@ pub enum Expression { Math(Box), Logic(Box), FunctionCall(Box), - Yield(Box), New(New), Command(Command), } impl AbstractTree for Expression { - fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + source: &str, + _context: &Context, + ) -> Result { SyntaxError::expect_syntax_node(source, "expression", node)?; let child = if node.child(0).unwrap().is_named() { @@ -46,13 +49,12 @@ impl AbstractTree for Expression { "function_call" => Expression::FunctionCall(Box::new(FunctionCall::from_syntax( child, source, _context, )?)), - "yield" => Expression::Yield(Box::new(Yield::from_syntax(child, source, _context)?)), "new" => Expression::New(New::from_syntax(child, source, _context)?), "command" => Expression::Command(Command::from_syntax(child, source, _context)?), _ => { return Err(SyntaxError::UnexpectedSyntaxNode { expected: - "value, identifier, index, math, logic, function call, new, context or ->" + "value, identifier, index, math, logic, function call, new or command" .to_string(), actual: child.kind().to_string(), location: child.start_position(), @@ -64,7 +66,7 @@ impl AbstractTree for Expression { Ok(expression) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { match self { Expression::Value(value_node) => value_node.expected_type(_context), Expression::Identifier(identifier) => identifier.expected_type(_context), @@ -72,13 +74,12 @@ impl AbstractTree for Expression { 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), Expression::New(new) => new.expected_type(_context), Expression::Command(command) => command.expected_type(_context), } } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { match self { Expression::Value(value_node) => value_node.validate(_source, _context), Expression::Identifier(identifier) => identifier.validate(_source, _context), @@ -86,13 +87,12 @@ impl AbstractTree for Expression { Expression::Logic(logic) => logic.validate(_source, _context), Expression::FunctionCall(function_call) => function_call.validate(_source, _context), Expression::Index(index) => index.validate(_source, _context), - Expression::Yield(r#yield) => r#yield.validate(_source, _context), Expression::New(new) => new.validate(_source, _context), Expression::Command(command) => command.validate(_source, _context), } } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { match self { Expression::Value(value_node) => value_node.run(_source, _context), Expression::Identifier(identifier) => identifier.run(_source, _context), @@ -100,7 +100,6 @@ impl AbstractTree for Expression { Expression::Logic(logic) => logic.run(_source, _context), Expression::FunctionCall(function_call) => function_call.run(_source, _context), Expression::Index(index) => index.run(_source, _context), - Expression::Yield(r#yield) => r#yield.run(_source, _context), Expression::New(new) => new.run(_source, _context), Expression::Command(command) => command.run(_source, _context), } @@ -116,7 +115,6 @@ impl Format for Expression { Expression::Logic(logic) => logic.format(_output, _indent_level), Expression::FunctionCall(function_call) => function_call.format(_output, _indent_level), Expression::Index(index) => index.format(_output, _indent_level), - Expression::Yield(r#yield) => r#yield.format(_output, _indent_level), Expression::New(new) => new.format(_output, _indent_level), Expression::Command(command) => command.format(_output, _indent_level), } diff --git a/src/abstract_tree/for.rs b/src/abstract_tree/for.rs index 659533c..892a2ab 100644 --- a/src/abstract_tree/for.rs +++ b/src/abstract_tree/for.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Block, Expression, Format, Identifier, Map, SourcePosition, SyntaxNode, Type, + AbstractTree, Block, Context, Expression, Format, Identifier, SourcePosition, SyntaxNode, Type, Value, }; @@ -18,7 +18,7 @@ pub struct For { } impl AbstractTree for For { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "for", node)?; let for_node = node.child(0).unwrap(); @@ -53,11 +53,11 @@ impl AbstractTree for For { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> { let collection_type = self.collection.expected_type(context)?; let item_type = if let Type::List(item_type) = collection_type { item_type.as_ref().clone() @@ -76,24 +76,24 @@ impl AbstractTree for For { self.block.validate(_source, context) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let expression_run = self.collection.run(source, context)?; let key = self.item_id.inner(); if let Value::Range(range) = expression_run { if self.is_async { range.into_par_iter().try_for_each(|integer| { - let iter_context = Map::clone_from(context)?; + let iter_context = Context::inherit_from(context)?; - iter_context.set(key.clone(), Value::Integer(integer))?; + iter_context.set_value(key.clone(), Value::Integer(integer))?; self.block.run(source, &iter_context).map(|_value| ()) })?; } else { - let loop_context = Map::clone_from(context)?; + let loop_context = Context::inherit_from(context)?; for i in range { - loop_context.set(key.clone(), Value::Integer(i))?; + loop_context.set_value(key.clone(), Value::Integer(i))?; self.block.run(source, &loop_context)?; } @@ -106,17 +106,17 @@ impl AbstractTree for For { if self.is_async { values.par_iter().try_for_each(|value| { - let iter_context = Map::clone_from(context)?; + let iter_context = Context::inherit_from(context)?; - iter_context.set(key.clone(), value.clone())?; + iter_context.set_value(key.clone(), value.clone())?; self.block.run(source, &iter_context).map(|_value| ()) })?; } else { - let loop_context = Map::clone_from(context)?; + let loop_context = Context::inherit_from(context)?; for value in values.iter() { - loop_context.set(key.clone(), value.clone())?; + loop_context.set_value(key.clone(), value.clone())?; self.block.run(source, &loop_context)?; } diff --git a/src/abstract_tree/function_call.rs b/src/abstract_tree/function_call.rs index 89615bf..802c57b 100644 --- a/src/abstract_tree/function_call.rs +++ b/src/abstract_tree/function_call.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Expression, Format, FunctionExpression, Map, SourcePosition, SyntaxNode, Type, - Value, + AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode, + Type, Value, }; /// A function being invoked and the arguments it is being passed. @@ -30,7 +30,7 @@ impl FunctionCall { } impl AbstractTree for FunctionCall { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "function_call", node)?; let function_node = node.child(0).unwrap(); @@ -55,7 +55,7 @@ impl AbstractTree for FunctionCall { }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { match &self.function_expression { FunctionExpression::Identifier(identifier) => { let identifier_type = identifier.expected_type(context)?; @@ -81,11 +81,10 @@ impl AbstractTree for FunctionCall { } } FunctionExpression::Index(index) => index.expected_type(context), - FunctionExpression::Yield(r#yield) => r#yield.expected_type(context), } } - fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> { let function_expression_type = self.function_expression.expected_type(context)?; let parameter_types = match function_expression_type { @@ -126,13 +125,12 @@ impl AbstractTree for FunctionCall { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let value = match &self.function_expression { FunctionExpression::Identifier(identifier) => { let key = identifier.inner(); - let variables = context.variables()?; - if let Some((value, _)) = variables.get(key) { + if let Some(value) = context.get_value(key)? { value.clone() } else { return Err(RuntimeError::VariableIdentifierNotFound( @@ -145,7 +143,6 @@ impl AbstractTree for FunctionCall { } FunctionExpression::Value(value_node) => value_node.run(source, context)?, FunctionExpression::Index(index) => index.run(source, context)?, - FunctionExpression::Yield(r#yield) => r#yield.run(source, context)?, }; let mut arguments = Vec::with_capacity(self.arguments.len()); diff --git a/src/abstract_tree/function_expression.rs b/src/abstract_tree/function_expression.rs index 7a8def8..e56e8b6 100644 --- a/src/abstract_tree/function_expression.rs +++ b/src/abstract_tree/function_expression.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, FunctionCall, Identifier, Index, Map, SyntaxNode, Type, Value, ValueNode, - Yield, + AbstractTree, Context, Format, FunctionCall, Identifier, Index, SyntaxNode, Type, Value, + ValueNode, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -12,11 +12,10 @@ pub enum FunctionExpression { FunctionCall(Box), Value(ValueNode), Index(Index), - Yield(Box), } impl AbstractTree for FunctionExpression { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "function_expression", node)?; let first_child = node.child(0).unwrap(); @@ -36,12 +35,9 @@ impl AbstractTree for FunctionExpression { )), "value" => FunctionExpression::Value(ValueNode::from_syntax(child, source, context)?), "index" => FunctionExpression::Index(Index::from_syntax(child, source, context)?), - "yield" => { - FunctionExpression::Yield(Box::new(Yield::from_syntax(child, source, context)?)) - } _ => { return Err(SyntaxError::UnexpectedSyntaxNode { - expected: "identifier, function call, value, index or yield".to_string(), + expected: "identifier, function call, value or index".to_string(), actual: child.kind().to_string(), location: child.start_position(), relevant_source: source[child.byte_range()].to_string(), @@ -52,17 +48,16 @@ impl AbstractTree for FunctionExpression { Ok(function_expression) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { match self { FunctionExpression::Identifier(identifier) => identifier.expected_type(context), FunctionExpression::FunctionCall(function_call) => function_call.expected_type(context), FunctionExpression::Value(value_node) => value_node.expected_type(context), FunctionExpression::Index(index) => index.expected_type(context), - FunctionExpression::Yield(r#yield) => r#yield.expected_type(context), } } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { match self { FunctionExpression::Identifier(identifier) => identifier.validate(_source, _context), FunctionExpression::FunctionCall(function_call) => { @@ -70,17 +65,15 @@ impl AbstractTree for FunctionExpression { } FunctionExpression::Value(value_node) => value_node.validate(_source, _context), FunctionExpression::Index(index) => index.validate(_source, _context), - FunctionExpression::Yield(r#yield) => r#yield.validate(_source, _context), } } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { match self { FunctionExpression::Identifier(identifier) => identifier.run(source, context), FunctionExpression::FunctionCall(function_call) => function_call.run(source, context), FunctionExpression::Value(value_node) => value_node.run(source, context), FunctionExpression::Index(index) => index.run(source, context), - FunctionExpression::Yield(r#yield) => r#yield.run(source, context), } } } @@ -94,7 +87,6 @@ impl Format for FunctionExpression { function_call.format(output, indent_level) } FunctionExpression::Index(index) => index.format(output, indent_level), - FunctionExpression::Yield(r#yield) => r#yield.format(output, indent_level), } } } diff --git a/src/abstract_tree/function_node.rs b/src/abstract_tree/function_node.rs index 45619f5..ed9d4dd 100644 --- a/src/abstract_tree/function_node.rs +++ b/src/abstract_tree/function_node.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Block, Format, Function, Identifier, Map, SourcePosition, SyntaxNode, Type, + AbstractTree, Block, Context, Format, Function, Identifier, SourcePosition, SyntaxNode, Type, TypeSpecification, Value, }; @@ -61,21 +61,15 @@ impl FunctionNode { &self, arguments: &[Value], source: &str, - outer_context: &Map, + outer_context: &Context, ) -> Result { - let function_context = Map::new(); + let function_context = Context::inherit_from(outer_context)?; let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter()); - for (key, (value, r#type)) in outer_context.variables()?.iter() { - if r#type.is_function() { - function_context.set(key.clone(), value.clone())?; - } - } - for (identifier, value) in parameter_argument_pairs { let key = identifier.inner().clone(); - function_context.set(key, value.clone())?; + function_context.set_value(key, value.clone())?; } let return_value = self.body.run(source, &function_context)?; @@ -88,7 +82,7 @@ impl AbstractTree for FunctionNode { fn from_syntax( node: SyntaxNode, source: &str, - outer_context: &Map, + outer_context: &Context, ) -> Result { SyntaxError::expect_syntax_node(source, "function", node)?; @@ -116,18 +110,12 @@ impl AbstractTree for FunctionNode { let return_type_node = node.child(child_count - 2).unwrap(); let return_type = TypeSpecification::from_syntax(return_type_node, source, outer_context)?; - let function_context = Map::new(); + let function_context = Context::inherit_from(outer_context)?; for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) { function_context.set_type(parameter.inner().clone(), parameter_type.clone())?; } - for (key, (value, r#type)) in outer_context.variables()?.iter() { - if r#type.is_function() { - function_context.set(key.clone(), value.clone())?; - } - } - let body_node = node.child(child_count - 1).unwrap(); let body = Block::from_syntax(body_node, source, &function_context)?; @@ -142,18 +130,12 @@ impl AbstractTree for FunctionNode { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(self.r#type().clone()) } - fn validate(&self, source: &str, context: &Map) -> Result<(), ValidationError> { - let function_context = Map::new(); - - for (key, (_value, r#type)) in context.variables()?.iter() { - if r#type.is_function() { - function_context.set_type(key.clone(), r#type.clone())?; - } - } + fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> { + let function_context = Context::inherit_from(context)?; if let Type::Function { parameter_types, @@ -185,7 +167,7 @@ impl AbstractTree for FunctionNode { } } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { let self_as_value = Value::Function(Function::ContextDefined(self.clone())); Ok(self_as_value) diff --git a/src/abstract_tree/identifier.rs b/src/abstract_tree/identifier.rs index 4106da4..279fbb2 100644 --- a/src/abstract_tree/identifier.rs +++ b/src/abstract_tree/identifier.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, SyntaxNode, Type, Value, }; /// A string by which a variable is known to a context. @@ -29,7 +29,11 @@ impl Identifier { } impl AbstractTree for Identifier { - fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + source: &str, + _context: &Context, + ) -> Result { SyntaxError::expect_syntax_node(source, "identifier", node)?; let text = &source[node.byte_range()]; @@ -39,20 +43,20 @@ impl AbstractTree for Identifier { Ok(Identifier(text.to_string())) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn expected_type(&self, context: &Map) -> Result { - if let Some((_value, r#type)) = context.variables()?.get(&self.0) { - Ok(r#type.clone()) + fn expected_type(&self, context: &Context) -> Result { + if let Some(r#type) = context.get_type(&self.0)? { + Ok(r#type) } else { Err(ValidationError::VariableIdentifierNotFound(self.clone())) } } - fn run(&self, _source: &str, context: &Map) -> Result { - if let Some((value, _)) = context.variables()?.get(&self.0) { + fn run(&self, _source: &str, context: &Context) -> Result { + if let Some(value) = context.get_value(&self.0)? { Ok(value.clone()) } else { Err(RuntimeError::VariableIdentifierNotFound(self.0.clone())) diff --git a/src/abstract_tree/if_else.rs b/src/abstract_tree/if_else.rs index 92617a2..aa9a807 100644 --- a/src/abstract_tree/if_else.rs +++ b/src/abstract_tree/if_else.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Block, Expression, Format, Map, SourcePosition, SyntaxNode, Type, Value, + AbstractTree, Block, Context, Expression, Format, SourcePosition, SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -16,7 +16,7 @@ pub struct IfElse { } impl AbstractTree for IfElse { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { let if_expression_node = node.child(0).unwrap().child(1).unwrap(); let if_expression = Expression::from_syntax(if_expression_node, source, context)?; @@ -59,11 +59,11 @@ impl AbstractTree for IfElse { }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { self.if_block.expected_type(context) } - fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> { self.if_expression.validate(_source, context)?; self.if_block.validate(_source, context)?; @@ -103,7 +103,7 @@ impl AbstractTree for IfElse { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let if_boolean = self.if_expression.run(source, context)?.as_boolean()?; if if_boolean { diff --git a/src/abstract_tree/index.rs b/src/abstract_tree/index.rs index e17d801..36af7e1 100644 --- a/src/abstract_tree/index.rs +++ b/src/abstract_tree/index.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, IndexExpression, List, Map, SourcePosition, SyntaxNode, Type, Value, + AbstractTree, Context, Format, IndexExpression, List, SourcePosition, SyntaxNode, Type, Value, }; /// Abstract representation of an index expression. @@ -17,7 +17,7 @@ pub struct Index { } impl AbstractTree for Index { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "index", node)?; let collection_node = node.child(0).unwrap(); @@ -45,7 +45,7 @@ impl AbstractTree for Index { }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { match self.collection.expected_type(context)? { Type::List(item_type) => Ok(*item_type.clone()), Type::Map(_) => Ok(Type::Any), @@ -54,7 +54,7 @@ impl AbstractTree for Index { } } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { self.collection.validate(_source, _context)?; self.index.validate(_source, _context)?; @@ -65,7 +65,7 @@ impl AbstractTree for Index { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let value = self.collection.run(source, context)?; match value { diff --git a/src/abstract_tree/index_assignment.rs b/src/abstract_tree/index_assignment.rs index bc0636a..ab72c89 100644 --- a/src/abstract_tree/index_assignment.rs +++ b/src/abstract_tree/index_assignment.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, AssignmentOperator, Format, Index, IndexExpression, Map, Statement, SyntaxNode, - Type, Value, + AbstractTree, AssignmentOperator, Context, Format, Index, IndexExpression, Statement, + SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -14,7 +14,7 @@ pub struct IndexAssignment { } impl AbstractTree for IndexAssignment { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "index_assignment", node)?; let index_node = node.child(0).unwrap(); @@ -33,18 +33,17 @@ impl AbstractTree for IndexAssignment { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { self.index.validate(_source, _context)?; self.statement.validate(_source, _context) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> 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 IndexExpression::Identifier(identifier) = &self.index.index { identifier.inner() } else { @@ -57,9 +56,7 @@ impl AbstractTree for IndexAssignment { let new_value = match self.operator { AssignmentOperator::PlusEqual => { - if let Some((mut previous_value, _)) = - index_context.variables()?.get(index_key).cloned() - { + if let Some(mut previous_value) = context.get_value(index_key)? { previous_value += value; previous_value } else { @@ -67,9 +64,7 @@ impl AbstractTree for IndexAssignment { } } AssignmentOperator::MinusEqual => { - if let Some((mut previous_value, _)) = - index_context.variables()?.get(index_key).cloned() - { + if let Some(mut previous_value) = context.get_value(index_key)? { previous_value -= value; previous_value } else { @@ -79,7 +74,7 @@ impl AbstractTree for IndexAssignment { AssignmentOperator::Equal => value, }; - index_context.set(index_key.clone(), new_value)?; + context.set_value(index_key.clone(), new_value)?; Ok(Value::none()) } diff --git a/src/abstract_tree/index_expression.rs b/src/abstract_tree/index_expression.rs index 235396f..474ed6a 100644 --- a/src/abstract_tree/index_expression.rs +++ b/src/abstract_tree/index_expression.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, value_node::ValueNode, - AbstractTree, Format, FunctionCall, Identifier, Index, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, FunctionCall, Identifier, Index, SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -15,7 +15,7 @@ pub enum IndexExpression { } impl AbstractTree for IndexExpression { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "index_expression", node)?; let first_child = node.child(0).unwrap(); @@ -49,7 +49,7 @@ impl AbstractTree for IndexExpression { Ok(abstract_node) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { match self { IndexExpression::Value(value_node) => value_node.expected_type(context), IndexExpression::Identifier(identifier) => identifier.expected_type(context), @@ -58,7 +58,7 @@ impl AbstractTree for IndexExpression { } } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { match self { IndexExpression::Value(value_node) => value_node.validate(_source, _context), IndexExpression::Identifier(identifier) => identifier.validate(_source, _context), @@ -69,7 +69,7 @@ impl AbstractTree for IndexExpression { } } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { match self { IndexExpression::Value(value_node) => value_node.run(source, context), IndexExpression::Identifier(identifier) => identifier.run(source, context), diff --git a/src/abstract_tree/logic.rs b/src/abstract_tree/logic.rs index 13b1b60..abd9e00 100644 --- a/src/abstract_tree/logic.rs +++ b/src/abstract_tree/logic.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Expression, Format, LogicOperator, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Expression, Format, LogicOperator, SyntaxNode, Type, Value, }; /// Abstract representation of a logic expression. @@ -14,7 +14,7 @@ pub struct Logic { } impl AbstractTree for Logic { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "logic", node)?; let first_node = node.child(0).unwrap(); @@ -40,16 +40,16 @@ impl AbstractTree for Logic { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::Boolean) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { self.left.validate(_source, _context)?; self.right.validate(_source, _context) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let left = self.left.run(source, context)?; let right = self.right.run(source, context)?; let result = match self.operator { diff --git a/src/abstract_tree/logic_operator.rs b/src/abstract_tree/logic_operator.rs index 7092216..4d80b68 100644 --- a/src/abstract_tree/logic_operator.rs +++ b/src/abstract_tree/logic_operator.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -18,7 +18,11 @@ pub enum LogicOperator { } impl AbstractTree for LogicOperator { - fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + source: &str, + _context: &Context, + ) -> Result { SyntaxError::expect_syntax_node(source, "logic_operator", node)?; let operator_node = node.child(0).unwrap(); @@ -44,15 +48,15 @@ impl AbstractTree for LogicOperator { Ok(operator) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { Ok(Value::none()) } } diff --git a/src/abstract_tree/match.rs b/src/abstract_tree/match.rs index c0d66d0..437e461 100644 --- a/src/abstract_tree/match.rs +++ b/src/abstract_tree/match.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Expression, Format, Map, Statement, SyntaxNode, Type, Value, + AbstractTree, Context, Expression, Format, Statement, SyntaxNode, Type, Value, }; /// Abstract representation of a match statement. @@ -18,7 +18,7 @@ pub struct Match { } impl AbstractTree for Match { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "match", node)?; let matcher_node = node.child(1).unwrap(); @@ -59,13 +59,13 @@ impl AbstractTree for Match { }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { let (_, first_statement) = self.options.first().unwrap(); first_statement.expected_type(context) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { self.matcher.validate(_source, _context)?; for (expression, statement) in &self.options { @@ -80,7 +80,7 @@ impl AbstractTree for Match { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let matcher_value = self.matcher.run(source, context)?; for (expression, statement) in &self.options { diff --git a/src/abstract_tree/math.rs b/src/abstract_tree/math.rs index 4a09d7c..aa315f5 100644 --- a/src/abstract_tree/math.rs +++ b/src/abstract_tree/math.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Expression, Format, Map, MathOperator, SyntaxNode, Type, Value, + AbstractTree, Context, Expression, Format, MathOperator, SyntaxNode, Type, Value, }; /// Abstract representation of a math operation. @@ -17,7 +17,7 @@ pub struct Math { } impl AbstractTree for Math { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "math", node)?; let left_node = node.child(0).unwrap(); @@ -36,16 +36,16 @@ impl AbstractTree for Math { }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { self.left.expected_type(context) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { self.left.validate(_source, _context)?; self.right.validate(_source, _context) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let left = self.left.run(source, context)?; let right = self.right.run(source, context)?; let value = match self.operator { diff --git a/src/abstract_tree/math_operator.rs b/src/abstract_tree/math_operator.rs index 4db7fe9..89d8290 100644 --- a/src/abstract_tree/math_operator.rs +++ b/src/abstract_tree/math_operator.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -15,7 +15,11 @@ pub enum MathOperator { } impl AbstractTree for MathOperator { - fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + source: &str, + _context: &Context, + ) -> Result { let operator_node = node.child(0).unwrap(); let operator = match operator_node.kind() { "+" => MathOperator::Add, @@ -36,15 +40,15 @@ impl AbstractTree for MathOperator { Ok(operator) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { Ok(Value::none()) } } diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index f8e0fe0..ef669de 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -32,14 +32,13 @@ pub mod r#type; pub mod type_specification; pub mod value_node; pub mod r#while; -pub mod r#yield; pub use { assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, expression::*, function_call::*, function_expression::*, function_node::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*, logic::*, logic_operator::*, - math::*, math_operator::*, new::*, r#for::*, r#match::*, r#type::*, r#while::*, r#yield::*, - statement::*, type_specification::*, value_node::*, + math::*, math_operator::*, new::*, r#for::*, r#match::*, r#type::*, r#while::*, statement::*, + type_specification::*, value_node::*, }; use serde::{Deserialize, Serialize}; @@ -47,7 +46,7 @@ use serde::{Deserialize, Serialize}; use crate::{ context::Context, error::{RuntimeError, SyntaxError, ValidationError}, - Map, SyntaxNode, Value, + SyntaxNode, Value, }; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] diff --git a/src/abstract_tree/new.rs b/src/abstract_tree/new.rs index fef1529..49575ae 100644 --- a/src/abstract_tree/new.rs +++ b/src/abstract_tree/new.rs @@ -3,7 +3,7 @@ use tree_sitter::Node; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Identifier, Map, Type, TypeSpecification, Value, ValueNode, + AbstractTree, Context, Format, Identifier, Type, TypeSpecification, Value, ValueNode, }; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] @@ -13,7 +13,7 @@ pub struct New { } impl AbstractTree for New { - fn from_syntax(node: Node, source: &str, context: &Map) -> Result { + fn from_syntax(node: Node, source: &str, context: &Context) -> Result { let identifier_node = node.child(1).unwrap(); let identifier = Identifier::from_syntax(identifier_node, source, context)?; @@ -25,15 +25,15 @@ impl AbstractTree for New { }) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { todo!() } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { todo!() } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { todo!() } } diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 917ea8e..14f978d 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Assignment, Block, Expression, For, Format, IfElse, IndexAssignment, Map, Match, - SyntaxNode, Type, Value, While, + AbstractTree, Assignment, Block, Context, Expression, For, Format, IfElse, IndexAssignment, + Match, SyntaxNode, Type, Value, While, }; /// Abstract representation of a statement. @@ -21,7 +21,7 @@ pub enum Statement { } impl AbstractTree for Statement { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "statement", node)?; let child = node.child(0).unwrap(); @@ -66,7 +66,7 @@ impl AbstractTree for Statement { } } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { match self { Statement::Assignment(assignment) => assignment.expected_type(context), Statement::Expression(expression) => expression.expected_type(context), @@ -80,7 +80,7 @@ impl AbstractTree for Statement { } } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { match self { Statement::Assignment(assignment) => assignment.validate(_source, _context), Statement::Expression(expression) => expression.validate(_source, _context), @@ -96,7 +96,7 @@ impl AbstractTree for Statement { } } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { match self { Statement::Assignment(assignment) => assignment.run(source, context), Statement::Expression(expression) => expression.run(source, context), diff --git a/src/abstract_tree/type.rs b/src/abstract_tree/type.rs index 9c24425..c8a68c8 100644 --- a/src/abstract_tree/type.rs +++ b/src/abstract_tree/type.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Identifier, Map, Structure, SyntaxNode, Value, + AbstractTree, Context, Format, Identifier, Structure, SyntaxNode, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -126,7 +126,11 @@ impl Type { } impl AbstractTree for Type { - fn from_syntax(node: SyntaxNode, _source: &str, _context: &Map) -> Result { + fn from_syntax( + node: SyntaxNode, + _source: &str, + _context: &Context, + ) -> Result { SyntaxError::expect_syntax_node(_source, "type", node)?; let type_node = node.child(0).unwrap(); @@ -192,15 +196,15 @@ impl AbstractTree for Type { Ok(r#type) } - fn expected_type(&self, _context: &Map) -> Result { + fn expected_type(&self, _context: &Context) -> Result { Ok(Type::None) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn run(&self, _source: &str, _context: &Map) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { Ok(Value::none()) } } diff --git a/src/abstract_tree/type_specification.rs b/src/abstract_tree/type_specification.rs index 471c7ee..5354069 100644 --- a/src/abstract_tree/type_specification.rs +++ b/src/abstract_tree/type_specification.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Context, Format, SyntaxNode, Type, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] @@ -25,7 +25,7 @@ impl TypeSpecification { } impl AbstractTree for TypeSpecification { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "type_specification", node)?; let type_node = node.child(1).unwrap(); @@ -34,15 +34,15 @@ impl AbstractTree for TypeSpecification { Ok(TypeSpecification { r#type }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { self.r#type.expected_type(context) } - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { self.r#type.run(source, context) } } diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs index 99b1fe5..acbbd57 100644 --- a/src/abstract_tree/value_node.rs +++ b/src/abstract_tree/value_node.rs @@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, BuiltInValue, Expression, Format, Function, FunctionNode, Identifier, List, Map, - SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value, + AbstractTree, BuiltInValue, Context, Expression, Format, Function, FunctionNode, Identifier, + List, Map, SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value, }; #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] @@ -24,7 +24,7 @@ pub enum ValueNode { } impl AbstractTree for ValueNode { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "value", node)?; let child = node.child(0).unwrap(); @@ -182,7 +182,7 @@ impl AbstractTree for ValueNode { Ok(value_node) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { let r#type = match self { ValueNode::Boolean(_) => Type::Boolean, ValueNode::Float(_) => Type::Float, @@ -234,7 +234,7 @@ impl AbstractTree for ValueNode { Ok(r#type) } - fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> { match self { ValueNode::Function(function) => { if let Function::ContextDefined(function_node) = function { @@ -262,7 +262,7 @@ impl AbstractTree for ValueNode { Ok(()) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { let value = match self { ValueNode::Boolean(value_source) => Value::Boolean(value_source.parse().unwrap()), ValueNode::Float(value_source) => { diff --git a/src/abstract_tree/while.rs b/src/abstract_tree/while.rs index d6a82ea..ed2b238 100644 --- a/src/abstract_tree/while.rs +++ b/src/abstract_tree/while.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, - AbstractTree, Block, Expression, Format, Map, SyntaxNode, Type, Value, + AbstractTree, Block, Context, Expression, Format, SyntaxNode, Type, Value, }; /// Abstract representation of a while loop. @@ -15,7 +15,7 @@ pub struct While { } impl AbstractTree for While { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { SyntaxError::expect_syntax_node(source, "while", node)?; let expression_node = node.child(1).unwrap(); @@ -27,16 +27,16 @@ impl AbstractTree for While { Ok(While { expression, block }) } - fn expected_type(&self, context: &Map) -> Result { + fn expected_type(&self, context: &Context) -> Result { self.block.expected_type(context) } - fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> { + fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> { self.expression.validate(_source, context)?; self.block.validate(_source, context) } - fn run(&self, source: &str, context: &Map) -> Result { + fn run(&self, source: &str, context: &Context) -> Result { while self.expression.run(source, context)?.as_boolean()? { self.block.run(source, context)?; } diff --git a/src/abstract_tree/yield.rs b/src/abstract_tree/yield.rs deleted file mode 100644 index be496f1..0000000 --- a/src/abstract_tree/yield.rs +++ /dev/null @@ -1,63 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use crate::{ - error::{RuntimeError, SyntaxError, ValidationError}, - function_expression::FunctionExpression, - AbstractTree, Expression, Format, FunctionCall, Map, SyntaxNode, Type, Value, -}; - -/// Abstract representation of a yield expression. -/// -/// Yield is an alternate means of calling and passing values to a function. -#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] -pub struct Yield { - call: FunctionCall, -} - -impl AbstractTree for Yield { - fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result { - SyntaxError::expect_syntax_node(source, "yield", node)?; - - let input_node = node.child(0).unwrap(); - let input = Expression::from_syntax(input_node, source, context)?; - - let function_node = node.child(2).unwrap(); - let function_expression = FunctionExpression::from_syntax(function_node, source, context)?; - - let mut arguments = Vec::new(); - - arguments.push(input); - - for index in 3..node.child_count() - 1 { - let child = node.child(index).unwrap(); - - if child.is_named() { - let expression = Expression::from_syntax(child, source, context)?; - - arguments.push(expression); - } - } - - let call = FunctionCall::new(function_expression, arguments, node.range().into()); - - Ok(Yield { call }) - } - - fn expected_type(&self, context: &Map) -> Result { - self.call.expected_type(context) - } - - fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> { - self.call.validate(_source, _context) - } - - fn run(&self, source: &str, context: &Map) -> Result { - self.call.run(source, context) - } -} - -impl Format for Yield { - fn format(&self, output: &mut String, indent_level: u8) { - self.call.format(output, indent_level); - } -} diff --git a/src/built_in_functions/fs.rs b/src/built_in_functions/fs.rs index 190d7a2..38a0847 100644 --- a/src/built_in_functions/fs.rs +++ b/src/built_in_functions/fs.rs @@ -3,7 +3,7 @@ use std::fs::read_to_string; use enum_iterator::{all, Sequence}; use serde::{Deserialize, Serialize}; -use crate::{error::RuntimeError, Map, Type, Value}; +use crate::{error::RuntimeError, Context, Type, Value}; use super::Callable; @@ -39,7 +39,7 @@ impl Callable for Fs { &self, arguments: &[Value], _source: &str, - _outer_context: &Map, + _outer_context: &Context, ) -> Result { match self { Fs::ReadFile => { diff --git a/src/built_in_functions/json.rs b/src/built_in_functions/json.rs index c0238d3..9a50aaa 100644 --- a/src/built_in_functions/json.rs +++ b/src/built_in_functions/json.rs @@ -1,7 +1,7 @@ use enum_iterator::Sequence; use serde::{Deserialize, Serialize}; -use crate::{error::RuntimeError, Map, Type, Value}; +use crate::{error::RuntimeError, Context, Type, Value}; use super::Callable; @@ -45,7 +45,7 @@ impl Callable for Json { &self, arguments: &[Value], _source: &str, - _outer_context: &Map, + _outer_context: &Context, ) -> Result { match self { Json::Create => { diff --git a/src/built_in_functions/mod.rs b/src/built_in_functions/mod.rs index 033bc0f..4008b05 100644 --- a/src/built_in_functions/mod.rs +++ b/src/built_in_functions/mod.rs @@ -7,7 +7,7 @@ use std::fmt::{self, Display, Formatter}; use rand::{random, thread_rng, Rng}; use serde::{Deserialize, Serialize}; -use crate::{error::RuntimeError, Format, Map, Type, Value}; +use crate::{error::RuntimeError, Context, Format, Type, Value}; use self::{fs::Fs, json::Json, str::StrFunction}; @@ -19,7 +19,7 @@ pub trait Callable { &self, arguments: &[Value], source: &str, - outer_context: &Map, + outer_context: &Context, ) -> Result; } @@ -87,7 +87,7 @@ impl Callable for BuiltInFunction { &self, arguments: &[Value], _source: &str, - _outer_context: &Map, + _outer_context: &Context, ) -> Result { match self { BuiltInFunction::AssertEqual => { diff --git a/src/built_in_functions/str.rs b/src/built_in_functions/str.rs index 86a8eb8..47184eb 100644 --- a/src/built_in_functions/str.rs +++ b/src/built_in_functions/str.rs @@ -1,7 +1,7 @@ use enum_iterator::Sequence; use serde::{Deserialize, Serialize}; -use crate::{error::RuntimeError, List, Map, Type, Value}; +use crate::{error::RuntimeError, Context, List, Type, Value}; use super::Callable; @@ -202,7 +202,7 @@ impl Callable for StrFunction { &self, arguments: &[Value], _source: &str, - _outer_context: &Map, + _outer_context: &Context, ) -> Result { let value = match self { StrFunction::AsBytes => { diff --git a/src/context.rs b/src/context.rs index 69b15b7..c9929e1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,6 +1,6 @@ use std::{ collections::HashMap, - sync::{Arc, RwLock, RwLockReadGuard}, + sync::{Arc, RwLock}, }; use crate::{error::rw_lock_error::RwLockError, Type, Value}; @@ -30,7 +30,7 @@ impl Context { pub fn inherit_from(other: &Context) -> Result { let mut new_variables = HashMap::new(); - for (identifier, value_data) in other.variables()?.iter() { + for (identifier, value_data) in other.inner.read()?.iter() { new_variables.insert(identifier.clone(), value_data.clone()); } @@ -39,14 +39,10 @@ impl Context { }) } - pub fn variables(&self) -> Result>, RwLockError> { - Ok(self.inner.read()?) - } - - pub fn get_value(&self, key: &str) -> Result, RwLockError> { + pub fn get_value(&self, key: &str) -> Result, RwLockError> { if let Some(value_data) = self.inner.read()?.get(key) { if let ValueData::Value { inner, .. } = value_data { - Ok(Some(inner)) + Ok(Some(inner.clone())) } else { Ok(None) } diff --git a/src/interpret.rs b/src/interpret.rs index 8a7ad2f..185deab 100644 --- a/src/interpret.rs +++ b/src/interpret.rs @@ -38,7 +38,7 @@ use tree_sitter::{Node as SyntaxNode, Parser, Tree as SyntaxTree, TreeCursor}; use crate::{ - error::SyntaxError, language, AbstractTree, Error, Format, Map, Root, SourcePosition, Value, + error::SyntaxError, language, AbstractTree, Context, Error, Format, Root, SourcePosition, Value, }; /// Interpret the given source code. Returns the value of last statement or the @@ -46,7 +46,7 @@ use crate::{ /// /// See the [module-level docs][self] for more info. pub fn interpret(source: &str) -> Result { - interpret_with_context(source, Map::new()) + interpret_with_context(source, Context::new()) } /// Interpret the given source code with the given context. @@ -57,7 +57,7 @@ pub fn interpret(source: &str) -> Result { /// maps. /// /// See the [module-level docs][self] for more info. -pub fn interpret_with_context(source: &str, context: Map) -> Result { +pub fn interpret_with_context(source: &str, context: Context) -> Result { let mut interpreter = Interpreter::new(context); let value = interpreter.run(source)?; @@ -71,12 +71,12 @@ pub fn interpret_with_context(source: &str, context: Map) -> Result Self { + pub fn new(context: Context) -> Self { let mut parser = Parser::new(); parser @@ -176,6 +176,6 @@ impl Interpreter { impl Default for Interpreter { fn default() -> Self { - Interpreter::new(Map::new()) + Interpreter::new(Context::new()) } } diff --git a/src/lib.rs b/src/lib.rs index fcac506..66976b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,8 @@ //! You can use this library externally by calling either of the "interpret" //! functions or by constructing your own Interpreter. pub use crate::{ - abstract_tree::*, built_in_functions::BuiltInFunction, error::Error, interpret::*, value::*, + abstract_tree::*, built_in_functions::BuiltInFunction, context::Context, error::Error, + interpret::*, value::*, }; pub use tree_sitter::Node as SyntaxNode; diff --git a/src/value/function.rs b/src/value/function.rs index 9690db7..050bf48 100644 --- a/src/value/function.rs +++ b/src/value/function.rs @@ -3,8 +3,8 @@ use std::fmt::{self, Display, Formatter}; use serde::{Deserialize, Serialize}; use crate::{ - built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Format, FunctionNode, Map, - Type, Value, + built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format, + FunctionNode, Type, Value, }; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -18,7 +18,7 @@ impl Function { &self, arguments: &[Value], source: &str, - outer_context: &Map, + outer_context: &Context, ) -> Result { match self { Function::BuiltIn(built_in_function) => {