Implement Range value
This commit is contained in:
parent
f2e7badf4b
commit
52c6c3a507
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AbstractTree, BuiltInValue, Error, Expression, Format, Function, FunctionNode, Identifier,
|
AbstractTree, BuiltInValue, Error, Expression, Format, Function, FunctionNode, Identifier,
|
||||||
List, Map, Result, Statement, Structure, SyntaxNode, Type, TypeDefintion, TypeSpecification,
|
List, Map, Range, Result, Statement, Structure, SyntaxNode, Type, TypeDefintion,
|
||||||
Value,
|
TypeSpecification, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -20,6 +20,7 @@ pub enum ValueNode {
|
|||||||
Map(BTreeMap<String, (Statement, Option<Type>)>),
|
Map(BTreeMap<String, (Statement, Option<Type>)>),
|
||||||
BuiltInValue(BuiltInValue),
|
BuiltInValue(BuiltInValue),
|
||||||
Structure(BTreeMap<String, (Option<Statement>, Type)>),
|
Structure(BTreeMap<String, (Option<Statement>, Type)>),
|
||||||
|
Range(Range),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractTree for ValueNode {
|
impl AbstractTree for ValueNode {
|
||||||
@ -162,10 +163,20 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
ValueNode::Structure(btree_map)
|
ValueNode::Structure(btree_map)
|
||||||
}
|
}
|
||||||
|
"range" => {
|
||||||
|
let start_node = child.child(0).unwrap();
|
||||||
|
let end_node = child.child(2).unwrap();
|
||||||
|
|
||||||
|
let start = source[start_node.byte_range()].parse().unwrap();
|
||||||
|
let end = source[end_node.byte_range()].parse().unwrap();
|
||||||
|
|
||||||
|
ValueNode::Range(Range { start, end })
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::UnexpectedSyntaxNode {
|
return Err(Error::UnexpectedSyntaxNode {
|
||||||
expected: "string, integer, float, boolean, list, map, option or structure"
|
expected:
|
||||||
.to_string(),
|
"string, integer, float, boolean, range, list, map, option or structure"
|
||||||
|
.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(),
|
||||||
@ -245,6 +256,7 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
Value::TypeDefinition(TypeDefintion::Structure(Structure::new(value_map)))
|
Value::TypeDefinition(TypeDefintion::Structure(Structure::new(value_map)))
|
||||||
}
|
}
|
||||||
|
ValueNode::Range(range) => Value::Range(*range),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
@ -296,6 +308,7 @@ impl AbstractTree for ValueNode {
|
|||||||
|
|
||||||
Type::Map(Some(Structure::new(value_map)))
|
Type::Map(Some(Structure::new(value_map)))
|
||||||
}
|
}
|
||||||
|
ValueNode::Range(_) => Type::Range,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
@ -379,6 +392,7 @@ impl Format for ValueNode {
|
|||||||
|
|
||||||
output.push('}');
|
output.push('}');
|
||||||
}
|
}
|
||||||
|
ValueNode::Range(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,10 @@ impl Value {
|
|||||||
Value::String(string.into())
|
Value::String(string.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn range(start: i64, end: i64) -> Self {
|
||||||
|
Value::Range(Range { start, end })
|
||||||
|
}
|
||||||
|
|
||||||
pub fn r#type(&self) -> Type {
|
pub fn r#type(&self) -> Type {
|
||||||
match self {
|
match self {
|
||||||
Value::List(list) => {
|
Value::List(list) => {
|
||||||
@ -440,6 +444,7 @@ impl PartialEq for Value {
|
|||||||
(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::TypeDefinition(left), Value::TypeDefinition(right)) => left == right,
|
(Value::TypeDefinition(left), Value::TypeDefinition(right)) => left == right,
|
||||||
|
(Value::Range(left), Value::Range(right)) => left == right,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
start: i64,
|
pub start: i64,
|
||||||
end: i64,
|
pub end: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Range {
|
impl Display for Range {
|
||||||
|
@ -116,3 +116,10 @@ fn option() {
|
|||||||
|
|
||||||
assert_eq!(Value::Option(Some(Box::new(Value::Integer(1)))), result);
|
assert_eq!(Value::Option(Some(Box::new(Value::Integer(1)))), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn range() {
|
||||||
|
let result = interpret("0..100");
|
||||||
|
|
||||||
|
assert_eq!(Ok(Value::range(0, 100)), result);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user