diff --git a/src/abstract_tree/enum_defintion.rs b/src/abstract_tree/enum_defintion.rs new file mode 100644 index 0000000..2301d00 --- /dev/null +++ b/src/abstract_tree/enum_defintion.rs @@ -0,0 +1,34 @@ +use serde::{Deserialize, Serialize}; +use tree_sitter::Node as SyntaxNode; + +use crate::{ + error::{RuntimeError, SyntaxError, ValidationError}, + AbstractTree, Context, Format, Type, Value, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub struct EnumDefinition; + +impl AbstractTree for EnumDefinition { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { + todo!() + } + + fn expected_type(&self, context: &Context) -> Result { + todo!() + } + + fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> { + todo!() + } + + fn run(&self, source: &str, context: &Context) -> Result { + todo!() + } +} + +impl Format for EnumDefinition { + fn format(&self, output: &mut String, indent_level: u8) { + todo!() + } +} diff --git a/src/abstract_tree/mod.rs b/src/abstract_tree/mod.rs index 5dd96da..0f9519c 100644 --- a/src/abstract_tree/mod.rs +++ b/src/abstract_tree/mod.rs @@ -12,6 +12,7 @@ pub mod assignment_operator; pub mod block; pub mod built_in_value; pub mod command; +pub mod enum_defintion; pub mod expression; pub mod r#for; pub mod function_call; @@ -29,17 +30,20 @@ pub mod math; pub mod math_operator; pub mod new; pub mod statement; +pub mod struct_definition; pub mod r#type; +pub mod type_definition; pub mod type_specification; pub mod value_node; pub mod r#while; pub use { - assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, expression::*, - function_call::*, function_expression::*, function_node::*, identifier::*, if_else::*, - index::*, index_assignment::IndexAssignment, index_expression::*, logic::*, logic_operator::*, - math::*, math_operator::*, new::*, r#as::*, r#for::*, r#match::*, r#type::*, r#while::*, - statement::*, type_specification::*, value_node::*, + assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, + enum_defintion::*, expression::*, function_call::*, function_expression::*, function_node::*, + identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*, + logic::*, logic_operator::*, math::*, math_operator::*, new::*, r#as::*, r#for::*, r#match::*, + r#type::*, r#while::*, statement::*, struct_definition::*, type_definition::*, + type_specification::*, value_node::*, }; use serde::{Deserialize, Serialize}; diff --git a/src/abstract_tree/statement.rs b/src/abstract_tree/statement.rs index 14f978d..b993c9b 100644 --- a/src/abstract_tree/statement.rs +++ b/src/abstract_tree/statement.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use crate::{ error::{RuntimeError, SyntaxError, ValidationError}, AbstractTree, Assignment, Block, Context, Expression, For, Format, IfElse, IndexAssignment, - Match, SyntaxNode, Type, Value, While, + Match, SyntaxNode, Type, TypeDefinition, Value, While, }; /// Abstract representation of a statement. @@ -18,6 +18,7 @@ pub enum Statement { Return(Box), For(Box), IndexAssignment(Box), + TypeDefinition(TypeDefinition), } impl AbstractTree for Statement { @@ -66,17 +67,20 @@ impl AbstractTree for Statement { } } - fn expected_type(&self, context: &Context) -> Result { + fn expected_type(&self, _context: &Context) -> Result { match self { - Statement::Assignment(assignment) => assignment.expected_type(context), - Statement::Expression(expression) => expression.expected_type(context), - Statement::IfElse(if_else) => if_else.expected_type(context), - Statement::Match(r#match) => r#match.expected_type(context), - Statement::While(r#while) => r#while.expected_type(context), - Statement::Block(block) => block.expected_type(context), - Statement::For(r#for) => r#for.expected_type(context), - Statement::IndexAssignment(index_assignment) => index_assignment.expected_type(context), - Statement::Return(statement) => statement.expected_type(context), + Statement::Assignment(assignment) => assignment.expected_type(_context), + Statement::Expression(expression) => expression.expected_type(_context), + Statement::IfElse(if_else) => if_else.expected_type(_context), + Statement::Match(r#match) => r#match.expected_type(_context), + Statement::While(r#while) => r#while.expected_type(_context), + Statement::Block(block) => block.expected_type(_context), + Statement::For(r#for) => r#for.expected_type(_context), + Statement::IndexAssignment(index_assignment) => { + index_assignment.expected_type(_context) + } + Statement::Return(statement) => statement.expected_type(_context), + Statement::TypeDefinition(type_definition) => type_definition.expected_type(_context), } } @@ -93,20 +97,24 @@ impl AbstractTree for Statement { index_assignment.validate(_source, _context) } Statement::Return(statement) => statement.validate(_source, _context), + Statement::TypeDefinition(type_definition) => { + type_definition.validate(_source, _context) + } } } - fn run(&self, source: &str, context: &Context) -> Result { + fn run(&self, _source: &str, _context: &Context) -> Result { match self { - Statement::Assignment(assignment) => assignment.run(source, context), - Statement::Expression(expression) => expression.run(source, context), - Statement::IfElse(if_else) => if_else.run(source, context), - Statement::Match(r#match) => r#match.run(source, context), - Statement::While(r#while) => r#while.run(source, context), - Statement::Block(block) => block.run(source, context), - Statement::For(r#for) => r#for.run(source, context), - Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context), - Statement::Return(statement) => statement.run(source, context), + Statement::Assignment(assignment) => assignment.run(_source, _context), + Statement::Expression(expression) => expression.run(_source, _context), + Statement::IfElse(if_else) => if_else.run(_source, _context), + Statement::Match(r#match) => r#match.run(_source, _context), + Statement::While(r#while) => r#while.run(_source, _context), + Statement::Block(block) => block.run(_source, _context), + Statement::For(r#for) => r#for.run(_source, _context), + Statement::IndexAssignment(index_assignment) => index_assignment.run(_source, _context), + Statement::Return(statement) => statement.run(_source, _context), + Statement::TypeDefinition(type_definition) => type_definition.run(_source, _context), } } } @@ -127,6 +135,9 @@ impl Format for Statement { index_assignment.format(output, indent_level) } Statement::Return(statement) => statement.format(output, indent_level), + Statement::TypeDefinition(type_definition) => { + type_definition.format(output, indent_level) + } } } } diff --git a/src/abstract_tree/struct_definition.rs b/src/abstract_tree/struct_definition.rs new file mode 100644 index 0000000..a8c4a9b --- /dev/null +++ b/src/abstract_tree/struct_definition.rs @@ -0,0 +1,34 @@ +use serde::{Deserialize, Serialize}; +use tree_sitter::Node as SyntaxNode; + +use crate::{ + error::{RuntimeError, SyntaxError, ValidationError}, + AbstractTree, Context, Format, Type, Value, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub struct StructDefinition; + +impl AbstractTree for StructDefinition { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { + todo!() + } + + fn expected_type(&self, context: &Context) -> Result { + todo!() + } + + fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> { + todo!() + } + + fn run(&self, source: &str, context: &Context) -> Result { + todo!() + } +} + +impl Format for StructDefinition { + fn format(&self, output: &mut String, indent_level: u8) { + todo!() + } +} diff --git a/src/abstract_tree/type_definition.rs b/src/abstract_tree/type_definition.rs new file mode 100644 index 0000000..b050704 --- /dev/null +++ b/src/abstract_tree/type_definition.rs @@ -0,0 +1,54 @@ +use serde::{Deserialize, Serialize}; +use tree_sitter::Node as SyntaxNode; + +use crate::{ + error::{RuntimeError, SyntaxError, ValidationError}, + AbstractTree, Context, EnumDefinition, Format, StructDefinition, Type, Value, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] +pub enum TypeDefinition { + Enum(EnumDefinition), + Struct(StructDefinition), +} + +impl AbstractTree for TypeDefinition { + fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result { + SyntaxError::expect_syntax_node(source, "type_definition", node)?; + + let child = node.child(0).unwrap(); + + match child.kind() { + "enum_definition" => Ok(TypeDefinition::Enum(EnumDefinition::from_syntax( + child, source, context, + )?)), + "struct_definition" => Ok(TypeDefinition::Struct(StructDefinition::from_syntax( + child, source, context, + )?)), + _ => Err(SyntaxError::UnexpectedSyntaxNode { + expected: "enum or struct definition".to_string(), + actual: child.kind().to_string(), + location: child.start_position(), + relevant_source: source[child.byte_range()].to_string(), + }), + } + } + + fn expected_type(&self, context: &Context) -> Result { + todo!() + } + + fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> { + todo!() + } + + fn run(&self, source: &str, context: &Context) -> Result { + todo!() + } +} + +impl Format for TypeDefinition { + fn format(&self, output: &mut String, indent_level: u8) { + todo!() + } +} diff --git a/src/value/enum.rs b/src/value/enum.rs new file mode 100644 index 0000000..556780a --- /dev/null +++ b/src/value/enum.rs @@ -0,0 +1,16 @@ +use crate::{Identifier, Value}; + +#[derive(Debug, Clone)] +pub struct Enum { + variant_name: String, + value: Box, +} + +impl Enum { + pub fn new(variant_name: String, value: Value) -> Self { + Self { + variant_name, + value: Box::new(value), + } + } +} diff --git a/src/value/mod.rs b/src/value/mod.rs index 0b43767..b3085f0 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -16,8 +16,9 @@ use std::{ ops::{Add, AddAssign, Div, Mul, RangeInclusive, Rem, Sub, SubAssign}, }; -pub use self::{function::Function, list::List, map::Map, structure::Structure}; +pub use self::{function::Function, list::List, map::Map, r#enum::Enum, structure::Structure}; +pub mod r#enum; pub mod function; pub mod list; pub mod map; @@ -40,6 +41,7 @@ pub enum Value { Range(RangeInclusive), Option(Option>), Structure(Structure), + Enum(Enum), } impl Default for Value { @@ -106,6 +108,7 @@ impl Value { } Value::Range(_) => todo!(), Value::Structure(_) => todo!(), + Value::Enum(_) => todo!(), } } @@ -489,6 +492,17 @@ impl Ord for Value { (Value::Range(_), _) => Ordering::Greater, (Value::Option(left), Value::Option(right)) => left.cmp(right), (Value::Option(_), _) => Ordering::Less, + (Value::Enum(_), Value::List(_)) => todo!(), + (Value::Enum(_), Value::Map(_)) => todo!(), + (Value::Enum(_), Value::Function(_)) => todo!(), + (Value::Enum(_), Value::String(_)) => todo!(), + (Value::Enum(_), Value::Float(_)) => todo!(), + (Value::Enum(_), Value::Integer(_)) => todo!(), + (Value::Enum(_), Value::Boolean(_)) => todo!(), + (Value::Enum(_), Value::Range(_)) => todo!(), + (Value::Enum(_), Value::Option(_)) => todo!(), + (Value::Enum(_), Value::Structure(_)) => todo!(), + (Value::Enum(_), Value::Enum(_)) => todo!(), } } } @@ -527,6 +541,7 @@ impl Serialize for Value { Value::Function(inner) => inner.serialize(serializer), Value::Structure(inner) => inner.serialize(serializer), Value::Range(range) => range.serialize(serializer), + Value::Enum(_) => todo!(), } } } @@ -550,6 +565,7 @@ impl Display for Value { Value::Function(function) => write!(f, "{function}"), Value::Structure(structure) => write!(f, "{structure}"), Value::Range(range) => write!(f, "{}..{}", range.start(), range.end()), + Value::Enum(_) => todo!(), } } } diff --git a/tests/enums.rs b/tests/enums.rs new file mode 100644 index 0000000..b18b5b6 --- /dev/null +++ b/tests/enums.rs @@ -0,0 +1,20 @@ +use dust_lang::*; + +#[test] +fn simple_enum() { + let result = interpret( + " + enum Foobar { + Foo, + Bar, + } + + new Foobar:Foo + ", + ); + + assert_eq!( + result, + Ok(Value::Enum(Enum::new("Foo".to_string(), Value::none()))) + ); +}