Refine Map interface for stability
This commit is contained in:
parent
c736e3be8f
commit
74dd455ae4
@ -36,18 +36,6 @@ impl AbstractTree for Assignment {
|
||||
|
||||
let statement_node = syntax_node.child(child_count - 1).unwrap();
|
||||
let statement = Statement::from_syntax(statement_node, source, context)?;
|
||||
let statement_type = statement.expected_type(context)?;
|
||||
|
||||
let variable_key = identifier.inner().clone();
|
||||
let variable_type = if let Some(definition) = &type_definition {
|
||||
definition.inner().clone()
|
||||
} else {
|
||||
statement_type
|
||||
};
|
||||
|
||||
if let AssignmentOperator::Equal = operator {
|
||||
context.set_type(variable_key, variable_type)?;
|
||||
}
|
||||
|
||||
Ok(Assignment {
|
||||
identifier,
|
||||
@ -59,21 +47,11 @@ impl AbstractTree for Assignment {
|
||||
}
|
||||
|
||||
fn check_type(&self, source: &str, context: &Map) -> Result<()> {
|
||||
let variables = context.variables()?;
|
||||
let established_type = variables
|
||||
.get(self.identifier.inner())
|
||||
.map(|(_value, _type)| _type);
|
||||
let actual_type = self.statement.expected_type(context)?;
|
||||
|
||||
if let Some(type_definition) = &self.type_definition {
|
||||
match self.operator {
|
||||
AssignmentOperator::Equal => {
|
||||
if let Some(r#type) = established_type {
|
||||
r#type.check(&actual_type).map_err(|error| {
|
||||
error.at_source_position(source, self.syntax_position)
|
||||
})?;
|
||||
}
|
||||
|
||||
type_definition
|
||||
.inner()
|
||||
.check(&actual_type)
|
||||
@ -97,13 +75,7 @@ impl AbstractTree for Assignment {
|
||||
}
|
||||
} else {
|
||||
match self.operator {
|
||||
AssignmentOperator::Equal => {
|
||||
if let Some(r#type) = established_type {
|
||||
r#type.check(&actual_type).map_err(|error| {
|
||||
error.at_source_position(source, self.syntax_position)
|
||||
})?;
|
||||
}
|
||||
}
|
||||
AssignmentOperator::Equal => {}
|
||||
AssignmentOperator::PlusEqual => {
|
||||
if let Type::List(item_type) = self.identifier.expected_type(context)? {
|
||||
item_type.check(&actual_type).map_err(|error| {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{env::args, sync::OnceLock};
|
||||
use std::{collections::BTreeMap, env::args, sync::OnceLock};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -89,45 +89,37 @@ impl BuiltInValue {
|
||||
BuiltInValue::Length => &Value::Function(Function::BuiltIn(BuiltInFunction::Length)),
|
||||
BuiltInValue::Output => &Value::Function(Function::BuiltIn(BuiltInFunction::Output)),
|
||||
BuiltInValue::Random => RANDOM.get_or_init(|| {
|
||||
let random_context = Map::new();
|
||||
let mut random_context = BTreeMap::new();
|
||||
|
||||
{
|
||||
let mut variables = random_context.variables_mut().unwrap();
|
||||
for built_in_function in [
|
||||
BuiltInFunction::RandomBoolean,
|
||||
BuiltInFunction::RandomFloat,
|
||||
BuiltInFunction::RandomFrom,
|
||||
BuiltInFunction::RandomInteger,
|
||||
] {
|
||||
let key = built_in_function.name().to_string();
|
||||
let value = Value::Function(Function::BuiltIn(built_in_function));
|
||||
let r#type = built_in_function.r#type();
|
||||
|
||||
for built_in_function in [
|
||||
BuiltInFunction::RandomBoolean,
|
||||
BuiltInFunction::RandomFloat,
|
||||
BuiltInFunction::RandomFrom,
|
||||
BuiltInFunction::RandomInteger,
|
||||
] {
|
||||
let key = built_in_function.name().to_string();
|
||||
let value = Value::Function(Function::BuiltIn(built_in_function));
|
||||
let r#type = built_in_function.r#type();
|
||||
|
||||
variables.insert(key, (value, r#type));
|
||||
}
|
||||
random_context.insert(key, (value, r#type));
|
||||
}
|
||||
|
||||
Value::Map(random_context)
|
||||
Value::Map(Map::with_variables(random_context))
|
||||
}),
|
||||
BuiltInValue::String => STRING.get_or_init(|| {
|
||||
let string_context = Map::new();
|
||||
let mut string_context = BTreeMap::new();
|
||||
|
||||
{
|
||||
let mut variables = string_context.variables_mut().unwrap();
|
||||
for string_function in string_functions() {
|
||||
let key = string_function.name().to_string();
|
||||
let value = Value::Function(Function::BuiltIn(BuiltInFunction::String(
|
||||
string_function,
|
||||
)));
|
||||
let r#type = string_function.r#type();
|
||||
|
||||
for string_function in string_functions() {
|
||||
let key = string_function.name().to_string();
|
||||
let value = Value::Function(Function::BuiltIn(BuiltInFunction::String(
|
||||
string_function,
|
||||
)));
|
||||
let r#type = string_function.r#type();
|
||||
|
||||
variables.insert(key, (value, r#type));
|
||||
}
|
||||
string_context.insert(key, (value, r#type));
|
||||
}
|
||||
|
||||
Value::Map(string_context)
|
||||
Value::Map(Map::with_variables(string_context))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -115,10 +115,6 @@ impl AbstractTree for FunctionNode {
|
||||
|
||||
function_context.clone_complex_values_from(context)?;
|
||||
|
||||
for (identifier, r#type) in parameters.iter().zip(parameter_types.iter()) {
|
||||
function_context.set_type(identifier.inner().clone(), r#type.clone())?;
|
||||
}
|
||||
|
||||
let body_node = node.child(child_count - 1).unwrap();
|
||||
let body = Block::from_syntax(body_node, source, &function_context)?;
|
||||
|
||||
|
@ -8,7 +8,7 @@ use std::{
|
||||
collections::BTreeMap,
|
||||
fmt::{self, Display, Formatter},
|
||||
marker::PhantomData,
|
||||
sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard},
|
||||
sync::{Arc, RwLock, RwLockReadGuard},
|
||||
};
|
||||
|
||||
use crate::{value::Value, Result, Structure, Type};
|
||||
@ -32,6 +32,13 @@ impl Map {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_variables(variables: BTreeMap<String, (Value, Type)>) -> Self {
|
||||
Map {
|
||||
variables: Arc::new(RwLock::new(variables)),
|
||||
structure: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_from(other: &Self) -> Result<Self> {
|
||||
let mut new_map = BTreeMap::new();
|
||||
|
||||
@ -48,7 +55,8 @@ impl Map {
|
||||
pub fn clone_complex_values_from(&self, other: &Self) -> Result<()> {
|
||||
for (key, (value, r#type)) in other.variables()?.iter() {
|
||||
if value.is_function() {
|
||||
self.variables_mut()?
|
||||
self.variables
|
||||
.write()?
|
||||
.insert(key.clone(), (value.clone(), r#type.clone()));
|
||||
}
|
||||
}
|
||||
@ -60,10 +68,6 @@ impl Map {
|
||||
Ok(self.variables.read()?)
|
||||
}
|
||||
|
||||
pub fn variables_mut(&self) -> Result<RwLockWriteGuard<BTreeMap<String, (Value, Type)>>> {
|
||||
Ok(self.variables.write()?)
|
||||
}
|
||||
|
||||
pub fn set(&self, key: String, value: Value) -> Result<Option<(Value, Type)>> {
|
||||
log::info!("Setting variable {key} = {value}");
|
||||
|
||||
@ -76,12 +80,6 @@ impl Map {
|
||||
Ok(previous)
|
||||
}
|
||||
|
||||
pub fn set_type(&self, key: String, r#type: Type) -> Result<Option<(Value, Type)>> {
|
||||
let previous = self.variables.write()?.insert(key, (Value::none(), r#type));
|
||||
|
||||
Ok(previous)
|
||||
}
|
||||
|
||||
pub fn unset_all(&self) -> Result<()> {
|
||||
for (_key, (value, r#_type)) in self.variables.write()?.iter_mut() {
|
||||
*value = Value::none();
|
||||
|
Loading…
Reference in New Issue
Block a user