Begin implementing enums
This commit is contained in:
parent
4323c50d32
commit
b8c54ea8bd
34
src/abstract_tree/enum_defintion.rs
Normal file
34
src/abstract_tree/enum_defintion.rs
Normal 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!()
|
||||
}
|
||||
}
|
@ -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};
|
||||
|
@ -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<Statement>),
|
||||
For(Box<For>),
|
||||
IndexAssignment(Box<IndexAssignment>),
|
||||
TypeDefinition(TypeDefinition),
|
||||
}
|
||||
|
||||
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 {
|
||||
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<Value, RuntimeError> {
|
||||
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
34
src/abstract_tree/struct_definition.rs
Normal file
34
src/abstract_tree/struct_definition.rs
Normal 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!()
|
||||
}
|
||||
}
|
54
src/abstract_tree/type_definition.rs
Normal file
54
src/abstract_tree/type_definition.rs
Normal 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
16
src/value/enum.rs
Normal 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),
|
||||
}
|
||||
}
|
||||
}
|
@ -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<i64>),
|
||||
Option(Option<Box<Value>>),
|
||||
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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
tests/enums.rs
Normal file
20
tests/enums.rs
Normal 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())))
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user