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 std::{cmp::Ordering, collections::BTreeMap, ops::Range};
|
||||||
|
|
||||||
|
use chumsky::container::Container;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
context::Context,
|
context::Context,
|
||||||
error::{RuntimeError, ValidationError},
|
error::{RuntimeError, ValidationError},
|
||||||
@ -165,7 +167,27 @@ impl AbstractTree for ValueNode {
|
|||||||
return_type,
|
return_type,
|
||||||
body,
|
body,
|
||||||
} => Value::function(parameters, 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))
|
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 {
|
pub fn built_in_function(function: BuiltInFunction) -> Self {
|
||||||
Value(Arc::new(ValueInner::Function(Function::BuiltIn(function))))
|
Value(Arc::new(ValueInner::Function(Function::BuiltIn(function))))
|
||||||
}
|
}
|
||||||
@ -108,13 +112,11 @@ impl Value {
|
|||||||
} => {
|
} => {
|
||||||
let mut fields = Vec::with_capacity(expressions.len());
|
let mut fields = Vec::with_capacity(expressions.len());
|
||||||
|
|
||||||
for (identifier, expression) in expressions {
|
for (identifier, value) in expressions {
|
||||||
let r#type = expression
|
fields.push((
|
||||||
.node
|
identifier.clone(),
|
||||||
.expected_type(context)?
|
value.r#type(context)?.with_position((0, 0)),
|
||||||
.with_position(expression.position);
|
));
|
||||||
|
|
||||||
fields.push((identifier.clone(), r#type));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Structure {
|
Type::Structure {
|
||||||
@ -229,7 +231,7 @@ pub enum ValueInner {
|
|||||||
String(String),
|
String(String),
|
||||||
Structure {
|
Structure {
|
||||||
name: Identifier,
|
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