1
0

Add instantiating unit structs

This commit is contained in:
Jeff 2024-08-13 14:21:31 -04:00
parent 7e7448fe52
commit 1d75bd6594
6 changed files with 67 additions and 19 deletions

View File

@ -11,7 +11,8 @@ use std::{
use crate::{
abstract_tree::{BinaryOperator, UnaryOperator},
parse, AbstractSyntaxTree, Context, DustError, Identifier, Node, Span, Statement, Type,
parse, AbstractSyntaxTree, Context, DustError, Identifier, Node, Span, Statement,
StructDefinition, StructType, Type,
};
/// Analyzes the abstract syntax tree for errors.
@ -420,7 +421,18 @@ impl<'a> Analyzer<'a> {
Statement::Nil(node) => {
self.analyze_statement(node)?;
}
Statement::StructDefinition(_) => {}
Statement::StructDefinition(struct_definition) => {
let (name, r#type) = match struct_definition {
StructDefinition::Unit { name } => (
name.inner.clone(),
Type::Struct(StructType::Unit {
name: name.inner.clone(),
}),
),
};
self.context.set_type(name, r#type, node.position);
}
Statement::UnaryOperation { operator, operand } => {
self.analyze_statement(operand)?;

View File

@ -24,7 +24,7 @@ pub use dust_error::DustError;
pub use identifier::Identifier;
pub use lexer::{lex, LexError, Lexer};
pub use parser::{parse, ParseError, Parser};
pub use r#type::Type;
pub use r#type::{StructType, Type};
pub use token::{Token, TokenKind, TokenOwned};
pub use value::{Struct, Value, ValueError};
pub use vm::{run, run_with_context, Vm, VmError};

View File

@ -912,7 +912,7 @@ impl Display for ParseError {
#[cfg(test)]
mod tests {
use crate::{abstract_tree::BinaryOperator, Identifier, StructDefinition, UnaryOperator};
use crate::{BinaryOperator, Identifier, StructDefinition, UnaryOperator};
use super::*;

View File

@ -16,7 +16,7 @@ use std::{
use serde::{Deserialize, Serialize};
use crate::Identifier;
use crate::{Identifier, Struct};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct TypeConflict {
@ -31,7 +31,6 @@ pub struct TypeConflict {
pub enum Type {
Any,
Boolean,
Defined(Identifier),
Enum {
name: Identifier,
type_parameters: Option<Vec<Type>>,
@ -252,7 +251,6 @@ impl Display for Type {
match self {
Type::Any => write!(f, "any"),
Type::Boolean => write!(f, "bool"),
Type::Defined(identifier) => write!(f, "{identifier}"),
Type::Enum { variants, .. } => {
write!(f, "enum ")?;
@ -354,6 +352,15 @@ pub enum StructType {
},
}
impl StructType {
pub fn instantiate(&self) -> Struct {
match self {
StructType::Unit { name } => Struct::Unit { name: name.clone() },
_ => todo!(),
}
}
}
impl Display for StructType {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {

View File

@ -14,7 +14,7 @@ use serde::{
Deserialize, Deserializer, Serialize,
};
use crate::{identifier::Identifier, AbstractSyntaxTree, Context, Type, Vm, VmError};
use crate::{identifier::Identifier, AbstractSyntaxTree, Context, StructType, Type, Vm, VmError};
/// Dust value representation
///
@ -699,7 +699,11 @@ impl ValueInner {
}
ValueInner::Range(_) => Type::Range,
ValueInner::String(_) => Type::String,
ValueInner::Struct(r#struct) => Type::Defined(r#struct.name().clone()),
ValueInner::Struct(r#struct) => match r#struct {
Struct::Unit { name } => Type::Struct(StructType::Unit { name: name.clone() }),
Struct::Tuple { .. } => todo!(),
Struct::Fields { .. } => todo!(),
},
}
}

View File

@ -11,8 +11,8 @@ use std::{
use crate::{
parse, value::ValueInner, AbstractSyntaxTree, Analyzer, BinaryOperator, BuiltInFunctionError,
Context, DustError, Identifier, Node, ParseError, Span, Statement, StructDefinition, Type,
UnaryOperator, Value, ValueError,
Context, DustError, Identifier, Node, ParseError, Span, Statement, StructDefinition,
StructType, Type, UnaryOperator, Value, ValueError,
};
/// Run the source code and return the result.
@ -378,12 +378,20 @@ impl Vm {
let value_option = self.context.get_value(&identifier);
if let Some(value) = value_option {
Ok(Some(value.clone()))
} else {
Err(VmError::UndefinedVariable {
identifier: Node::new(Statement::Identifier(identifier), node.position),
})
return Ok(Some(value.clone()));
}
let type_option = self.context.get_type(&identifier);
println!("{type_option:?}");
if let Some(Type::Struct(struct_type)) = type_option {
return Ok(Some(Value::r#struct(struct_type.instantiate())));
}
Err(VmError::UndefinedVariable {
identifier: Node::new(Statement::Identifier(identifier), node.position),
})
}
Statement::If { condition, body } => {
let condition_position = condition.position;
@ -578,9 +586,12 @@ impl Vm {
}
Statement::StructDefinition(struct_definition) => {
let (type_name, r#type) = match struct_definition {
StructDefinition::Unit { name } => {
(name.inner.clone(), Type::Defined(name.inner.clone()))
}
StructDefinition::Unit { name } => (
name.inner.clone(),
Type::Struct(StructType::Unit {
name: name.inner.clone(),
}),
),
};
self.context.set_type(type_name, r#type, node.position);
@ -797,8 +808,22 @@ impl Display for VmError {
#[cfg(test)]
mod tests {
use crate::Struct;
use super::*;
#[test]
fn define_and_instantiate_unit_struct() {
let input = "struct Foo Foo";
assert_eq!(
run(input),
Ok(Some(Value::r#struct(Struct::Unit {
name: Identifier::new("Foo")
})))
);
}
#[test]
fn list_index_nested() {
let input = "[[1, 2], [42, 4], [5, 6]][1][0]";