Implement structure values

This commit is contained in:
Jeff 2024-03-19 19:16:33 -04:00
parent bcc89f2c7d
commit 21fea2b43f
3 changed files with 60 additions and 9 deletions

View File

@ -1,5 +1,7 @@
use std::{cmp::Ordering, collections::BTreeMap, ops::Range};
use chumsky::container::Container;
use crate::{
context::Context,
error::{RuntimeError, ValidationError},
@ -165,7 +167,27 @@ impl AbstractTree for ValueNode {
return_type,
body,
} => Value::function(parameters, return_type, body),
ValueNode::Structure { name, fields } => todo!(),
ValueNode::Structure {
name,
fields: expressions,
} => {
let mut fields = Vec::with_capacity(expressions.len());
for (identifier, expression) in expressions {
let action = expression.node.run(_context)?;
let value = if let Action::Return(value) = action {
value
} else {
return Err(RuntimeError::ValidationFailure(
ValidationError::InterpreterExpectedReturn(expression.position),
));
};
fields.push((identifier, value));
}
Value::structure(name, fields)
}
};
Ok(Action::Return(value))

View File

@ -70,6 +70,10 @@ impl Value {
))))
}
pub fn structure(name: Identifier, fields: Vec<(Identifier, Value)>) -> Self {
Value(Arc::new(ValueInner::Structure { name, fields }))
}
pub fn built_in_function(function: BuiltInFunction) -> Self {
Value(Arc::new(ValueInner::Function(Function::BuiltIn(function))))
}
@ -108,13 +112,11 @@ impl Value {
} => {
let mut fields = Vec::with_capacity(expressions.len());
for (identifier, expression) in expressions {
let r#type = expression
.node
.expected_type(context)?
.with_position(expression.position);
fields.push((identifier.clone(), r#type));
for (identifier, value) in expressions {
fields.push((
identifier.clone(),
value.r#type(context)?.with_position((0, 0)),
));
}
Type::Structure {
@ -229,7 +231,7 @@ pub enum ValueInner {
String(String),
Structure {
name: Identifier,
fields: Vec<(Identifier, WithPosition<Expression>)>,
fields: Vec<(Identifier, Value)>,
},
}

27
tests/structs.rs Normal file
View File

@ -0,0 +1,27 @@
use dust_lang::{abstract_tree::Identifier, *};
#[test]
fn simple_structure() {
assert_eq!(
interpret(
"
struct Foo {
bar : int,
baz : str,
}
Foo {
bar = 42,
baz = 'hiya',
}
"
),
Ok(Some(Value::structure(
Identifier::new("Foo"),
vec![
(Identifier::new("bar"), Value::integer(42)),
(Identifier::new("baz"), Value::string("hiya".to_string())),
]
)))
)
}