Continue implementing context
This commit is contained in:
parent
ddd5912248
commit
d997bbd08a
@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, AssignmentOperator, Format, Identifier, Map, SourcePosition, Statement,
|
AbstractTree, AssignmentOperator, Format, Identifier, SourcePosition, Statement, SyntaxNode,
|
||||||
SyntaxNode, Type, TypeSpecification, Value,
|
Type, TypeSpecification, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Variable assignment, including add-assign and subtract-assign operations.
|
/// Variable assignment, including add-assign and subtract-assign operations.
|
||||||
@ -130,13 +130,13 @@ impl AbstractTree for Assignment {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let key = self.identifier.inner();
|
let key = self.identifier.inner();
|
||||||
let value = self.statement.run(source, context)?;
|
let value = self.statement.run(source, context)?;
|
||||||
|
|
||||||
let new_value = match self.operator {
|
let new_value = match self.operator {
|
||||||
AssignmentOperator::PlusEqual => {
|
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 += value;
|
||||||
previous_value
|
previous_value
|
||||||
} else {
|
} else {
|
||||||
@ -144,7 +144,7 @@ impl AbstractTree for Assignment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssignmentOperator::MinusEqual => {
|
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 -= value;
|
||||||
previous_value
|
previous_value
|
||||||
} else {
|
} else {
|
||||||
@ -154,12 +154,12 @@ impl AbstractTree for Assignment {
|
|||||||
AssignmentOperator::Equal => value,
|
AssignmentOperator::Equal => value,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.set(key.clone(), new_value)?;
|
context.set_value(key.clone(), new_value)?;
|
||||||
|
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Format, Map, SyntaxNode, Type, Value,
|
AbstractTree, Context, Format, SyntaxNode, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Operators that be used in an assignment statement.
|
/// Operators that be used in an assignment statement.
|
||||||
@ -17,7 +17,7 @@ impl AbstractTree for AssignmentOperator {
|
|||||||
fn from_syntax(
|
fn from_syntax(
|
||||||
node: SyntaxNode,
|
node: SyntaxNode,
|
||||||
source: &str,
|
source: &str,
|
||||||
_context: &crate::Map,
|
_context: &Context,
|
||||||
) -> Result<Self, SyntaxError> {
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "assignment_operator", node)?;
|
SyntaxError::expect_syntax_node(source, "assignment_operator", node)?;
|
||||||
|
|
||||||
@ -39,15 +39,15 @@ impl AbstractTree for AssignmentOperator {
|
|||||||
Ok(operator)
|
Ok(operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{rw_lock_error::RwLockError, RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of a block.
|
||||||
@ -20,11 +20,10 @@ use crate::{
|
|||||||
pub struct Block {
|
pub struct Block {
|
||||||
is_async: bool,
|
is_async: bool,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
context: Map,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Block {
|
impl AbstractTree for Block {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "block", node)?;
|
SyntaxError::expect_syntax_node(source, "block", node)?;
|
||||||
|
|
||||||
let first_child = node.child(0).unwrap();
|
let first_child = node.child(0).unwrap();
|
||||||
@ -36,13 +35,12 @@ impl AbstractTree for Block {
|
|||||||
node.child_count() - 2
|
node.child_count() - 2
|
||||||
};
|
};
|
||||||
let mut statements = Vec::with_capacity(statement_count);
|
let mut statements = Vec::with_capacity(statement_count);
|
||||||
let block_context = Map::clone_from(context)?;
|
|
||||||
|
|
||||||
for index in 1..node.child_count() - 1 {
|
for index in 1..node.child_count() - 1 {
|
||||||
let child_node = node.child(index).unwrap();
|
let child_node = node.child(index).unwrap();
|
||||||
|
|
||||||
if child_node.kind() == "statement" {
|
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);
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
@ -51,23 +49,22 @@ impl AbstractTree for Block {
|
|||||||
Ok(Block {
|
Ok(Block {
|
||||||
is_async,
|
is_async,
|
||||||
statements,
|
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 {
|
for statement in &self.statements {
|
||||||
if let Statement::Return(inner_statement) = statement {
|
if let Statement::Return(inner_statement) = statement {
|
||||||
return inner_statement.validate(_source, &self.context);
|
return inner_statement.validate(_source, _context);
|
||||||
} else {
|
} else {
|
||||||
statement.validate(_source, &self.context)?;
|
statement.validate(_source, _context)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
if self.is_async {
|
if self.is_async {
|
||||||
let statements = &self.statements;
|
let statements = &self.statements;
|
||||||
let final_result = RwLock::new(Ok(Value::none()));
|
let final_result = RwLock::new(Ok(Value::none()));
|
||||||
@ -76,7 +73,7 @@ impl AbstractTree for Block {
|
|||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find_map_first(|(index, statement)| {
|
.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_last_statement = index == statements.len() - 1;
|
||||||
let is_return_statement = if let Statement::Return(_) = statement {
|
let is_return_statement = if let Statement::Return(_) = statement {
|
||||||
true
|
true
|
||||||
@ -116,7 +113,7 @@ impl AbstractTree for Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
if let Some(statement) = self.statements.iter().find(|statement| {
|
if let Some(statement) = self.statements.iter().find(|statement| {
|
||||||
if let Statement::Return(_) = statement {
|
if let Statement::Return(_) = statement {
|
||||||
true
|
true
|
||||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
|
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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<Value> = OnceLock::new();
|
static ARGS: OnceLock<Value> = OnceLock::new();
|
||||||
@ -175,7 +175,11 @@ impl BuiltInValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for BuiltInValue {
|
impl AbstractTree for BuiltInValue {
|
||||||
fn from_syntax(node: SyntaxNode, _source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
_source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
let built_in_value = match node.kind() {
|
let built_in_value = match node.kind() {
|
||||||
"args" => BuiltInValue::Args,
|
"args" => BuiltInValue::Args,
|
||||||
"assert_equal" => BuiltInValue::AssertEqual,
|
"assert_equal" => BuiltInValue::AssertEqual,
|
||||||
@ -191,15 +195,15 @@ impl AbstractTree for BuiltInValue {
|
|||||||
Ok(built_in_value)
|
Ok(built_in_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(self.r#type())
|
Ok(self.r#type())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
Ok(self.get().clone())
|
Ok(self.get().clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use std::process;
|
use std::process;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tree_sitter::Node as SyntaxNode;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Format, Map, Type, Value,
|
AbstractTree, Context, Format, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An external program invokation.
|
/// An external program invokation.
|
||||||
@ -16,9 +17,9 @@ pub struct Command {
|
|||||||
|
|
||||||
impl AbstractTree for Command {
|
impl AbstractTree for Command {
|
||||||
fn from_syntax(
|
fn from_syntax(
|
||||||
node: tree_sitter::Node,
|
node: SyntaxNode,
|
||||||
source: &str,
|
source: &str,
|
||||||
_context: &crate::Map,
|
_context: &Context,
|
||||||
) -> Result<Self, SyntaxError> {
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "command", node)?;
|
SyntaxError::expect_syntax_node(source, "command", node)?;
|
||||||
|
|
||||||
@ -47,15 +48,15 @@ impl AbstractTree for Command {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::String)
|
Ok(Type::String)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let output = process::Command::new(&self.command_text)
|
let output = process::Command::new(&self.command_text)
|
||||||
.args(&self.command_arguments)
|
.args(&self.command_arguments)
|
||||||
.spawn()?
|
.spawn()?
|
||||||
|
@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
value_node::ValueNode,
|
value_node::ValueNode,
|
||||||
AbstractTree, Command, Format, FunctionCall, Identifier, Index, Logic, Map, Math, New,
|
AbstractTree, Command, Context, Format, FunctionCall, Identifier, Index, Logic, Math, New,
|
||||||
SyntaxNode, Type, Value, Yield,
|
SyntaxNode, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Abstract representation of an expression statement.
|
/// Abstract representation of an expression statement.
|
||||||
@ -20,13 +20,16 @@ pub enum Expression {
|
|||||||
Math(Box<Math>),
|
Math(Box<Math>),
|
||||||
Logic(Box<Logic>),
|
Logic(Box<Logic>),
|
||||||
FunctionCall(Box<FunctionCall>),
|
FunctionCall(Box<FunctionCall>),
|
||||||
Yield(Box<Yield>),
|
|
||||||
New(New),
|
New(New),
|
||||||
Command(Command),
|
Command(Command),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Expression {
|
impl AbstractTree for Expression {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "expression", node)?;
|
SyntaxError::expect_syntax_node(source, "expression", node)?;
|
||||||
|
|
||||||
let child = if node.child(0).unwrap().is_named() {
|
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(
|
"function_call" => Expression::FunctionCall(Box::new(FunctionCall::from_syntax(
|
||||||
child, source, _context,
|
child, source, _context,
|
||||||
)?)),
|
)?)),
|
||||||
"yield" => Expression::Yield(Box::new(Yield::from_syntax(child, source, _context)?)),
|
|
||||||
"new" => Expression::New(New::from_syntax(child, source, _context)?),
|
"new" => Expression::New(New::from_syntax(child, source, _context)?),
|
||||||
"command" => Expression::Command(Command::from_syntax(child, source, _context)?),
|
"command" => Expression::Command(Command::from_syntax(child, source, _context)?),
|
||||||
_ => {
|
_ => {
|
||||||
return Err(SyntaxError::UnexpectedSyntaxNode {
|
return Err(SyntaxError::UnexpectedSyntaxNode {
|
||||||
expected:
|
expected:
|
||||||
"value, identifier, index, math, logic, function call, new, context or ->"
|
"value, identifier, index, math, logic, function call, new or command"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
actual: child.kind().to_string(),
|
actual: child.kind().to_string(),
|
||||||
location: child.start_position(),
|
location: child.start_position(),
|
||||||
@ -64,7 +66,7 @@ impl AbstractTree for Expression {
|
|||||||
Ok(expression)
|
Ok(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
Expression::Value(value_node) => value_node.expected_type(_context),
|
Expression::Value(value_node) => value_node.expected_type(_context),
|
||||||
Expression::Identifier(identifier) => identifier.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::Logic(logic) => logic.expected_type(_context),
|
||||||
Expression::FunctionCall(function_call) => function_call.expected_type(_context),
|
Expression::FunctionCall(function_call) => function_call.expected_type(_context),
|
||||||
Expression::Index(index) => index.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::New(new) => new.expected_type(_context),
|
||||||
Expression::Command(command) => command.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 {
|
match self {
|
||||||
Expression::Value(value_node) => value_node.validate(_source, _context),
|
Expression::Value(value_node) => value_node.validate(_source, _context),
|
||||||
Expression::Identifier(identifier) => identifier.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::Logic(logic) => logic.validate(_source, _context),
|
||||||
Expression::FunctionCall(function_call) => function_call.validate(_source, _context),
|
Expression::FunctionCall(function_call) => function_call.validate(_source, _context),
|
||||||
Expression::Index(index) => index.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::New(new) => new.validate(_source, _context),
|
||||||
Expression::Command(command) => command.validate(_source, _context),
|
Expression::Command(command) => command.validate(_source, _context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Expression::Value(value_node) => value_node.run(_source, _context),
|
Expression::Value(value_node) => value_node.run(_source, _context),
|
||||||
Expression::Identifier(identifier) => identifier.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::Logic(logic) => logic.run(_source, _context),
|
||||||
Expression::FunctionCall(function_call) => function_call.run(_source, _context),
|
Expression::FunctionCall(function_call) => function_call.run(_source, _context),
|
||||||
Expression::Index(index) => index.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::New(new) => new.run(_source, _context),
|
||||||
Expression::Command(command) => command.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::Logic(logic) => logic.format(_output, _indent_level),
|
||||||
Expression::FunctionCall(function_call) => function_call.format(_output, _indent_level),
|
Expression::FunctionCall(function_call) => function_call.format(_output, _indent_level),
|
||||||
Expression::Index(index) => index.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::New(new) => new.format(_output, _indent_level),
|
||||||
Expression::Command(command) => command.format(_output, _indent_level),
|
Expression::Command(command) => command.format(_output, _indent_level),
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Block, Expression, Format, Identifier, Map, SourcePosition, SyntaxNode, Type,
|
AbstractTree, Block, Context, Expression, Format, Identifier, SourcePosition, SyntaxNode, Type,
|
||||||
Value,
|
Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ pub struct For {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for For {
|
impl AbstractTree for For {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "for", node)?;
|
SyntaxError::expect_syntax_node(source, "for", node)?;
|
||||||
|
|
||||||
let for_node = node.child(0).unwrap();
|
let for_node = node.child(0).unwrap();
|
||||||
@ -53,11 +53,11 @@ impl AbstractTree for For {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
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 collection_type = self.collection.expected_type(context)?;
|
||||||
let item_type = if let Type::List(item_type) = collection_type {
|
let item_type = if let Type::List(item_type) = collection_type {
|
||||||
item_type.as_ref().clone()
|
item_type.as_ref().clone()
|
||||||
@ -76,24 +76,24 @@ impl AbstractTree for For {
|
|||||||
self.block.validate(_source, context)
|
self.block.validate(_source, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let expression_run = self.collection.run(source, context)?;
|
let expression_run = self.collection.run(source, context)?;
|
||||||
let key = self.item_id.inner();
|
let key = self.item_id.inner();
|
||||||
|
|
||||||
if let Value::Range(range) = expression_run {
|
if let Value::Range(range) = expression_run {
|
||||||
if self.is_async {
|
if self.is_async {
|
||||||
range.into_par_iter().try_for_each(|integer| {
|
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| ())
|
self.block.run(source, &iter_context).map(|_value| ())
|
||||||
})?;
|
})?;
|
||||||
} else {
|
} else {
|
||||||
let loop_context = Map::clone_from(context)?;
|
let loop_context = Context::inherit_from(context)?;
|
||||||
|
|
||||||
for i in range {
|
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)?;
|
self.block.run(source, &loop_context)?;
|
||||||
}
|
}
|
||||||
@ -106,17 +106,17 @@ impl AbstractTree for For {
|
|||||||
|
|
||||||
if self.is_async {
|
if self.is_async {
|
||||||
values.par_iter().try_for_each(|value| {
|
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| ())
|
self.block.run(source, &iter_context).map(|_value| ())
|
||||||
})?;
|
})?;
|
||||||
} else {
|
} else {
|
||||||
let loop_context = Map::clone_from(context)?;
|
let loop_context = Context::inherit_from(context)?;
|
||||||
|
|
||||||
for value in values.iter() {
|
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)?;
|
self.block.run(source, &loop_context)?;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Expression, Format, FunctionExpression, Map, SourcePosition, SyntaxNode, Type,
|
AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode,
|
||||||
Value,
|
Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A function being invoked and the arguments it is being passed.
|
/// A function being invoked and the arguments it is being passed.
|
||||||
@ -30,7 +30,7 @@ impl FunctionCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for FunctionCall {
|
impl AbstractTree for FunctionCall {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "function_call", node)?;
|
SyntaxError::expect_syntax_node(source, "function_call", node)?;
|
||||||
|
|
||||||
let function_node = node.child(0).unwrap();
|
let function_node = node.child(0).unwrap();
|
||||||
@ -55,7 +55,7 @@ impl AbstractTree for FunctionCall {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match &self.function_expression {
|
match &self.function_expression {
|
||||||
FunctionExpression::Identifier(identifier) => {
|
FunctionExpression::Identifier(identifier) => {
|
||||||
let identifier_type = identifier.expected_type(context)?;
|
let identifier_type = identifier.expected_type(context)?;
|
||||||
@ -81,11 +81,10 @@ impl AbstractTree for FunctionCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FunctionExpression::Index(index) => index.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> {
|
||||||
let function_expression_type = self.function_expression.expected_type(context)?;
|
let function_expression_type = self.function_expression.expected_type(context)?;
|
||||||
|
|
||||||
let parameter_types = match function_expression_type {
|
let parameter_types = match function_expression_type {
|
||||||
@ -126,13 +125,12 @@ impl AbstractTree for FunctionCall {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let value = match &self.function_expression {
|
let value = match &self.function_expression {
|
||||||
FunctionExpression::Identifier(identifier) => {
|
FunctionExpression::Identifier(identifier) => {
|
||||||
let key = identifier.inner();
|
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()
|
value.clone()
|
||||||
} else {
|
} else {
|
||||||
return Err(RuntimeError::VariableIdentifierNotFound(
|
return Err(RuntimeError::VariableIdentifierNotFound(
|
||||||
@ -145,7 +143,6 @@ impl AbstractTree for FunctionCall {
|
|||||||
}
|
}
|
||||||
FunctionExpression::Value(value_node) => value_node.run(source, context)?,
|
FunctionExpression::Value(value_node) => value_node.run(source, context)?,
|
||||||
FunctionExpression::Index(index) => index.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());
|
let mut arguments = Vec::with_capacity(self.arguments.len());
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Format, FunctionCall, Identifier, Index, Map, SyntaxNode, Type, Value, ValueNode,
|
AbstractTree, Context, Format, FunctionCall, Identifier, Index, SyntaxNode, Type, Value,
|
||||||
Yield,
|
ValueNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -12,11 +12,10 @@ pub enum FunctionExpression {
|
|||||||
FunctionCall(Box<FunctionCall>),
|
FunctionCall(Box<FunctionCall>),
|
||||||
Value(ValueNode),
|
Value(ValueNode),
|
||||||
Index(Index),
|
Index(Index),
|
||||||
Yield(Box<Yield>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for FunctionExpression {
|
impl AbstractTree for FunctionExpression {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "function_expression", node)?;
|
SyntaxError::expect_syntax_node(source, "function_expression", node)?;
|
||||||
|
|
||||||
let first_child = node.child(0).unwrap();
|
let first_child = node.child(0).unwrap();
|
||||||
@ -36,12 +35,9 @@ impl AbstractTree for FunctionExpression {
|
|||||||
)),
|
)),
|
||||||
"value" => FunctionExpression::Value(ValueNode::from_syntax(child, source, context)?),
|
"value" => FunctionExpression::Value(ValueNode::from_syntax(child, source, context)?),
|
||||||
"index" => FunctionExpression::Index(Index::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 {
|
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(),
|
actual: child.kind().to_string(),
|
||||||
location: child.start_position(),
|
location: child.start_position(),
|
||||||
relevant_source: source[child.byte_range()].to_string(),
|
relevant_source: source[child.byte_range()].to_string(),
|
||||||
@ -52,17 +48,16 @@ impl AbstractTree for FunctionExpression {
|
|||||||
Ok(function_expression)
|
Ok(function_expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
FunctionExpression::Identifier(identifier) => identifier.expected_type(context),
|
FunctionExpression::Identifier(identifier) => identifier.expected_type(context),
|
||||||
FunctionExpression::FunctionCall(function_call) => function_call.expected_type(context),
|
FunctionExpression::FunctionCall(function_call) => function_call.expected_type(context),
|
||||||
FunctionExpression::Value(value_node) => value_node.expected_type(context),
|
FunctionExpression::Value(value_node) => value_node.expected_type(context),
|
||||||
FunctionExpression::Index(index) => index.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 {
|
match self {
|
||||||
FunctionExpression::Identifier(identifier) => identifier.validate(_source, _context),
|
FunctionExpression::Identifier(identifier) => identifier.validate(_source, _context),
|
||||||
FunctionExpression::FunctionCall(function_call) => {
|
FunctionExpression::FunctionCall(function_call) => {
|
||||||
@ -70,17 +65,15 @@ impl AbstractTree for FunctionExpression {
|
|||||||
}
|
}
|
||||||
FunctionExpression::Value(value_node) => value_node.validate(_source, _context),
|
FunctionExpression::Value(value_node) => value_node.validate(_source, _context),
|
||||||
FunctionExpression::Index(index) => index.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<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
FunctionExpression::Identifier(identifier) => identifier.run(source, context),
|
FunctionExpression::Identifier(identifier) => identifier.run(source, context),
|
||||||
FunctionExpression::FunctionCall(function_call) => function_call.run(source, context),
|
FunctionExpression::FunctionCall(function_call) => function_call.run(source, context),
|
||||||
FunctionExpression::Value(value_node) => value_node.run(source, context),
|
FunctionExpression::Value(value_node) => value_node.run(source, context),
|
||||||
FunctionExpression::Index(index) => index.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)
|
function_call.format(output, indent_level)
|
||||||
}
|
}
|
||||||
FunctionExpression::Index(index) => index.format(output, indent_level),
|
FunctionExpression::Index(index) => index.format(output, indent_level),
|
||||||
FunctionExpression::Yield(r#yield) => r#yield.format(output, indent_level),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Block, Format, Function, Identifier, Map, SourcePosition, SyntaxNode, Type,
|
AbstractTree, Block, Context, Format, Function, Identifier, SourcePosition, SyntaxNode, Type,
|
||||||
TypeSpecification, Value,
|
TypeSpecification, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,21 +61,15 @@ impl FunctionNode {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
source: &str,
|
source: &str,
|
||||||
outer_context: &Map,
|
outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
let function_context = Map::new();
|
let function_context = Context::inherit_from(outer_context)?;
|
||||||
let parameter_argument_pairs = self.parameters.iter().zip(arguments.iter());
|
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 {
|
for (identifier, value) in parameter_argument_pairs {
|
||||||
let key = identifier.inner().clone();
|
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)?;
|
let return_value = self.body.run(source, &function_context)?;
|
||||||
@ -88,7 +82,7 @@ impl AbstractTree for FunctionNode {
|
|||||||
fn from_syntax(
|
fn from_syntax(
|
||||||
node: SyntaxNode,
|
node: SyntaxNode,
|
||||||
source: &str,
|
source: &str,
|
||||||
outer_context: &Map,
|
outer_context: &Context,
|
||||||
) -> Result<Self, SyntaxError> {
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "function", node)?;
|
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_node = node.child(child_count - 2).unwrap();
|
||||||
let return_type = TypeSpecification::from_syntax(return_type_node, source, outer_context)?;
|
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()) {
|
for (parameter, parameter_type) in parameters.iter().zip(parameter_types.iter()) {
|
||||||
function_context.set_type(parameter.inner().clone(), parameter_type.clone())?;
|
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_node = node.child(child_count - 1).unwrap();
|
||||||
let body = Block::from_syntax(body_node, source, &function_context)?;
|
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<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(self.r#type().clone())
|
Ok(self.r#type().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, source: &str, context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
|
||||||
let function_context = Map::new();
|
let function_context = Context::inherit_from(context)?;
|
||||||
|
|
||||||
for (key, (_value, r#type)) in context.variables()?.iter() {
|
|
||||||
if r#type.is_function() {
|
|
||||||
function_context.set_type(key.clone(), r#type.clone())?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Type::Function {
|
if let Type::Function {
|
||||||
parameter_types,
|
parameter_types,
|
||||||
@ -185,7 +167,7 @@ impl AbstractTree for FunctionNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let self_as_value = Value::Function(Function::ContextDefined(self.clone()));
|
let self_as_value = Value::Function(Function::ContextDefined(self.clone()));
|
||||||
|
|
||||||
Ok(self_as_value)
|
Ok(self_as_value)
|
||||||
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// A string by which a variable is known to a context.
|
||||||
@ -29,7 +29,11 @@ impl Identifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Identifier {
|
impl AbstractTree for Identifier {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "identifier", node)?;
|
SyntaxError::expect_syntax_node(source, "identifier", node)?;
|
||||||
|
|
||||||
let text = &source[node.byte_range()];
|
let text = &source[node.byte_range()];
|
||||||
@ -39,20 +43,20 @@ impl AbstractTree for Identifier {
|
|||||||
Ok(Identifier(text.to_string()))
|
Ok(Identifier(text.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
if let Some((_value, r#type)) = context.variables()?.get(&self.0) {
|
if let Some(r#type) = context.get_type(&self.0)? {
|
||||||
Ok(r#type.clone())
|
Ok(r#type)
|
||||||
} else {
|
} else {
|
||||||
Err(ValidationError::VariableIdentifierNotFound(self.clone()))
|
Err(ValidationError::VariableIdentifierNotFound(self.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
if let Some((value, _)) = context.variables()?.get(&self.0) {
|
if let Some(value) = context.get_value(&self.0)? {
|
||||||
Ok(value.clone())
|
Ok(value.clone())
|
||||||
} else {
|
} else {
|
||||||
Err(RuntimeError::VariableIdentifierNotFound(self.0.clone()))
|
Err(RuntimeError::VariableIdentifierNotFound(self.0.clone()))
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -16,7 +16,7 @@ pub struct IfElse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for IfElse {
|
impl AbstractTree for IfElse {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
let if_expression_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(if_expression_node, source, context)?;
|
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<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
self.if_block.expected_type(context)
|
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_expression.validate(_source, context)?;
|
||||||
self.if_block.validate(_source, context)?;
|
self.if_block.validate(_source, context)?;
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ impl AbstractTree for IfElse {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
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 {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of an index expression.
|
||||||
@ -17,7 +17,7 @@ pub struct Index {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Index {
|
impl AbstractTree for Index {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "index", node)?;
|
SyntaxError::expect_syntax_node(source, "index", node)?;
|
||||||
|
|
||||||
let collection_node = node.child(0).unwrap();
|
let collection_node = node.child(0).unwrap();
|
||||||
@ -45,7 +45,7 @@ impl AbstractTree for Index {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self.collection.expected_type(context)? {
|
match self.collection.expected_type(context)? {
|
||||||
Type::List(item_type) => Ok(*item_type.clone()),
|
Type::List(item_type) => Ok(*item_type.clone()),
|
||||||
Type::Map(_) => Ok(Type::Any),
|
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.collection.validate(_source, _context)?;
|
||||||
self.index.validate(_source, _context)?;
|
self.index.validate(_source, _context)?;
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ impl AbstractTree for Index {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let value = self.collection.run(source, context)?;
|
let value = self.collection.run(source, context)?;
|
||||||
|
|
||||||
match value {
|
match value {
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, AssignmentOperator, Format, Index, IndexExpression, Map, Statement, SyntaxNode,
|
AbstractTree, AssignmentOperator, Context, Format, Index, IndexExpression, Statement,
|
||||||
Type, Value,
|
SyntaxNode, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -14,7 +14,7 @@ pub struct IndexAssignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for IndexAssignment {
|
impl AbstractTree for IndexAssignment {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "index_assignment", node)?;
|
SyntaxError::expect_syntax_node(source, "index_assignment", node)?;
|
||||||
|
|
||||||
let index_node = node.child(0).unwrap();
|
let index_node = node.child(0).unwrap();
|
||||||
@ -33,18 +33,17 @@ impl AbstractTree for IndexAssignment {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
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.index.validate(_source, _context)?;
|
||||||
self.statement.validate(_source, _context)
|
self.statement.validate(_source, _context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let index_collection = self.index.collection.run(source, context)?;
|
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 {
|
let index_key = if let IndexExpression::Identifier(identifier) = &self.index.index {
|
||||||
identifier.inner()
|
identifier.inner()
|
||||||
} else {
|
} else {
|
||||||
@ -57,9 +56,7 @@ impl AbstractTree for IndexAssignment {
|
|||||||
|
|
||||||
let new_value = match self.operator {
|
let new_value = match self.operator {
|
||||||
AssignmentOperator::PlusEqual => {
|
AssignmentOperator::PlusEqual => {
|
||||||
if let Some((mut previous_value, _)) =
|
if let Some(mut previous_value) = context.get_value(index_key)? {
|
||||||
index_context.variables()?.get(index_key).cloned()
|
|
||||||
{
|
|
||||||
previous_value += value;
|
previous_value += value;
|
||||||
previous_value
|
previous_value
|
||||||
} else {
|
} else {
|
||||||
@ -67,9 +64,7 @@ impl AbstractTree for IndexAssignment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssignmentOperator::MinusEqual => {
|
AssignmentOperator::MinusEqual => {
|
||||||
if let Some((mut previous_value, _)) =
|
if let Some(mut previous_value) = context.get_value(index_key)? {
|
||||||
index_context.variables()?.get(index_key).cloned()
|
|
||||||
{
|
|
||||||
previous_value -= value;
|
previous_value -= value;
|
||||||
previous_value
|
previous_value
|
||||||
} else {
|
} else {
|
||||||
@ -79,7 +74,7 @@ impl AbstractTree for IndexAssignment {
|
|||||||
AssignmentOperator::Equal => value,
|
AssignmentOperator::Equal => value,
|
||||||
};
|
};
|
||||||
|
|
||||||
index_context.set(index_key.clone(), new_value)?;
|
context.set_value(index_key.clone(), new_value)?;
|
||||||
|
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
value_node::ValueNode,
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -15,7 +15,7 @@ pub enum IndexExpression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for IndexExpression {
|
impl AbstractTree for IndexExpression {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "index_expression", node)?;
|
SyntaxError::expect_syntax_node(source, "index_expression", node)?;
|
||||||
|
|
||||||
let first_child = node.child(0).unwrap();
|
let first_child = node.child(0).unwrap();
|
||||||
@ -49,7 +49,7 @@ impl AbstractTree for IndexExpression {
|
|||||||
Ok(abstract_node)
|
Ok(abstract_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
IndexExpression::Value(value_node) => value_node.expected_type(context),
|
IndexExpression::Value(value_node) => value_node.expected_type(context),
|
||||||
IndexExpression::Identifier(identifier) => identifier.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 {
|
match self {
|
||||||
IndexExpression::Value(value_node) => value_node.validate(_source, _context),
|
IndexExpression::Value(value_node) => value_node.validate(_source, _context),
|
||||||
IndexExpression::Identifier(identifier) => identifier.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<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
IndexExpression::Value(value_node) => value_node.run(source, context),
|
IndexExpression::Value(value_node) => value_node.run(source, context),
|
||||||
IndexExpression::Identifier(identifier) => identifier.run(source, context),
|
IndexExpression::Identifier(identifier) => identifier.run(source, context),
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of a logic expression.
|
||||||
@ -14,7 +14,7 @@ pub struct Logic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Logic {
|
impl AbstractTree for Logic {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "logic", node)?;
|
SyntaxError::expect_syntax_node(source, "logic", node)?;
|
||||||
|
|
||||||
let first_node = node.child(0).unwrap();
|
let first_node = node.child(0).unwrap();
|
||||||
@ -40,16 +40,16 @@ impl AbstractTree for Logic {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::Boolean)
|
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.left.validate(_source, _context)?;
|
||||||
self.right.validate(_source, _context)
|
self.right.validate(_source, _context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let left = self.left.run(source, context)?;
|
let left = self.left.run(source, context)?;
|
||||||
let right = self.right.run(source, context)?;
|
let right = self.right.run(source, context)?;
|
||||||
let result = match self.operator {
|
let result = match self.operator {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -18,7 +18,11 @@ pub enum LogicOperator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for LogicOperator {
|
impl AbstractTree for LogicOperator {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "logic_operator", node)?;
|
SyntaxError::expect_syntax_node(source, "logic_operator", node)?;
|
||||||
|
|
||||||
let operator_node = node.child(0).unwrap();
|
let operator_node = node.child(0).unwrap();
|
||||||
@ -44,15 +48,15 @@ impl AbstractTree for LogicOperator {
|
|||||||
Ok(operator)
|
Ok(operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of a match statement.
|
||||||
@ -18,7 +18,7 @@ pub struct Match {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Match {
|
impl AbstractTree for Match {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "match", node)?;
|
SyntaxError::expect_syntax_node(source, "match", node)?;
|
||||||
|
|
||||||
let matcher_node = node.child(1).unwrap();
|
let matcher_node = node.child(1).unwrap();
|
||||||
@ -59,13 +59,13 @@ impl AbstractTree for Match {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
let (_, first_statement) = self.options.first().unwrap();
|
let (_, first_statement) = self.options.first().unwrap();
|
||||||
|
|
||||||
first_statement.expected_type(context)
|
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)?;
|
self.matcher.validate(_source, _context)?;
|
||||||
|
|
||||||
for (expression, statement) in &self.options {
|
for (expression, statement) in &self.options {
|
||||||
@ -80,7 +80,7 @@ impl AbstractTree for Match {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let matcher_value = self.matcher.run(source, context)?;
|
let matcher_value = self.matcher.run(source, context)?;
|
||||||
|
|
||||||
for (expression, statement) in &self.options {
|
for (expression, statement) in &self.options {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of a math operation.
|
||||||
@ -17,7 +17,7 @@ pub struct Math {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Math {
|
impl AbstractTree for Math {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "math", node)?;
|
SyntaxError::expect_syntax_node(source, "math", node)?;
|
||||||
|
|
||||||
let left_node = node.child(0).unwrap();
|
let left_node = node.child(0).unwrap();
|
||||||
@ -36,16 +36,16 @@ impl AbstractTree for Math {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
self.left.expected_type(context)
|
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.left.validate(_source, _context)?;
|
||||||
self.right.validate(_source, _context)
|
self.right.validate(_source, _context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let left = self.left.run(source, context)?;
|
let left = self.left.run(source, context)?;
|
||||||
let right = self.right.run(source, context)?;
|
let right = self.right.run(source, context)?;
|
||||||
let value = match self.operator {
|
let value = match self.operator {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -15,7 +15,11 @@ pub enum MathOperator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for MathOperator {
|
impl AbstractTree for MathOperator {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
let operator_node = node.child(0).unwrap();
|
let operator_node = node.child(0).unwrap();
|
||||||
let operator = match operator_node.kind() {
|
let operator = match operator_node.kind() {
|
||||||
"+" => MathOperator::Add,
|
"+" => MathOperator::Add,
|
||||||
@ -36,15 +40,15 @@ impl AbstractTree for MathOperator {
|
|||||||
Ok(operator)
|
Ok(operator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,13 @@ pub mod r#type;
|
|||||||
pub mod type_specification;
|
pub mod type_specification;
|
||||||
pub mod value_node;
|
pub mod value_node;
|
||||||
pub mod r#while;
|
pub mod r#while;
|
||||||
pub mod r#yield;
|
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, expression::*,
|
assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, expression::*,
|
||||||
function_call::*, function_expression::*, function_node::*, identifier::*, if_else::*,
|
function_call::*, function_expression::*, function_node::*, identifier::*, if_else::*,
|
||||||
index::*, index_assignment::IndexAssignment, index_expression::*, logic::*, logic_operator::*,
|
index::*, index_assignment::IndexAssignment, index_expression::*, logic::*, logic_operator::*,
|
||||||
math::*, math_operator::*, new::*, r#for::*, r#match::*, r#type::*, r#while::*, r#yield::*,
|
math::*, math_operator::*, new::*, r#for::*, r#match::*, r#type::*, r#while::*, statement::*,
|
||||||
statement::*, type_specification::*, value_node::*,
|
type_specification::*, value_node::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -47,7 +46,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
Map, SyntaxNode, Value,
|
SyntaxNode, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
|
@ -3,7 +3,7 @@ use tree_sitter::Node;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
@ -13,7 +13,7 @@ pub struct New {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for New {
|
impl AbstractTree for New {
|
||||||
fn from_syntax(node: Node, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: Node, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
let identifier_node = node.child(1).unwrap();
|
let identifier_node = node.child(1).unwrap();
|
||||||
let identifier = Identifier::from_syntax(identifier_node, source, context)?;
|
let identifier = Identifier::from_syntax(identifier_node, source, context)?;
|
||||||
|
|
||||||
@ -25,15 +25,15 @@ impl AbstractTree for New {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Assignment, Block, Expression, For, Format, IfElse, IndexAssignment, Map, Match,
|
AbstractTree, Assignment, Block, Context, Expression, For, Format, IfElse, IndexAssignment,
|
||||||
SyntaxNode, Type, Value, While,
|
Match, SyntaxNode, Type, Value, While,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Abstract representation of a statement.
|
/// Abstract representation of a statement.
|
||||||
@ -21,7 +21,7 @@ pub enum Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Statement {
|
impl AbstractTree for Statement {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "statement", node)?;
|
SyntaxError::expect_syntax_node(source, "statement", node)?;
|
||||||
|
|
||||||
let child = node.child(0).unwrap();
|
let child = node.child(0).unwrap();
|
||||||
@ -66,7 +66,7 @@ impl AbstractTree for Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.expected_type(context),
|
Statement::Assignment(assignment) => assignment.expected_type(context),
|
||||||
Statement::Expression(expression) => expression.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 {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.validate(_source, _context),
|
Statement::Assignment(assignment) => assignment.validate(_source, _context),
|
||||||
Statement::Expression(expression) => expression.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<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Statement::Assignment(assignment) => assignment.run(source, context),
|
Statement::Assignment(assignment) => assignment.run(source, context),
|
||||||
Statement::Expression(expression) => expression.run(source, context),
|
Statement::Expression(expression) => expression.run(source, context),
|
||||||
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -126,7 +126,11 @@ impl Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for Type {
|
impl AbstractTree for Type {
|
||||||
fn from_syntax(node: SyntaxNode, _source: &str, _context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(
|
||||||
|
node: SyntaxNode,
|
||||||
|
_source: &str,
|
||||||
|
_context: &Context,
|
||||||
|
) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(_source, "type", node)?;
|
SyntaxError::expect_syntax_node(_source, "type", node)?;
|
||||||
|
|
||||||
let type_node = node.child(0).unwrap();
|
let type_node = node.child(0).unwrap();
|
||||||
@ -192,15 +196,15 @@ impl AbstractTree for Type {
|
|||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
Ok(Type::None)
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, _source: &str, _context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
Ok(Value::none())
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -25,7 +25,7 @@ impl TypeSpecification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for TypeSpecification {
|
impl AbstractTree for TypeSpecification {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "type_specification", node)?;
|
SyntaxError::expect_syntax_node(source, "type_specification", node)?;
|
||||||
|
|
||||||
let type_node = node.child(1).unwrap();
|
let type_node = node.child(1).unwrap();
|
||||||
@ -34,15 +34,15 @@ impl AbstractTree for TypeSpecification {
|
|||||||
Ok(TypeSpecification { r#type })
|
Ok(TypeSpecification { r#type })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
self.r#type.expected_type(context)
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
self.r#type.run(source, context)
|
self.r#type.run(source, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, BuiltInValue, Expression, Format, Function, FunctionNode, Identifier, List, Map,
|
AbstractTree, BuiltInValue, Context, Expression, Format, Function, FunctionNode, Identifier,
|
||||||
SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value,
|
List, Map, SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
@ -24,7 +24,7 @@ pub enum ValueNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for ValueNode {
|
impl AbstractTree for ValueNode {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "value", node)?;
|
SyntaxError::expect_syntax_node(source, "value", node)?;
|
||||||
|
|
||||||
let child = node.child(0).unwrap();
|
let child = node.child(0).unwrap();
|
||||||
@ -182,7 +182,7 @@ impl AbstractTree for ValueNode {
|
|||||||
Ok(value_node)
|
Ok(value_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
let r#type = match self {
|
let r#type = match self {
|
||||||
ValueNode::Boolean(_) => Type::Boolean,
|
ValueNode::Boolean(_) => Type::Boolean,
|
||||||
ValueNode::Float(_) => Type::Float,
|
ValueNode::Float(_) => Type::Float,
|
||||||
@ -234,7 +234,7 @@ impl AbstractTree for ValueNode {
|
|||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, context: &Map) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
ValueNode::Function(function) => {
|
ValueNode::Function(function) => {
|
||||||
if let Function::ContextDefined(function_node) = function {
|
if let Function::ContextDefined(function_node) = function {
|
||||||
@ -262,7 +262,7 @@ impl AbstractTree for ValueNode {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let value = match self {
|
let value = match self {
|
||||||
ValueNode::Boolean(value_source) => Value::Boolean(value_source.parse().unwrap()),
|
ValueNode::Boolean(value_source) => Value::Boolean(value_source.parse().unwrap()),
|
||||||
ValueNode::Float(value_source) => {
|
ValueNode::Float(value_source) => {
|
||||||
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
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.
|
/// Abstract representation of a while loop.
|
||||||
@ -15,7 +15,7 @@ pub struct While {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for While {
|
impl AbstractTree for While {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Map) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
SyntaxError::expect_syntax_node(source, "while", node)?;
|
SyntaxError::expect_syntax_node(source, "while", node)?;
|
||||||
|
|
||||||
let expression_node = node.child(1).unwrap();
|
let expression_node = node.child(1).unwrap();
|
||||||
@ -27,16 +27,16 @@ impl AbstractTree for While {
|
|||||||
Ok(While { expression, block })
|
Ok(While { expression, block })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Map) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
self.block.expected_type(context)
|
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.expression.validate(_source, context)?;
|
||||||
self.block.validate(_source, context)
|
self.block.validate(_source, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Map) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
while self.expression.run(source, context)?.as_boolean()? {
|
while self.expression.run(source, context)?.as_boolean()? {
|
||||||
self.block.run(source, context)?;
|
self.block.run(source, context)?;
|
||||||
}
|
}
|
||||||
|
@ -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<Self, SyntaxError> {
|
|
||||||
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<Type, ValidationError> {
|
|
||||||
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<Value, RuntimeError> {
|
|
||||||
self.call.run(source, context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Format for Yield {
|
|
||||||
fn format(&self, output: &mut String, indent_level: u8) {
|
|
||||||
self.call.format(output, indent_level);
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,7 @@ use std::fs::read_to_string;
|
|||||||
use enum_iterator::{all, Sequence};
|
use enum_iterator::{all, Sequence};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{error::RuntimeError, Map, Type, Value};
|
use crate::{error::RuntimeError, Context, Type, Value};
|
||||||
|
|
||||||
use super::Callable;
|
use super::Callable;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ impl Callable for Fs {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
_source: &str,
|
_source: &str,
|
||||||
_outer_context: &Map,
|
_outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Fs::ReadFile => {
|
Fs::ReadFile => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use enum_iterator::Sequence;
|
use enum_iterator::Sequence;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{error::RuntimeError, Map, Type, Value};
|
use crate::{error::RuntimeError, Context, Type, Value};
|
||||||
|
|
||||||
use super::Callable;
|
use super::Callable;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ impl Callable for Json {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
_source: &str,
|
_source: &str,
|
||||||
_outer_context: &Map,
|
_outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Json::Create => {
|
Json::Create => {
|
||||||
|
@ -7,7 +7,7 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
use rand::{random, thread_rng, Rng};
|
use rand::{random, thread_rng, Rng};
|
||||||
use serde::{Deserialize, Serialize};
|
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};
|
use self::{fs::Fs, json::Json, str::StrFunction};
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ pub trait Callable {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
source: &str,
|
source: &str,
|
||||||
outer_context: &Map,
|
outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError>;
|
) -> Result<Value, RuntimeError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ impl Callable for BuiltInFunction {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
_source: &str,
|
_source: &str,
|
||||||
_outer_context: &Map,
|
_outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
BuiltInFunction::AssertEqual => {
|
BuiltInFunction::AssertEqual => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use enum_iterator::Sequence;
|
use enum_iterator::Sequence;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{error::RuntimeError, List, Map, Type, Value};
|
use crate::{error::RuntimeError, Context, List, Type, Value};
|
||||||
|
|
||||||
use super::Callable;
|
use super::Callable;
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ impl Callable for StrFunction {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
_source: &str,
|
_source: &str,
|
||||||
_outer_context: &Map,
|
_outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
let value = match self {
|
let value = match self {
|
||||||
StrFunction::AsBytes => {
|
StrFunction::AsBytes => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::rw_lock_error::RwLockError, Type, Value};
|
use crate::{error::rw_lock_error::RwLockError, Type, Value};
|
||||||
@ -30,7 +30,7 @@ impl Context {
|
|||||||
pub fn inherit_from(other: &Context) -> Result<Context, RwLockError> {
|
pub fn inherit_from(other: &Context) -> Result<Context, RwLockError> {
|
||||||
let mut new_variables = HashMap::new();
|
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());
|
new_variables.insert(identifier.clone(), value_data.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,14 +39,10 @@ impl Context {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variables(&self) -> Result<RwLockReadGuard<HashMap<String, ValueData>>, RwLockError> {
|
pub fn get_value(&self, key: &str) -> Result<Option<Value>, RwLockError> {
|
||||||
Ok(self.inner.read()?)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_value(&self, key: &str) -> Result<Option<&Value>, RwLockError> {
|
|
||||||
if let Some(value_data) = self.inner.read()?.get(key) {
|
if let Some(value_data) = self.inner.read()?.get(key) {
|
||||||
if let ValueData::Value { inner, .. } = value_data {
|
if let ValueData::Value { inner, .. } = value_data {
|
||||||
Ok(Some(inner))
|
Ok(Some(inner.clone()))
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
use tree_sitter::{Node as SyntaxNode, Parser, Tree as SyntaxTree, TreeCursor};
|
use tree_sitter::{Node as SyntaxNode, Parser, Tree as SyntaxTree, TreeCursor};
|
||||||
|
|
||||||
use crate::{
|
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
|
/// 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.
|
/// See the [module-level docs][self] for more info.
|
||||||
pub fn interpret(source: &str) -> Result<Value, Error> {
|
pub fn interpret(source: &str) -> Result<Value, Error> {
|
||||||
interpret_with_context(source, Map::new())
|
interpret_with_context(source, Context::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Interpret the given source code with the given context.
|
/// Interpret the given source code with the given context.
|
||||||
@ -57,7 +57,7 @@ pub fn interpret(source: &str) -> Result<Value, Error> {
|
|||||||
/// maps.
|
/// maps.
|
||||||
///
|
///
|
||||||
/// See the [module-level docs][self] for more info.
|
/// See the [module-level docs][self] for more info.
|
||||||
pub fn interpret_with_context(source: &str, context: Map) -> Result<Value, Error> {
|
pub fn interpret_with_context(source: &str, context: Context) -> Result<Value, Error> {
|
||||||
let mut interpreter = Interpreter::new(context);
|
let mut interpreter = Interpreter::new(context);
|
||||||
let value = interpreter.run(source)?;
|
let value = interpreter.run(source)?;
|
||||||
|
|
||||||
@ -71,12 +71,12 @@ pub fn interpret_with_context(source: &str, context: Map) -> Result<Value, Error
|
|||||||
/// process contains the prior steps, meaning that the same code is always used to create the syntax /// tree, abstract tree and final evaluation. This avoids a critical logic error.
|
/// process contains the prior steps, meaning that the same code is always used to create the syntax /// tree, abstract tree and final evaluation. This avoids a critical logic error.
|
||||||
pub struct Interpreter {
|
pub struct Interpreter {
|
||||||
parser: Parser,
|
parser: Parser,
|
||||||
context: Map,
|
context: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpreter {
|
impl Interpreter {
|
||||||
/// Creates a new interpreter with the given variable context.
|
/// Creates a new interpreter with the given variable context.
|
||||||
pub fn new(context: Map) -> Self {
|
pub fn new(context: Context) -> Self {
|
||||||
let mut parser = Parser::new();
|
let mut parser = Parser::new();
|
||||||
|
|
||||||
parser
|
parser
|
||||||
@ -176,6 +176,6 @@ impl Interpreter {
|
|||||||
|
|
||||||
impl Default for Interpreter {
|
impl Default for Interpreter {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Interpreter::new(Map::new())
|
Interpreter::new(Context::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
//! You can use this library externally by calling either of the "interpret"
|
//! You can use this library externally by calling either of the "interpret"
|
||||||
//! functions or by constructing your own Interpreter.
|
//! functions or by constructing your own Interpreter.
|
||||||
pub use crate::{
|
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;
|
pub use tree_sitter::Node as SyntaxNode;
|
||||||
|
@ -3,8 +3,8 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Format, FunctionNode, Map,
|
built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format,
|
||||||
Type, Value,
|
FunctionNode, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
@ -18,7 +18,7 @@ impl Function {
|
|||||||
&self,
|
&self,
|
||||||
arguments: &[Value],
|
arguments: &[Value],
|
||||||
source: &str,
|
source: &str,
|
||||||
outer_context: &Map,
|
outer_context: &Context,
|
||||||
) -> Result<Value, RuntimeError> {
|
) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Function::BuiltIn(built_in_function) => {
|
Function::BuiltIn(built_in_function) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user