1
0

Fix type setting bugs

This commit is contained in:
Jeff 2024-01-31 21:21:42 -05:00
parent e486413aca
commit 9ef82df3a7
4 changed files with 45 additions and 30 deletions

View File

@ -5,7 +5,7 @@ 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, Expression, Format, Function, FunctionNode, Identifier, List, Map,
Statement, Structure, SyntaxNode, Type, TypeSpecification, Value, SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
@ -17,7 +17,7 @@ pub enum ValueNode {
String(String), String(String),
List(Vec<Expression>), List(Vec<Expression>),
Option(Option<Box<Expression>>), Option(Option<Box<Expression>>),
Map(BTreeMap<String, (Statement, Option<Type>)>), Map(BTreeMap<String, (Statement, Option<Type>)>, SourcePosition),
BuiltInValue(BuiltInValue), BuiltInValue(BuiltInValue),
Structure(BTreeMap<String, (Option<Statement>, Type)>), Structure(BTreeMap<String, (Option<Statement>, Type)>),
Range(RangeInclusive<i64>), Range(RangeInclusive<i64>),
@ -83,7 +83,7 @@ impl AbstractTree for ValueNode {
} }
} }
ValueNode::Map(child_nodes) ValueNode::Map(child_nodes, SourcePosition::from(child.range()))
} }
"option" => { "option" => {
let first_grandchild = child.child(0).unwrap(); let first_grandchild = child.child(0).unwrap();
@ -217,7 +217,7 @@ impl AbstractTree for ValueNode {
Type::None Type::None
} }
} }
ValueNode::Map(_) => Type::Map(None), ValueNode::Map(_, _) => Type::Map(None),
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?, ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
ValueNode::Structure(node_map) => { ValueNode::Structure(node_map) => {
let mut value_map = BTreeMap::new(); let mut value_map = BTreeMap::new();
@ -234,11 +234,26 @@ 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: &Map) -> 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 {
function_node.validate(_source, _context)?; function_node.validate(_source, context)?;
}
}
ValueNode::Map(statements, source_position) => {
for (key, (statement, r#type)) in statements {
if let Some(expected) = r#type {
let actual = statement.expected_type(context)?;
if !expected.accepts(&actual) {
return Err(ValidationError::TypeCheck {
expected: expected.clone(),
actual,
position: source_position.clone(),
});
}
}
} }
} }
_ => {} _ => {}
@ -278,7 +293,7 @@ impl AbstractTree for ValueNode {
Value::Option(option_value) Value::Option(option_value)
} }
ValueNode::Map(key_statement_pairs) => { ValueNode::Map(key_statement_pairs, _) => {
let map = Map::new(); let map = Map::new();
{ {
@ -344,7 +359,7 @@ impl Format for ValueNode {
output.push_str("none"); output.push_str("none");
} }
} }
ValueNode::Map(nodes) => { ValueNode::Map(nodes, _) => {
output.push_str("{\n"); output.push_str("{\n");
for (key, (statement, type_option)) in nodes { for (key, (statement, type_option)) in nodes {
@ -413,8 +428,8 @@ impl Ord for ValueNode {
(ValueNode::List(_), _) => Ordering::Greater, (ValueNode::List(_), _) => Ordering::Greater,
(ValueNode::Option(left), ValueNode::Option(right)) => left.cmp(right), (ValueNode::Option(left), ValueNode::Option(right)) => left.cmp(right),
(ValueNode::Option(_), _) => Ordering::Greater, (ValueNode::Option(_), _) => Ordering::Greater,
(ValueNode::Map(left), ValueNode::Map(right)) => left.cmp(right), (ValueNode::Map(left, _), ValueNode::Map(right, _)) => left.cmp(right),
(ValueNode::Map(_), _) => Ordering::Greater, (ValueNode::Map(_, _), _) => Ordering::Greater,
(ValueNode::BuiltInValue(left), ValueNode::BuiltInValue(right)) => left.cmp(right), (ValueNode::BuiltInValue(left), ValueNode::BuiltInValue(right)) => left.cmp(right),
(ValueNode::BuiltInValue(_), _) => Ordering::Greater, (ValueNode::BuiltInValue(_), _) => Ordering::Greater,
(ValueNode::Structure(left), ValueNode::Structure(right)) => left.cmp(right), (ValueNode::Structure(left), ValueNode::Structure(right)) => left.cmp(right),

View File

@ -44,12 +44,12 @@ fn list_add_wrong_type() {
expected: Type::String, expected: Type::String,
actual: Type::Integer, actual: Type::Integer,
position: SourcePosition { position: SourcePosition {
start_byte: 0, start_byte: 40,
end_byte: 0, end_byte: 46,
start_row: 0, start_row: 3,
start_column: 0, start_column: 12,
end_row: 0, end_row: 3,
end_column: 0 end_column: 18
} }
})), })),
result result

View File

@ -10,11 +10,11 @@ fn simple_type_check() {
actual: Type::Integer, actual: Type::Integer,
position: SourcePosition { position: SourcePosition {
start_byte: 0, start_byte: 0,
end_byte: 0, end_byte: 12,
start_row: 0, start_row: 1,
start_column: 0, start_column: 0,
end_row: 0, end_row: 1,
end_column: 0, end_column: 12,
} }
})), })),
result result
@ -59,12 +59,12 @@ fn callback_type_check() {
return_type: Box::new(Type::Integer), return_type: Box::new(Type::Integer),
}, },
position: SourcePosition { position: SourcePosition {
start_byte: 0, start_byte: 91,
end_byte: 0, end_byte: 108,
start_row: 0, start_row: 5,
start_column: 0, start_column: 12,
end_row: 0, end_row: 5,
end_column: 0 end_column: 29,
} }
})), })),
result result

View File

@ -106,11 +106,11 @@ fn map_type_errors() {
actual: Type::String, actual: Type::String,
position: SourcePosition { position: SourcePosition {
start_byte: 0, start_byte: 0,
end_byte: 0, end_byte: 22,
start_row: 0, start_row: 1,
start_column: 0, start_column: 0,
end_row: 0, end_row: 1,
end_column: 0 end_column: 22
} }
})) }))
); );