Implement Option and None value types
This commit is contained in:
parent
8369477346
commit
2bcb5f59f7
@ -1,4 +1,4 @@
|
||||
create_random_numbers = (fn count <int>) <any> {
|
||||
create_random_numbers = (fn count <int>) <none> {
|
||||
numbers = []
|
||||
|
||||
while (length numbers) < count {
|
||||
|
@ -151,7 +151,7 @@ impl AbstractTree for Assignment {
|
||||
}
|
||||
|
||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
||||
Ok(Type::Empty)
|
||||
Ok(Type::None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,6 @@ impl AbstractTree for For {
|
||||
}
|
||||
|
||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
||||
Ok(Type::Empty)
|
||||
Ok(Type::None)
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ impl AbstractTree for Identifier {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Type::Empty)
|
||||
Ok(Type::None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ impl AbstractTree for Index {
|
||||
match self.collection.expected_type(context)? {
|
||||
Type::List(item_type) => Ok(*item_type.clone()),
|
||||
Type::Map => Ok(Type::Any),
|
||||
Type::Empty => Ok(Type::Empty),
|
||||
Type::None => Ok(Type::None),
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,6 @@ impl AbstractTree for IndexAssignment {
|
||||
}
|
||||
|
||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
||||
Ok(Type::Empty)
|
||||
Ok(Type::None)
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,6 @@ impl Display for TypeDefinition {
|
||||
pub enum Type {
|
||||
Any,
|
||||
Boolean,
|
||||
Empty,
|
||||
Float,
|
||||
Function {
|
||||
parameter_types: Vec<Type>,
|
||||
@ -62,9 +61,10 @@ pub enum Type {
|
||||
Integer,
|
||||
List(Box<Type>),
|
||||
Map,
|
||||
None,
|
||||
Number,
|
||||
String,
|
||||
Option(Option<Box<Type>>),
|
||||
Option(Box<Type>),
|
||||
}
|
||||
|
||||
impl Type {
|
||||
@ -73,7 +73,6 @@ impl Type {
|
||||
(Type::Any, _)
|
||||
| (_, Type::Any)
|
||||
| (Type::Boolean, Type::Boolean)
|
||||
| (Type::Empty, Type::Empty)
|
||||
| (Type::Float, Type::Float)
|
||||
| (Type::Integer, Type::Integer)
|
||||
| (Type::Map, Type::Map)
|
||||
@ -82,6 +81,7 @@ impl Type {
|
||||
| (Type::Number, Type::Float)
|
||||
| (Type::Integer, Type::Number)
|
||||
| (Type::Float, Type::Number)
|
||||
| (Type::None, Type::None)
|
||||
| (Type::String, Type::String) => Ok(()),
|
||||
(Type::Option(left), Type::Option(right)) => {
|
||||
if left == right {
|
||||
@ -177,7 +177,7 @@ impl AbstractTree for Type {
|
||||
let return_type = if final_node.is_named() {
|
||||
Type::from_syntax_node(source, final_node, context)?
|
||||
} else {
|
||||
Type::Empty
|
||||
Type::None
|
||||
};
|
||||
|
||||
Type::Function {
|
||||
@ -188,12 +188,13 @@ impl AbstractTree for Type {
|
||||
"int" => Type::Integer,
|
||||
"map" => Type::Map,
|
||||
"num" => Type::Number,
|
||||
"none" => Type::None,
|
||||
"str" => Type::String,
|
||||
"option" => {
|
||||
let inner_type_node = node.child(2).unwrap();
|
||||
let inner_type = Type::from_syntax_node(source, inner_type_node, context)?;
|
||||
|
||||
Type::Option(Some(Box::new(inner_type)))
|
||||
Type::Option(Box::new(inner_type))
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::UnexpectedSyntaxNode {
|
||||
@ -213,7 +214,7 @@ impl AbstractTree for Type {
|
||||
}
|
||||
|
||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
||||
Ok(Type::Empty)
|
||||
Ok(Type::None)
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +223,6 @@ impl Display for Type {
|
||||
match self {
|
||||
Type::Any => write!(f, "any"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Empty => write!(f, "empty"),
|
||||
Type::Float => write!(f, "float"),
|
||||
Type::Function {
|
||||
parameter_types,
|
||||
@ -245,13 +245,10 @@ impl Display for Type {
|
||||
Type::List(item_type) => write!(f, "[{item_type}]"),
|
||||
Type::Map => write!(f, "map"),
|
||||
Type::Number => write!(f, "num"),
|
||||
Type::None => write!(f, "none"),
|
||||
Type::String => write!(f, "str"),
|
||||
Type::Option(option) => {
|
||||
if let Some(r#type) = option {
|
||||
write!(f, "some({})", r#type)
|
||||
} else {
|
||||
write!(f, "none")
|
||||
}
|
||||
Type::Option(inner_type) => {
|
||||
write!(f, "option({})", inner_type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,9 +234,9 @@ impl AbstractTree for ValueNode {
|
||||
}
|
||||
ValueNode::Option(option) => {
|
||||
if let Some(expression) = option {
|
||||
Type::Option(Some(Box::new(expression.expected_type(context)?)))
|
||||
Type::Option(Box::new(expression.expected_type(context)?))
|
||||
} else {
|
||||
Type::Option(None)
|
||||
Type::None
|
||||
}
|
||||
}
|
||||
ValueNode::Map(_) => Type::Map,
|
||||
|
@ -20,7 +20,7 @@ impl BuiltInFunction for Assert {
|
||||
fn r#type(&self) -> Type {
|
||||
Type::Function {
|
||||
parameter_types: vec![Type::Any],
|
||||
return_type: Box::new(Type::Empty),
|
||||
return_type: Box::new(Type::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ impl BuiltInFunction for Write {
|
||||
fn r#type(&self) -> Type {
|
||||
Type::Function {
|
||||
parameter_types: vec![Type::String],
|
||||
return_type: Box::new(Type::Empty),
|
||||
return_type: Box::new(Type::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +105,7 @@ impl BuiltInFunction for Append {
|
||||
fn r#type(&self) -> Type {
|
||||
Type::Function {
|
||||
parameter_types: vec![Type::String, Type::String],
|
||||
return_type: Box::new(Type::Empty),
|
||||
return_type: Box::new(Type::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ impl BuiltInFunction for Output {
|
||||
fn r#type(&self) -> Type {
|
||||
Type::Function {
|
||||
parameter_types: vec![Type::Any],
|
||||
return_type: Box::new(Type::Empty),
|
||||
return_type: Box::new(Type::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ impl BuiltInFunction for InstallPackages {
|
||||
fn r#type(&self) -> Type {
|
||||
Type::Function {
|
||||
parameter_types: vec![Type::List(Box::new(Type::String))],
|
||||
return_type: Box::new(Type::Empty),
|
||||
return_type: Box::new(Type::None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,9 +77,9 @@ impl Value {
|
||||
Value::Boolean(_) => Type::Boolean,
|
||||
Value::Option(option) => {
|
||||
if let Some(value) = option {
|
||||
Type::Option(Some(Box::new(value.r#type())))
|
||||
Type::Option(Box::new(value.r#type()))
|
||||
} else {
|
||||
Type::Option(None)
|
||||
Type::None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -346,6 +346,7 @@ module.exports = grammar({
|
||||
'float',
|
||||
'int',
|
||||
'map',
|
||||
'none',
|
||||
'num',
|
||||
'str',
|
||||
seq('[', $.type, ']'),
|
||||
|
@ -1104,6 +1104,10 @@
|
||||
"type": "STRING",
|
||||
"value": "map"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "none"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "num"
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user