Revert changes to map type

This commit is contained in:
Jeff 2024-01-05 20:02:29 -05:00
parent ff6cc707d2
commit d4487117eb
8 changed files with 34 additions and 113 deletions

View File

@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{ use crate::{
built_in_functions::string_functions, AbstractTree, BuiltInFunction, Function, Identifier, built_in_functions::string_functions, AbstractTree, BuiltInFunction, Function, List, Map,
List, Map, Result, Type, TypeDefinition, Value, Result, Type, Value,
}; };
static ARGS: OnceLock<Value> = OnceLock::new(); static ARGS: OnceLock<Value> = OnceLock::new();
@ -31,29 +31,12 @@ impl BuiltInValue {
match self { match self {
BuiltInValue::Args => Type::list(Type::String), BuiltInValue::Args => Type::list(Type::String),
BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(), BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(),
BuiltInValue::Fs => Type::Map(Vec::new()), BuiltInValue::Fs => Type::Map,
BuiltInValue::Json => Type::Map(Vec::new()), BuiltInValue::Json => Type::Map,
BuiltInValue::Length => BuiltInFunction::Length.r#type(), BuiltInValue::Length => BuiltInFunction::Length.r#type(),
BuiltInValue::Output => BuiltInFunction::Output.r#type(), BuiltInValue::Output => BuiltInFunction::Output.r#type(),
BuiltInValue::Random => Type::Map(vec![ BuiltInValue::Random => Type::Map,
( BuiltInValue::String => Type::Map,
Identifier::new("boolean".to_string()),
TypeDefinition::new(BuiltInFunction::RandomBoolean.r#type()),
),
(
Identifier::new("float".to_string()),
TypeDefinition::new(BuiltInFunction::RandomFloat.r#type()),
),
(
Identifier::new("from".to_string()),
TypeDefinition::new(BuiltInFunction::RandomFrom.r#type()),
),
(
Identifier::new("integer".to_string()),
TypeDefinition::new(BuiltInFunction::RandomInteger.r#type()),
),
]),
BuiltInValue::String => Type::Map(Vec::new()),
} }
} }

View File

@ -46,15 +46,17 @@ impl AbstractTree for FunctionCall {
fn check_type(&self, context: &Map) -> Result<()> { fn check_type(&self, context: &Map) -> Result<()> {
let function_expression_type = self.function_expression.expected_type(context)?; let function_expression_type = self.function_expression.expected_type(context)?;
let parameter_types = if let Type::Function {
parameter_types, .. let parameter_types = match function_expression_type {
} = &function_expression_type Type::Function {
{ parameter_types, ..
parameter_types } => parameter_types,
} else { Type::Any => return Ok(()),
return Err(Error::ExpectedFunctionType { _ => {
actual: function_expression_type, return Err(Error::TypeCheckExpectedFunction {
}); actual: function_expression_type,
})
}
}; };
for (index, expression) in self.arguments.iter().enumerate() { for (index, expression) in self.arguments.iter().enumerate() {

View File

@ -92,17 +92,7 @@ impl AbstractTree for Index {
fn expected_type(&self, context: &Map) -> Result<Type> { fn expected_type(&self, context: &Map) -> Result<Type> {
match self.collection.expected_type(context)? { match self.collection.expected_type(context)? {
Type::List(item_type) => Ok(*item_type.clone()), Type::List(item_type) => Ok(*item_type.clone()),
Type::Map(identifier_types) => { Type::Map => Ok(Type::Any),
if let IndexExpression::Identifier(index_identifier) = &self.index {
for (identifier, r#type) in identifier_types {
if &identifier == index_identifier {
return Ok(r#type.take_inner());
}
}
}
Ok(Type::None)
}
Type::None => Ok(Type::None), Type::None => Ok(Type::None),
r#type => Ok(r#type), r#type => Ok(r#type),
} }

View File

@ -3,7 +3,7 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Identifier, Map, Result, Value}; use crate::{AbstractTree, Error, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct TypeDefinition { pub struct TypeDefinition {
@ -61,7 +61,7 @@ pub enum Type {
}, },
Integer, Integer,
List(Box<Type>), List(Box<Type>),
Map(Vec<(Identifier, TypeDefinition)>), Map,
None, None,
Number, Number,
String, String,
@ -92,12 +92,13 @@ impl Type {
| (Type::Collection, Type::Collection) | (Type::Collection, Type::Collection)
| (Type::Collection, Type::List(_)) | (Type::Collection, Type::List(_))
| (Type::List(_), Type::Collection) | (Type::List(_), Type::Collection)
| (Type::Collection, Type::Map(_)) | (Type::Collection, Type::Map)
| (Type::Map(_), Type::Collection) | (Type::Map, Type::Collection)
| (Type::Collection, Type::String) | (Type::Collection, Type::String)
| (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::Number, Type::Number) | (Type::Number, Type::Number)
| (Type::Number, Type::Integer) | (Type::Number, Type::Integer)
| (Type::Number, Type::Float) | (Type::Number, Type::Float)
@ -105,16 +106,6 @@ impl Type {
| (Type::Float, Type::Number) | (Type::Float, Type::Number)
| (Type::None, Type::None) | (Type::None, Type::None)
| (Type::String, Type::String) => Ok(()), | (Type::String, Type::String) => Ok(()),
(Type::Map(left), Type::Map(right)) => {
if left == right {
Ok(())
} else {
Err(Error::TypeCheck {
expected: self.clone(),
actual: other.clone(),
})
}
}
(Type::Option(left), Type::Option(right)) => { (Type::Option(left), Type::Option(right)) => {
if left == right { if left == right {
Ok(()) Ok(())
@ -224,37 +215,10 @@ impl AbstractTree for Type {
} }
} }
"int" => Type::Integer, "int" => Type::Integer,
"map" => Type::Map,
"num" => Type::Number, "num" => Type::Number,
"none" => Type::None, "none" => Type::None,
"str" => Type::String, "str" => Type::String,
"{" => {
let child_count = node.child_count();
let mut identifier_types = Vec::new();
let mut identifier = None;
for index in 1..child_count - 1 {
let child = node.child(index).unwrap();
match child.kind() {
"identifier" => {
identifier =
Some(Identifier::from_syntax_node(_source, child, _context)?);
}
"type_definition" => {
if let Some(identifier) = &identifier {
let type_definition =
TypeDefinition::from_syntax_node(_source, child, _context)?;
identifier_types.push((identifier.clone(), type_definition));
}
}
_ => {}
}
}
Type::Map(identifier_types)
}
"option" => { "option" => {
let inner_type_node = node.child(2).unwrap(); let inner_type_node = node.child(2).unwrap();
let inner_type = Type::from_syntax_node(_source, inner_type_node, _context)?; let inner_type = Type::from_syntax_node(_source, inner_type_node, _context)?;
@ -309,15 +273,7 @@ impl Display for Type {
} }
Type::Integer => write!(f, "int"), Type::Integer => write!(f, "int"),
Type::List(item_type) => write!(f, "[{item_type}]"), Type::List(item_type) => write!(f, "[{item_type}]"),
Type::Map(identifier_types) => { Type::Map => write!(f, "map"),
write!(f, "{{")?;
for (identifier, r#type) in identifier_types {
write!(f, "{} {}", identifier.inner(), r#type)?;
}
write!(f, "}}")
}
Type::Number => write!(f, "num"), Type::Number => write!(f, "num"),
Type::None => write!(f, "none"), Type::None => write!(f, "none"),
Type::String => write!(f, "str"), Type::String => write!(f, "str"),

View File

@ -203,18 +203,7 @@ impl AbstractTree for ValueNode {
Type::None Type::None
} }
} }
ValueNode::Map(statements) => { ValueNode::Map(_) => Type::Map,
let mut identifier_types = Vec::new();
for (key, (statement, _)) in statements {
identifier_types.push((
Identifier::new(key.clone()),
TypeDefinition::new(statement.expected_type(context)?),
));
}
Type::Map(identifier_types)
}
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?, ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
}; };

View File

@ -41,6 +41,10 @@ pub enum Error {
actual: Type, actual: Type,
}, },
TypeCheckExpectedFunction {
actual: Type,
},
/// The 'assert' macro did not resolve successfully. /// The 'assert' macro did not resolve successfully.
AssertEqualFailed { AssertEqualFailed {
expected: Value, expected: Value,
@ -420,6 +424,9 @@ impl fmt::Display for Error {
f, f,
"Type check error. Expected type {expected} but got type {actual}." "Type check error. Expected type {expected} but got type {actual}."
), ),
TypeCheckExpectedFunction { actual } => {
write!(f, "Type check error. Expected a function but got {actual}.")
}
WithContext { WithContext {
error, error,
location, location,

View File

@ -84,7 +84,7 @@ impl Value {
)); ));
} }
Type::Map(identifier_types) Type::Map
} }
Value::Function(function) => function.r#type().clone(), Value::Function(function) => function.r#type().clone(),
Value::String(_) => Type::String, Value::String(_) => Type::String,

View File

@ -352,12 +352,6 @@ module.exports = grammar({
'num', 'num',
'str', 'str',
seq('[', $.type, ']'), seq('[', $.type, ']'),
seq(
'{',
$.identifier,
$.type_definition,
'}',
),
seq( seq(
'(', '(',
repeat( repeat(