1
0

Refine Map interface for stability

This commit is contained in:
Jeff 2024-01-17 10:21:00 -05:00
parent c736e3be8f
commit 74dd455ae4
4 changed files with 33 additions and 75 deletions

View File

@ -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| {

View File

@ -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))
}),
}
}

View File

@ -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)?;

View File

@ -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();