diff --git a/src/abstract_tree/value_node.rs b/src/abstract_tree/value_node.rs index 3eddb32..2bb5d79 100644 --- a/src/abstract_tree/value_node.rs +++ b/src/abstract_tree/value_node.rs @@ -1,7 +1,5 @@ use std::{cmp::Ordering, collections::BTreeMap, ops::Range}; -use chumsky::container::Container; - use crate::{ context::Context, error::{RuntimeError, ValidationError}, diff --git a/src/error.rs b/src/error.rs index 20f015f..6c102bb 100644 --- a/src/error.rs +++ b/src/error.rs @@ -177,6 +177,7 @@ impl Error { ValidationError::ExpectedValue(_) => todo!(), ValidationError::PropertyNotFound { .. } => todo!(), ValidationError::WrongArguments { .. } => todo!(), + ValidationError::TypeNotFound(_) => todo!(), } } @@ -279,6 +280,7 @@ pub enum ValidationError { actual: Vec, }, VariableNotFound(Identifier), + TypeNotFound(Identifier), PropertyNotFound { identifier: Identifier, position: SourcePosition, diff --git a/src/value.rs b/src/value.rs index f7df626..c2fc434 100644 --- a/src/value.rs +++ b/src/value.rs @@ -15,7 +15,7 @@ use stanza::{ }; use crate::{ - abstract_tree::{AbstractTree, Action, Block, Expression, Identifier, Type, WithPosition}, + abstract_tree::{AbstractTree, Action, Block, Identifier, Type, WithPosition}, context::Context, error::{RuntimeError, ValidationError}, }; @@ -106,22 +106,11 @@ impl Value { }, Function::BuiltIn(built_in_function) => built_in_function.r#type(), }, - ValueInner::Structure { - name, - fields: expressions, - } => { - let mut fields = Vec::with_capacity(expressions.len()); - - for (identifier, value) in expressions { - fields.push(( - identifier.clone(), - value.r#type(context)?.with_position((0, 0)), - )); - } - - Type::Structure { - name: name.clone(), - fields, + ValueInner::Structure { name, .. } => { + if let Some(r#type) = context.get_type(name)? { + r#type + } else { + return Err(ValidationError::TypeNotFound(name.clone())); } } }; @@ -200,7 +189,15 @@ impl Display for Value { ValueInner::Function(Function::BuiltIn(built_in_function)) => { write!(f, "{built_in_function}") } - ValueInner::Structure { name, fields } => todo!(), + ValueInner::Structure { name, fields } => { + let mut table = create_table(); + + for (identifier, value) in fields { + table = table.with_row([identifier.as_str(), &value.to_string()]); + } + + write!(f, "{name}\n{}", Console::default().render(&table)) + } } } } diff --git a/tests/structs.rs b/tests/structs.rs index c466006..47e0ba8 100644 --- a/tests/structs.rs +++ b/tests/structs.rs @@ -25,3 +25,32 @@ fn simple_structure() { ))) ) } + +#[test] +fn nested_structure() { + assert_eq!( + interpret( + " + struct Bar { + baz : int + } + struct Foo { + bar : Bar + } + + Foo { + bar = Baz { + baz = 42 + } + } + " + ), + Ok(Some(Value::structure( + Identifier::new("Foo"), + vec![ + (Identifier::new("bar"), Value::integer(42)), + (Identifier::new("baz"), Value::string("hiya".to_string())), + ] + ))) + ) +}