Implement new context principles
This commit is contained in:
parent
90c0304af5
commit
f2049225fe
@ -20,6 +20,7 @@ use crate::{
|
||||
pub struct Block {
|
||||
is_async: bool,
|
||||
statements: Vec<Statement>,
|
||||
context: Context,
|
||||
}
|
||||
|
||||
impl AbstractTree for Block {
|
||||
@ -35,12 +36,13 @@ impl AbstractTree for Block {
|
||||
node.child_count() - 2
|
||||
};
|
||||
let mut statements = Vec::with_capacity(statement_count);
|
||||
let block_context = Context::inherit_from(context)?;
|
||||
|
||||
for index in 1..node.child_count() - 1 {
|
||||
let child_node = node.child(index).unwrap();
|
||||
|
||||
if child_node.kind() == "statement" {
|
||||
let statement = Statement::from_syntax(child_node, source, &context)?;
|
||||
let statement = Statement::from_syntax(child_node, source, &block_context)?;
|
||||
|
||||
statements.push(statement);
|
||||
}
|
||||
@ -49,22 +51,23 @@ impl AbstractTree for Block {
|
||||
Ok(Block {
|
||||
is_async,
|
||||
statements,
|
||||
context: block_context,
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||
for statement in &self.statements {
|
||||
if let Statement::Return(inner_statement) = statement {
|
||||
return inner_statement.validate(_source, _context);
|
||||
return inner_statement.validate(_source, &self.context);
|
||||
} else {
|
||||
statement.validate(_source, _context)?;
|
||||
statement.validate(_source, &self.context)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||
fn run(&self, source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||
if self.is_async {
|
||||
let statements = &self.statements;
|
||||
let final_result = RwLock::new(Ok(Value::none()));
|
||||
@ -73,7 +76,7 @@ impl AbstractTree for Block {
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
.find_map_first(|(index, statement)| {
|
||||
let result = statement.run(source, context);
|
||||
let result = statement.run(source, &self.context);
|
||||
let is_last_statement = index == statements.len() - 1;
|
||||
let is_return_statement = if let Statement::Return(_) = statement {
|
||||
true
|
||||
@ -103,17 +106,17 @@ impl AbstractTree for Block {
|
||||
|
||||
for statement in &self.statements {
|
||||
if let Statement::Return(inner_statement) = statement {
|
||||
return inner_statement.run(source, context);
|
||||
return inner_statement.run(source, &self.context);
|
||||
}
|
||||
|
||||
prev_result = Some(statement.run(source, context));
|
||||
prev_result = Some(statement.run(source, &self.context));
|
||||
}
|
||||
|
||||
prev_result.unwrap_or(Ok(Value::none()))
|
||||
}
|
||||
}
|
||||
|
||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||
if let Some(statement) = self.statements.iter().find(|statement| {
|
||||
if let Statement::Return(_) = statement {
|
||||
true
|
||||
@ -121,9 +124,9 @@ impl AbstractTree for Block {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
statement.expected_type(context)
|
||||
statement.expected_type(&self.context)
|
||||
} else if let Some(statement) = self.statements.last() {
|
||||
statement.expected_type(context)
|
||||
statement.expected_type(&self.context)
|
||||
} else {
|
||||
Ok(Type::None)
|
||||
}
|
||||
|
@ -1,8 +1,11 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::{self, Debug, Display, Formatter},
|
||||
sync::{Arc, RwLock, RwLockReadGuard},
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{error::rw_lock_error::RwLockError, Type, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -16,6 +19,26 @@ pub enum ValueData {
|
||||
},
|
||||
}
|
||||
|
||||
impl Eq for ValueData {}
|
||||
|
||||
impl PartialEq for ValueData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for ValueData {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for ValueData {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
inner: Arc<RwLock<HashMap<String, ValueData>>>,
|
||||
@ -87,3 +110,68 @@ impl Context {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Context {}
|
||||
|
||||
impl PartialEq for Context {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
let self_variables = self.inner().unwrap();
|
||||
let other_variables = other.inner().unwrap();
|
||||
|
||||
if self_variables.len() != other_variables.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ((left_key, left_value_data), (right_key, right_value_data)) in
|
||||
self_variables.iter().zip(other_variables.iter())
|
||||
{
|
||||
if left_key != right_key || left_value_data != right_value_data {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Context {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Context {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Context {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for Context {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Context {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Context {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user