Begin implementing enums

This commit is contained in:
Jeff 2024-02-14 20:53:42 -05:00
parent 4323c50d32
commit b8c54ea8bd
8 changed files with 216 additions and 27 deletions

View File

@ -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<Self, SyntaxError> {
todo!()
}
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
todo!()
}
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
todo!()
}
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
todo!()
}
}
impl Format for EnumDefinition {
fn format(&self, output: &mut String, indent_level: u8) {
todo!()
}
}

View File

@ -12,6 +12,7 @@ pub mod assignment_operator;
pub mod block; pub mod block;
pub mod built_in_value; pub mod built_in_value;
pub mod command; pub mod command;
pub mod enum_defintion;
pub mod expression; pub mod expression;
pub mod r#for; pub mod r#for;
pub mod function_call; pub mod function_call;
@ -29,17 +30,20 @@ pub mod math;
pub mod math_operator; pub mod math_operator;
pub mod new; pub mod new;
pub mod statement; pub mod statement;
pub mod struct_definition;
pub mod r#type; pub mod r#type;
pub mod type_definition;
pub mod type_specification; pub mod type_specification;
pub mod value_node; pub mod value_node;
pub mod r#while; pub mod r#while;
pub use { pub use {
assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*, expression::*, assignment::*, assignment_operator::*, block::*, built_in_value::*, command::*,
function_call::*, function_expression::*, function_node::*, identifier::*, if_else::*, enum_defintion::*, expression::*, function_call::*, function_expression::*, function_node::*,
index::*, index_assignment::IndexAssignment, index_expression::*, logic::*, logic_operator::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*,
math::*, math_operator::*, new::*, r#as::*, r#for::*, r#match::*, r#type::*, r#while::*, logic::*, logic_operator::*, math::*, math_operator::*, new::*, r#as::*, r#for::*, r#match::*,
statement::*, type_specification::*, value_node::*, r#type::*, r#while::*, statement::*, struct_definition::*, type_definition::*,
type_specification::*, value_node::*,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};

View File

@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
error::{RuntimeError, SyntaxError, ValidationError}, error::{RuntimeError, SyntaxError, ValidationError},
AbstractTree, Assignment, Block, Context, Expression, For, Format, IfElse, IndexAssignment, 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. /// Abstract representation of a statement.
@ -18,6 +18,7 @@ pub enum Statement {
Return(Box<Statement>), Return(Box<Statement>),
For(Box<For>), For(Box<For>),
IndexAssignment(Box<IndexAssignment>), IndexAssignment(Box<IndexAssignment>),
TypeDefinition(TypeDefinition),
} }
impl AbstractTree for Statement { impl AbstractTree for Statement {
@ -66,17 +67,20 @@ impl AbstractTree for Statement {
} }
} }
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
match self { match self {
Statement::Assignment(assignment) => assignment.expected_type(context), Statement::Assignment(assignment) => assignment.expected_type(_context),
Statement::Expression(expression) => expression.expected_type(context), Statement::Expression(expression) => expression.expected_type(_context),
Statement::IfElse(if_else) => if_else.expected_type(context), Statement::IfElse(if_else) => if_else.expected_type(_context),
Statement::Match(r#match) => r#match.expected_type(context), Statement::Match(r#match) => r#match.expected_type(_context),
Statement::While(r#while) => r#while.expected_type(context), Statement::While(r#while) => r#while.expected_type(_context),
Statement::Block(block) => block.expected_type(context), Statement::Block(block) => block.expected_type(_context),
Statement::For(r#for) => r#for.expected_type(context), Statement::For(r#for) => r#for.expected_type(_context),
Statement::IndexAssignment(index_assignment) => index_assignment.expected_type(context), Statement::IndexAssignment(index_assignment) => {
Statement::Return(statement) => statement.expected_type(context), 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) index_assignment.validate(_source, _context)
} }
Statement::Return(statement) => statement.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<Value, RuntimeError> { fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
match self { match self {
Statement::Assignment(assignment) => assignment.run(source, context), Statement::Assignment(assignment) => assignment.run(_source, _context),
Statement::Expression(expression) => expression.run(source, context), Statement::Expression(expression) => expression.run(_source, _context),
Statement::IfElse(if_else) => if_else.run(source, context), Statement::IfElse(if_else) => if_else.run(_source, _context),
Statement::Match(r#match) => r#match.run(source, context), Statement::Match(r#match) => r#match.run(_source, _context),
Statement::While(r#while) => r#while.run(source, context), Statement::While(r#while) => r#while.run(_source, _context),
Statement::Block(block) => block.run(source, context), Statement::Block(block) => block.run(_source, _context),
Statement::For(r#for) => r#for.run(source, context), Statement::For(r#for) => r#for.run(_source, _context),
Statement::IndexAssignment(index_assignment) => index_assignment.run(source, context), Statement::IndexAssignment(index_assignment) => index_assignment.run(_source, _context),
Statement::Return(statement) => statement.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) index_assignment.format(output, indent_level)
} }
Statement::Return(statement) => statement.format(output, indent_level), Statement::Return(statement) => statement.format(output, indent_level),
Statement::TypeDefinition(type_definition) => {
type_definition.format(output, indent_level)
}
} }
} }
} }

View File

@ -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<Self, SyntaxError> {
todo!()
}
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
todo!()
}
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
todo!()
}
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
todo!()
}
}
impl Format for StructDefinition {
fn format(&self, output: &mut String, indent_level: u8) {
todo!()
}
}

View File

@ -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<Self, SyntaxError> {
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<Type, ValidationError> {
todo!()
}
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
todo!()
}
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
todo!()
}
}
impl Format for TypeDefinition {
fn format(&self, output: &mut String, indent_level: u8) {
todo!()
}
}

16
src/value/enum.rs Normal file
View File

@ -0,0 +1,16 @@
use crate::{Identifier, Value};
#[derive(Debug, Clone)]
pub struct Enum {
variant_name: String,
value: Box<Value>,
}
impl Enum {
pub fn new(variant_name: String, value: Value) -> Self {
Self {
variant_name,
value: Box::new(value),
}
}
}

View File

@ -16,8 +16,9 @@ use std::{
ops::{Add, AddAssign, Div, Mul, RangeInclusive, Rem, Sub, SubAssign}, 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 function;
pub mod list; pub mod list;
pub mod map; pub mod map;
@ -40,6 +41,7 @@ pub enum Value {
Range(RangeInclusive<i64>), Range(RangeInclusive<i64>),
Option(Option<Box<Value>>), Option(Option<Box<Value>>),
Structure(Structure), Structure(Structure),
Enum(Enum),
} }
impl Default for Value { impl Default for Value {
@ -106,6 +108,7 @@ impl Value {
} }
Value::Range(_) => todo!(), Value::Range(_) => todo!(),
Value::Structure(_) => todo!(), Value::Structure(_) => todo!(),
Value::Enum(_) => todo!(),
} }
} }
@ -489,6 +492,17 @@ impl Ord for Value {
(Value::Range(_), _) => Ordering::Greater, (Value::Range(_), _) => Ordering::Greater,
(Value::Option(left), Value::Option(right)) => left.cmp(right), (Value::Option(left), Value::Option(right)) => left.cmp(right),
(Value::Option(_), _) => Ordering::Less, (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::Function(inner) => inner.serialize(serializer),
Value::Structure(inner) => inner.serialize(serializer), Value::Structure(inner) => inner.serialize(serializer),
Value::Range(range) => range.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::Function(function) => write!(f, "{function}"),
Value::Structure(structure) => write!(f, "{structure}"), Value::Structure(structure) => write!(f, "{structure}"),
Value::Range(range) => write!(f, "{}..{}", range.start(), range.end()), Value::Range(range) => write!(f, "{}..{}", range.start(), range.end()),
Value::Enum(_) => todo!(),
} }
} }
} }

20
tests/enums.rs Normal file
View File

@ -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())))
);
}