Fix type setting bugs
This commit is contained in:
parent
e486413aca
commit
9ef82df3a7
@ -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),
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user