Implement specific map types
This commit is contained in:
parent
52027db6c3
commit
3a63d4973d
@ -58,6 +58,10 @@ impl AbstractTree for MapNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
|
||||||
|
if self.properties.is_empty() {
|
||||||
|
return Ok(Type::Map(None));
|
||||||
|
}
|
||||||
|
|
||||||
let mut type_map = BTreeMap::new();
|
let mut type_map = BTreeMap::new();
|
||||||
|
|
||||||
for (identifier, (statement, r#type_option)) in &self.properties {
|
for (identifier, (statement, r#type_option)) in &self.properties {
|
||||||
|
@ -9,7 +9,7 @@ use tree_sitter::Node as SyntaxNode;
|
|||||||
use crate::{
|
use crate::{
|
||||||
built_in_types::BuiltInType,
|
built_in_types::BuiltInType,
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Context, Format, Identifier, Value,
|
AbstractTree, Context, Format, Identifier, TypeSpecification, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -78,7 +78,7 @@ impl Type {
|
|||||||
| (Type::String, Type::Collection)
|
| (Type::String, Type::Collection)
|
||||||
| (Type::Float, Type::Float)
|
| (Type::Float, Type::Float)
|
||||||
| (Type::Integer, Type::Integer)
|
| (Type::Integer, Type::Integer)
|
||||||
| (Type::Map(_), Type::Map(_))
|
| (Type::Map(None), Type::Map(None))
|
||||||
| (Type::Number, Type::Number)
|
| (Type::Number, Type::Number)
|
||||||
| (Type::Number, Type::Integer)
|
| (Type::Number, Type::Integer)
|
||||||
| (Type::Number, Type::Float)
|
| (Type::Number, Type::Float)
|
||||||
@ -86,6 +86,7 @@ impl Type {
|
|||||||
| (Type::Float, Type::Number)
|
| (Type::Float, Type::Number)
|
||||||
| (Type::String, Type::String)
|
| (Type::String, Type::String)
|
||||||
| (Type::None, Type::None) => true,
|
| (Type::None, Type::None) => true,
|
||||||
|
(Type::Map(left_types), Type::Map(right_types)) => left_types == right_types,
|
||||||
(
|
(
|
||||||
Type::Custom {
|
Type::Custom {
|
||||||
name: left_name,
|
name: left_name,
|
||||||
@ -165,6 +166,27 @@ impl AbstractTree for Type {
|
|||||||
|
|
||||||
Type::custom(name, argument)
|
Type::custom(name, argument)
|
||||||
}
|
}
|
||||||
|
"{" => {
|
||||||
|
let mut type_map = BTreeMap::new();
|
||||||
|
let mut previous_identifier = None;
|
||||||
|
|
||||||
|
for index in 1..node.child_count() - 1 {
|
||||||
|
let child = node.child(index).unwrap();
|
||||||
|
|
||||||
|
if let Some(identifier) = previous_identifier {
|
||||||
|
let type_specification =
|
||||||
|
TypeSpecification::from_syntax(child, _source, context)?;
|
||||||
|
|
||||||
|
type_map.insert(identifier, type_specification.take_inner());
|
||||||
|
previous_identifier = None;
|
||||||
|
} else {
|
||||||
|
previous_identifier =
|
||||||
|
Some(Identifier::from_syntax(child, _source, context)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Map(Some(type_map))
|
||||||
|
}
|
||||||
"[" => {
|
"[" => {
|
||||||
let item_type_node = node.child(1).unwrap();
|
let item_type_node = node.child(1).unwrap();
|
||||||
let item_type = Type::from_syntax(item_type_node, _source, context)?;
|
let item_type = Type::from_syntax(item_type_node, _source, context)?;
|
||||||
|
@ -77,7 +77,18 @@ impl From<RwLockError> for SyntaxError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SyntaxError {
|
impl Display for SyntaxError {
|
||||||
fn fmt(&self, _f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
todo!()
|
match self {
|
||||||
|
SyntaxError::InvalidSource { position } => write!(f, "Invalid syntax at {position:?}."),
|
||||||
|
SyntaxError::RwLock(_) => todo!(),
|
||||||
|
SyntaxError::UnexpectedSyntaxNode {
|
||||||
|
expected,
|
||||||
|
actual,
|
||||||
|
position,
|
||||||
|
} => write!(
|
||||||
|
f,
|
||||||
|
"Unexpected syntax node. Expected {expected} but got {actual} at {position:?}."
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,13 +95,17 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Map(map) => {
|
Value::Map(map) => {
|
||||||
let mut type_map = BTreeMap::new();
|
if map.inner().is_empty() {
|
||||||
|
Type::Map(None)
|
||||||
|
} else {
|
||||||
|
let mut type_map = BTreeMap::new();
|
||||||
|
|
||||||
for (identifier, value) in map.inner() {
|
for (identifier, value) in map.inner() {
|
||||||
type_map.insert(identifier.clone(), value.r#type()?);
|
type_map.insert(identifier.clone(), value.r#type()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Map(Some(type_map))
|
||||||
}
|
}
|
||||||
|
|
||||||
Type::Map(Some(type_map))
|
|
||||||
}
|
}
|
||||||
Value::Function(function) => function.r#type().clone(),
|
Value::Function(function) => function.r#type().clone(),
|
||||||
Value::String(_) => Type::String,
|
Value::String(_) => Type::String,
|
||||||
|
@ -6,3 +6,25 @@ x <{ y <int> }> = { y = 2 }
|
|||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(root
|
||||||
|
(statement
|
||||||
|
(statement_kind
|
||||||
|
(assignment
|
||||||
|
(identifier)
|
||||||
|
(type_specification
|
||||||
|
(type
|
||||||
|
(identifier)
|
||||||
|
(type_specification
|
||||||
|
(type))))
|
||||||
|
(assignment_operator)
|
||||||
|
(statement
|
||||||
|
(statement_kind
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(map
|
||||||
|
(identifier)
|
||||||
|
(statement
|
||||||
|
(statement_kind
|
||||||
|
(expression
|
||||||
|
(value
|
||||||
|
(integer))))))))))))))
|
||||||
|
@ -356,7 +356,6 @@ module.exports = grammar({
|
|||||||
'int',
|
'int',
|
||||||
'map',
|
'map',
|
||||||
seq(
|
seq(
|
||||||
'map',
|
|
||||||
'{',
|
'{',
|
||||||
repeat1(
|
repeat1(
|
||||||
seq(
|
seq(
|
||||||
|
@ -1079,10 +1079,6 @@
|
|||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
{
|
|
||||||
"type": "STRING",
|
|
||||||
"value": "map"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": "{"
|
"value": "{"
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user