Implement structure values
This commit is contained in:
parent
bcc89f2c7d
commit
21fea2b43f
@ -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))
|
||||
|
18
src/value.rs
18
src/value.rs
@ -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
27
tests/structs.rs
Normal 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())),
|
||||
]
|
||||
)))
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user