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