Implement basic enum instantiation
This commit is contained in:
parent
b8c54ea8bd
commit
89a4c09307
@ -3,32 +3,89 @@ use tree_sitter::Node as SyntaxNode;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Context, Format, Type, Value,
|
AbstractTree, Context, EnumInstance, Format, Identifier, Type, TypeDefinition, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct EnumDefinition;
|
pub struct EnumDefinition {
|
||||||
|
identifier: Identifier,
|
||||||
|
variants: Vec<(Identifier, VariantContent)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
|
enum VariantContent {
|
||||||
|
Type(Type),
|
||||||
|
TypeDefinition(TypeDefinition),
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EnumDefinition {
|
||||||
|
pub fn instantiate(&self, variant: String, content: Value) -> EnumInstance {
|
||||||
|
EnumInstance::new(self.identifier.inner().clone(), variant, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AbstractTree for EnumDefinition {
|
impl AbstractTree for EnumDefinition {
|
||||||
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
fn from_syntax(node: SyntaxNode, source: &str, context: &Context) -> Result<Self, SyntaxError> {
|
||||||
todo!()
|
SyntaxError::expect_syntax_node(source, "enum_definition", node)?;
|
||||||
|
|
||||||
|
let identifier_node = node.child(1).unwrap();
|
||||||
|
let identifier = Identifier::from_syntax(identifier_node, source, context)?;
|
||||||
|
|
||||||
|
let mut variants = Vec::new();
|
||||||
|
let mut current_identifier = None;
|
||||||
|
|
||||||
|
for index in 3..node.child_count() - 1 {
|
||||||
|
let child = node.child(index).unwrap();
|
||||||
|
|
||||||
|
if child.kind() == "identifier" {
|
||||||
|
current_identifier = Some(Identifier::from_syntax(child, source, context)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(identifier) = ¤t_identifier {
|
||||||
|
if child.kind() == "type" {
|
||||||
|
let r#type = Type::from_syntax(child, source, context)?;
|
||||||
|
|
||||||
|
variants.push((identifier.clone(), VariantContent::Type(r#type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if child.kind() == "type_definition" {
|
||||||
|
let type_definition = TypeDefinition::from_syntax(child, source, context)?;
|
||||||
|
|
||||||
|
variants.push((
|
||||||
|
identifier.clone(),
|
||||||
|
VariantContent::TypeDefinition(type_definition),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(EnumDefinition {
|
||||||
|
identifier,
|
||||||
|
variants,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
todo!()
|
Ok(Type::None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
todo!()
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
todo!()
|
context.set_definition(
|
||||||
|
self.identifier.inner().clone(),
|
||||||
|
TypeDefinition::Enum(self.clone()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(Value::none())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format for EnumDefinition {
|
impl Format for EnumDefinition {
|
||||||
fn format(&self, output: &mut String, indent_level: u8) {
|
fn format(&self, _output: &mut String, _indent_level: u8) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,12 @@ impl AbstractTree for Statement {
|
|||||||
|
|
||||||
Ok(Statement::Return(Box::new(Statement::from_syntax(statement_node, source, context)?)))
|
Ok(Statement::Return(Box::new(Statement::from_syntax(statement_node, source, context)?)))
|
||||||
},
|
},
|
||||||
|
"type_definition" => Ok(Statement::TypeDefinition(TypeDefinition::from_syntax(
|
||||||
|
child, source, context
|
||||||
|
)?)),
|
||||||
_ => Err(SyntaxError::UnexpectedSyntaxNode {
|
_ => Err(SyntaxError::UnexpectedSyntaxNode {
|
||||||
expected:
|
expected:
|
||||||
"assignment, index assignment, expression, block, return, if...else, while, for or match".to_string(),
|
"assignment, index assignment, expression, type_definition, block, return, if...else, while, for or match".to_string(),
|
||||||
actual: child.kind().to_string(),
|
actual: child.kind().to_string(),
|
||||||
location: child.start_position(),
|
location: child.start_position(),
|
||||||
relevant_source: source[child.byte_range()].to_string(),
|
relevant_source: source[child.byte_range()].to_string(),
|
||||||
|
@ -34,21 +34,32 @@ impl AbstractTree for TypeDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
todo!()
|
match self {
|
||||||
|
TypeDefinition::Enum(enum_definition) => enum_definition.expected_type(_context),
|
||||||
|
TypeDefinition::Struct(struct_definition) => struct_definition.expected_type(_context),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, source: &str, context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
||||||
todo!()
|
match self {
|
||||||
|
TypeDefinition::Enum(enum_definition) => enum_definition.validate(_source, _context),
|
||||||
|
TypeDefinition::Struct(struct_definition) => {
|
||||||
|
struct_definition.validate(_source, _context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
fn run(&self, _source: &str, _context: &Context) -> Result<Value, RuntimeError> {
|
||||||
todo!()
|
match self {
|
||||||
|
TypeDefinition::Enum(enum_definition) => enum_definition.run(_source, _context),
|
||||||
|
TypeDefinition::Struct(struct_definition) => struct_definition.run(_source, _context),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Format for TypeDefinition {
|
impl Format for TypeDefinition {
|
||||||
fn format(&self, output: &mut String, indent_level: u8) {
|
fn format(&self, _output: &mut String, _indent_level: u8) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use std::{cmp::Ordering, collections::BTreeMap, ops::RangeInclusive};
|
use std::{cmp::Ordering, collections::BTreeMap, ops::RangeInclusive};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tree_sitter::Node as SyntaxNode;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, BuiltInValue, Context, Expression, Format, Function, FunctionNode, Identifier,
|
AbstractTree, BuiltInValue, Context, Expression, Format, Function, FunctionNode,
|
||||||
List, Map, SourcePosition, Statement, Structure, SyntaxNode, Type, TypeSpecification, Value,
|
Identifier, List, Map, SourcePosition, Statement, Structure, Type,
|
||||||
|
TypeSpecification, Value, TypeDefinition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
@ -19,8 +21,13 @@ pub enum ValueNode {
|
|||||||
Option(Option<Box<Expression>>),
|
Option(Option<Box<Expression>>),
|
||||||
Map(BTreeMap<String, (Statement, Option<Type>)>, SourcePosition),
|
Map(BTreeMap<String, (Statement, Option<Type>)>, SourcePosition),
|
||||||
BuiltInValue(BuiltInValue),
|
BuiltInValue(BuiltInValue),
|
||||||
Structure(BTreeMap<String, (Option<Statement>, Type)>),
|
|
||||||
Range(RangeInclusive<i64>),
|
Range(RangeInclusive<i64>),
|
||||||
|
Structure(BTreeMap<String, (Option<Statement>, Type)>),
|
||||||
|
Enum {
|
||||||
|
name: Identifier,
|
||||||
|
variant: Identifier,
|
||||||
|
expression: Option<Box<Expression>>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for ValueNode {
|
impl AbstractTree for ValueNode {
|
||||||
@ -167,10 +174,25 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
ValueNode::Range(start..=end)
|
ValueNode::Range(start..=end)
|
||||||
}
|
}
|
||||||
|
"enum_instance" => {
|
||||||
|
let name_node = child.child(1).unwrap();
|
||||||
|
let name = Identifier::from_syntax(name_node, source, context)?;
|
||||||
|
|
||||||
|
let variant_node = child.child(3).unwrap();
|
||||||
|
let variant = Identifier::from_syntax(variant_node, source, context)?;
|
||||||
|
|
||||||
|
let expression = if let Some(expression_node) = child.child(5) {
|
||||||
|
Some(Box::new(Expression::from_syntax(expression_node, source, context)?))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
ValueNode::Enum { name, variant , expression }
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(SyntaxError::UnexpectedSyntaxNode {
|
return Err(SyntaxError::UnexpectedSyntaxNode {
|
||||||
expected:
|
expected:
|
||||||
"string, integer, float, boolean, range, list, map, option, function or structure"
|
"string, integer, float, boolean, range, list, map, option, function, structure or enum"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
actual: child.kind().to_string(),
|
actual: child.kind().to_string(),
|
||||||
location: child.start_position(),
|
location: child.start_position(),
|
||||||
@ -229,6 +251,7 @@ impl AbstractTree for ValueNode {
|
|||||||
Type::Map(Some(Structure::new(value_map)))
|
Type::Map(Some(Structure::new(value_map)))
|
||||||
}
|
}
|
||||||
ValueNode::Range(_) => Type::Range,
|
ValueNode::Range(_) => Type::Range,
|
||||||
|
ValueNode::Enum { name, .. } => Type::Custom(name.clone()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
@ -256,7 +279,7 @@ impl AbstractTree for ValueNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -323,6 +346,30 @@ impl AbstractTree for ValueNode {
|
|||||||
Value::Structure(Structure::new(value_map))
|
Value::Structure(Structure::new(value_map))
|
||||||
}
|
}
|
||||||
ValueNode::Range(range) => Value::Range(range.clone()),
|
ValueNode::Range(range) => Value::Range(range.clone()),
|
||||||
|
ValueNode::Enum { name, variant, expression } => {
|
||||||
|
let value = if let Some(expression) = expression {
|
||||||
|
expression.run(source, context)?
|
||||||
|
} else {
|
||||||
|
Value::none()
|
||||||
|
};
|
||||||
|
let instance = if let Some(definition) = context.get_definition(name.inner())? {
|
||||||
|
if let TypeDefinition::Enum(enum_defintion) = definition {
|
||||||
|
enum_defintion.instantiate(variant.inner().clone(), value)
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::ExpectedEnumDefintion {
|
||||||
|
actual: definition.clone()
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(RuntimeError::ValidationFailure(
|
||||||
|
ValidationError::TypeDefinitionNotFound(name.inner().clone())
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
Value::Enum(instance)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
@ -407,6 +454,7 @@ impl Format for ValueNode {
|
|||||||
output.push('}');
|
output.push('}');
|
||||||
}
|
}
|
||||||
ValueNode::Range(_) => todo!(),
|
ValueNode::Range(_) => todo!(),
|
||||||
|
ValueNode::Enum { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,6 +482,29 @@ impl Ord for ValueNode {
|
|||||||
(ValueNode::BuiltInValue(_), _) => Ordering::Greater,
|
(ValueNode::BuiltInValue(_), _) => Ordering::Greater,
|
||||||
(ValueNode::Structure(left), ValueNode::Structure(right)) => left.cmp(right),
|
(ValueNode::Structure(left), ValueNode::Structure(right)) => left.cmp(right),
|
||||||
(ValueNode::Structure(_), _) => Ordering::Greater,
|
(ValueNode::Structure(_), _) => Ordering::Greater,
|
||||||
|
(
|
||||||
|
ValueNode::Enum {
|
||||||
|
name: left_name, variant: left_variant, expression: left_expression
|
||||||
|
},
|
||||||
|
ValueNode::Enum {
|
||||||
|
name: right_name, variant: right_variant, expression: right_expression
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
let name_cmp = left_name.cmp(right_name);
|
||||||
|
|
||||||
|
if name_cmp.is_eq() {
|
||||||
|
let variant_cmp = left_variant.cmp(right_variant);
|
||||||
|
|
||||||
|
if variant_cmp.is_eq() {
|
||||||
|
left_expression.cmp(right_expression)
|
||||||
|
} else {
|
||||||
|
variant_cmp
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name_cmp
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(ValueNode::Enum { .. }, _) => Ordering::Greater,
|
||||||
(ValueNode::Range(left), ValueNode::Range(right)) => left.clone().cmp(right.clone()),
|
(ValueNode::Range(left), ValueNode::Range(right)) => left.clone().cmp(right.clone()),
|
||||||
(ValueNode::Range(_), _) => Ordering::Less,
|
(ValueNode::Range(_), _) => Ordering::Less,
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use std::{
|
|||||||
sync::{Arc, RwLock, RwLockReadGuard},
|
sync::{Arc, RwLock, RwLockReadGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::rw_lock_error::RwLockError, Type, Value};
|
use crate::{error::rw_lock_error::RwLockError, Type, TypeDefinition, Value};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
@ -65,12 +65,23 @@ impl Context {
|
|||||||
match value_data {
|
match value_data {
|
||||||
ValueData::Value { inner, .. } => Ok(Some(inner.r#type())),
|
ValueData::Value { inner, .. } => Ok(Some(inner.r#type())),
|
||||||
ValueData::ExpectedType { inner, .. } => Ok(Some(inner.clone())),
|
ValueData::ExpectedType { inner, .. } => Ok(Some(inner.clone())),
|
||||||
|
ValueData::TypeDefinition(_) => todo!(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_definition(&self, key: &str) -> Result<Option<TypeDefinition>, RwLockError> {
|
||||||
|
if let Some(value_data) = self.inner.read()?.get(key) {
|
||||||
|
if let ValueData::TypeDefinition(definition) = value_data {
|
||||||
|
return Ok(Some(definition.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_value(&self, key: String, value: Value) -> Result<(), RwLockError> {
|
pub fn set_value(&self, key: String, value: Value) -> Result<(), RwLockError> {
|
||||||
self.inner.write()?.insert(
|
self.inner.write()?.insert(
|
||||||
key,
|
key,
|
||||||
@ -91,6 +102,18 @@ impl Context {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_definition(
|
||||||
|
&self,
|
||||||
|
key: String,
|
||||||
|
definition: TypeDefinition,
|
||||||
|
) -> Result<(), RwLockError> {
|
||||||
|
self.inner
|
||||||
|
.write()?
|
||||||
|
.insert(key, ValueData::TypeDefinition(definition));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unset(&self, key: &str) -> Result<(), RwLockError> {
|
pub fn unset(&self, key: &str) -> Result<(), RwLockError> {
|
||||||
self.inner.write()?.remove(key);
|
self.inner.write()?.remove(key);
|
||||||
|
|
||||||
@ -151,6 +174,7 @@ pub enum ValueData {
|
|||||||
ExpectedType {
|
ExpectedType {
|
||||||
inner: Type,
|
inner: Type,
|
||||||
},
|
},
|
||||||
|
TypeDefinition(TypeDefinition),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for ValueData {}
|
impl Eq for ValueData {}
|
||||||
@ -207,6 +231,8 @@ impl Ord for ValueData {
|
|||||||
ValueData::ExpectedType { inner: inner_left },
|
ValueData::ExpectedType { inner: inner_left },
|
||||||
ValueData::ExpectedType { inner: inner_right },
|
ValueData::ExpectedType { inner: inner_right },
|
||||||
) => inner_left.cmp(inner_right),
|
) => inner_left.cmp(inner_right),
|
||||||
|
(ValueData::TypeDefinition(left), ValueData::TypeDefinition(right)) => left.cmp(right),
|
||||||
|
(ValueData::TypeDefinition(_), _) => Greater,
|
||||||
(ValueData::ExpectedType { .. }, _) => Less,
|
(ValueData::ExpectedType { .. }, _) => Less,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::{Type, Value};
|
use crate::{Type, Value};
|
||||||
|
|
||||||
use super::rw_lock_error::RwLockError;
|
use super::{rw_lock_error::RwLockError, ValidationError};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum RuntimeError {
|
pub enum RuntimeError {
|
||||||
@ -114,6 +114,8 @@ pub enum RuntimeError {
|
|||||||
expected: usize,
|
expected: usize,
|
||||||
actual: usize,
|
actual: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ValidationFailure(ValidationError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RuntimeError {
|
impl RuntimeError {
|
||||||
|
@ -2,7 +2,7 @@ use std::fmt::{self, Display, Formatter};
|
|||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Identifier, SourcePosition, Type, Value};
|
use crate::{Identifier, SourcePosition, Type, TypeDefinition, Value};
|
||||||
|
|
||||||
use super::rw_lock_error::RwLockError;
|
use super::rw_lock_error::RwLockError;
|
||||||
|
|
||||||
@ -61,8 +61,14 @@ pub enum ValidationError {
|
|||||||
position: SourcePosition,
|
position: SourcePosition,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Failed to find a variable with a value for this key.
|
/// Failed to find a value with this key.
|
||||||
VariableIdentifierNotFound(Identifier),
|
VariableIdentifierNotFound(Identifier),
|
||||||
|
|
||||||
|
/// Failed to find a type definition with this key.
|
||||||
|
TypeDefinitionNotFound(String),
|
||||||
|
|
||||||
|
/// Failed to find a type definition with this key.
|
||||||
|
ExpectedEnumDefintion { actual: TypeDefinition },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValidationError {
|
impl ValidationError {
|
||||||
|
@ -310,6 +310,7 @@ impl Completer for DustCompleter {
|
|||||||
let value = match value_data {
|
let value = match value_data {
|
||||||
ValueData::Value { inner, .. } => inner,
|
ValueData::Value { inner, .. } => inner,
|
||||||
ValueData::ExpectedType { .. } => continue,
|
ValueData::ExpectedType { .. } => continue,
|
||||||
|
ValueData::TypeDefinition(_) => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
if key.contains(last_word) {
|
if key.contains(last_word) {
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
use crate::{Identifier, Value};
|
use crate::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
pub struct Enum {
|
pub struct EnumInstance {
|
||||||
|
name: String,
|
||||||
variant_name: String,
|
variant_name: String,
|
||||||
value: Box<Value>,
|
value: Box<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Enum {
|
impl EnumInstance {
|
||||||
pub fn new(variant_name: String, value: Value) -> Self {
|
pub fn new(name: String, variant_name: String, value: Value) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
name,
|
||||||
variant_name,
|
variant_name,
|
||||||
value: Box::new(value),
|
value: Box::new(value),
|
||||||
}
|
}
|
||||||
|
@ -16,7 +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, r#enum::Enum, structure::Structure};
|
pub use self::{
|
||||||
|
function::Function, list::List, map::Map, r#enum::EnumInstance, structure::Structure,
|
||||||
|
};
|
||||||
|
|
||||||
pub mod r#enum;
|
pub mod r#enum;
|
||||||
pub mod function;
|
pub mod function;
|
||||||
@ -41,7 +43,7 @@ pub enum Value {
|
|||||||
Range(RangeInclusive<i64>),
|
Range(RangeInclusive<i64>),
|
||||||
Option(Option<Box<Value>>),
|
Option(Option<Box<Value>>),
|
||||||
Structure(Structure),
|
Structure(Structure),
|
||||||
Enum(Enum),
|
Enum(EnumInstance),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Value {
|
impl Default for Value {
|
||||||
@ -443,8 +445,9 @@ impl PartialEq for Value {
|
|||||||
(Value::Map(left), Value::Map(right)) => left == right,
|
(Value::Map(left), Value::Map(right)) => left == right,
|
||||||
(Value::Function(left), Value::Function(right)) => left == right,
|
(Value::Function(left), Value::Function(right)) => left == right,
|
||||||
(Value::Option(left), Value::Option(right)) => left == right,
|
(Value::Option(left), Value::Option(right)) => left == right,
|
||||||
(Value::Structure(left), Value::Structure(right)) => left == right,
|
|
||||||
(Value::Range(left), Value::Range(right)) => left == right,
|
(Value::Range(left), Value::Range(right)) => left == right,
|
||||||
|
(Value::Structure(left), Value::Structure(right)) => left == right,
|
||||||
|
(Value::Enum(left), Value::Enum(right)) => left == right,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,6 +486,8 @@ impl Ord for Value {
|
|||||||
(Value::Function(_), _) => Ordering::Greater,
|
(Value::Function(_), _) => Ordering::Greater,
|
||||||
(Value::Structure(left), Value::Structure(right)) => left.cmp(right),
|
(Value::Structure(left), Value::Structure(right)) => left.cmp(right),
|
||||||
(Value::Structure(_), _) => Ordering::Greater,
|
(Value::Structure(_), _) => Ordering::Greater,
|
||||||
|
(Value::Enum(left), Value::Enum(right)) => left.cmp(right),
|
||||||
|
(Value::Enum(_), _) => Ordering::Greater,
|
||||||
(Value::Range(left), Value::Range(right)) => {
|
(Value::Range(left), Value::Range(right)) => {
|
||||||
let left_len = left.end() - left.start();
|
let left_len = left.end() - left.start();
|
||||||
let right_len = right.end() - right.start();
|
let right_len = right.end() - right.start();
|
||||||
@ -492,17 +497,6 @@ 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!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@ fn simple_enum() {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
Ok(Value::Enum(Enum::new("Foo".to_string(), Value::none())))
|
Ok(Value::Enum(EnumInstance::new(
|
||||||
|
"Foobar".to_string(),
|
||||||
|
"Foo".to_string(),
|
||||||
|
Value::none()
|
||||||
|
)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user