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 = []
|
numbers = []
|
||||||
|
|
||||||
while (length numbers) < count {
|
while (length numbers) < count {
|
||||||
|
@ -151,7 +151,7 @@ impl AbstractTree for Assignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
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> {
|
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)? {
|
match self.collection.expected_type(context)? {
|
||||||
Type::List(item_type) => Ok(*item_type.clone()),
|
Type::List(item_type) => Ok(*item_type.clone()),
|
||||||
Type::Map => Ok(Type::Any),
|
Type::Map => Ok(Type::Any),
|
||||||
Type::Empty => Ok(Type::Empty),
|
Type::None => Ok(Type::None),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,6 @@ impl AbstractTree for IndexAssignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<Type> {
|
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 {
|
pub enum Type {
|
||||||
Any,
|
Any,
|
||||||
Boolean,
|
Boolean,
|
||||||
Empty,
|
|
||||||
Float,
|
Float,
|
||||||
Function {
|
Function {
|
||||||
parameter_types: Vec<Type>,
|
parameter_types: Vec<Type>,
|
||||||
@ -62,9 +61,10 @@ pub enum Type {
|
|||||||
Integer,
|
Integer,
|
||||||
List(Box<Type>),
|
List(Box<Type>),
|
||||||
Map,
|
Map,
|
||||||
|
None,
|
||||||
Number,
|
Number,
|
||||||
String,
|
String,
|
||||||
Option(Option<Box<Type>>),
|
Option(Box<Type>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
@ -73,7 +73,6 @@ impl Type {
|
|||||||
(Type::Any, _)
|
(Type::Any, _)
|
||||||
| (_, Type::Any)
|
| (_, Type::Any)
|
||||||
| (Type::Boolean, Type::Boolean)
|
| (Type::Boolean, Type::Boolean)
|
||||||
| (Type::Empty, Type::Empty)
|
|
||||||
| (Type::Float, Type::Float)
|
| (Type::Float, Type::Float)
|
||||||
| (Type::Integer, Type::Integer)
|
| (Type::Integer, Type::Integer)
|
||||||
| (Type::Map, Type::Map)
|
| (Type::Map, Type::Map)
|
||||||
@ -82,6 +81,7 @@ impl Type {
|
|||||||
| (Type::Number, Type::Float)
|
| (Type::Number, Type::Float)
|
||||||
| (Type::Integer, Type::Number)
|
| (Type::Integer, Type::Number)
|
||||||
| (Type::Float, Type::Number)
|
| (Type::Float, Type::Number)
|
||||||
|
| (Type::None, Type::None)
|
||||||
| (Type::String, Type::String) => Ok(()),
|
| (Type::String, Type::String) => Ok(()),
|
||||||
(Type::Option(left), Type::Option(right)) => {
|
(Type::Option(left), Type::Option(right)) => {
|
||||||
if left == right {
|
if left == right {
|
||||||
@ -177,7 +177,7 @@ impl AbstractTree for Type {
|
|||||||
let return_type = if final_node.is_named() {
|
let return_type = if final_node.is_named() {
|
||||||
Type::from_syntax_node(source, final_node, context)?
|
Type::from_syntax_node(source, final_node, context)?
|
||||||
} else {
|
} else {
|
||||||
Type::Empty
|
Type::None
|
||||||
};
|
};
|
||||||
|
|
||||||
Type::Function {
|
Type::Function {
|
||||||
@ -188,12 +188,13 @@ impl AbstractTree for Type {
|
|||||||
"int" => Type::Integer,
|
"int" => Type::Integer,
|
||||||
"map" => Type::Map,
|
"map" => Type::Map,
|
||||||
"num" => Type::Number,
|
"num" => Type::Number,
|
||||||
|
"none" => Type::None,
|
||||||
"str" => Type::String,
|
"str" => Type::String,
|
||||||
"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)?;
|
||||||
|
|
||||||
Type::Option(Some(Box::new(inner_type)))
|
Type::Option(Box::new(inner_type))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::UnexpectedSyntaxNode {
|
return Err(Error::UnexpectedSyntaxNode {
|
||||||
@ -213,7 +214,7 @@ impl AbstractTree for Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn expected_type(&self, _context: &Map) -> Result<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 {
|
match self {
|
||||||
Type::Any => write!(f, "any"),
|
Type::Any => write!(f, "any"),
|
||||||
Type::Boolean => write!(f, "bool"),
|
Type::Boolean => write!(f, "bool"),
|
||||||
Type::Empty => write!(f, "empty"),
|
|
||||||
Type::Float => write!(f, "float"),
|
Type::Float => write!(f, "float"),
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types,
|
parameter_types,
|
||||||
@ -245,13 +245,10 @@ impl Display for Type {
|
|||||||
Type::List(item_type) => write!(f, "[{item_type}]"),
|
Type::List(item_type) => write!(f, "[{item_type}]"),
|
||||||
Type::Map => write!(f, "map"),
|
Type::Map => write!(f, "map"),
|
||||||
Type::Number => write!(f, "num"),
|
Type::Number => write!(f, "num"),
|
||||||
|
Type::None => write!(f, "none"),
|
||||||
Type::String => write!(f, "str"),
|
Type::String => write!(f, "str"),
|
||||||
Type::Option(option) => {
|
Type::Option(inner_type) => {
|
||||||
if let Some(r#type) = option {
|
write!(f, "option({})", inner_type)
|
||||||
write!(f, "some({})", r#type)
|
|
||||||
} else {
|
|
||||||
write!(f, "none")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,9 +234,9 @@ impl AbstractTree for ValueNode {
|
|||||||
}
|
}
|
||||||
ValueNode::Option(option) => {
|
ValueNode::Option(option) => {
|
||||||
if let Some(expression) = option {
|
if let Some(expression) = option {
|
||||||
Type::Option(Some(Box::new(expression.expected_type(context)?)))
|
Type::Option(Box::new(expression.expected_type(context)?))
|
||||||
} else {
|
} else {
|
||||||
Type::Option(None)
|
Type::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueNode::Map(_) => Type::Map,
|
ValueNode::Map(_) => Type::Map,
|
||||||
|
@ -20,7 +20,7 @@ impl BuiltInFunction for Assert {
|
|||||||
fn r#type(&self) -> Type {
|
fn r#type(&self) -> Type {
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types: vec![Type::Any],
|
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 {
|
fn r#type(&self) -> Type {
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types: vec![Type::String],
|
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 {
|
fn r#type(&self) -> Type {
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types: vec![Type::String, Type::String],
|
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 {
|
fn r#type(&self) -> Type {
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types: vec![Type::Any],
|
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 {
|
fn r#type(&self) -> Type {
|
||||||
Type::Function {
|
Type::Function {
|
||||||
parameter_types: vec![Type::List(Box::new(Type::String))],
|
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::Boolean(_) => Type::Boolean,
|
||||||
Value::Option(option) => {
|
Value::Option(option) => {
|
||||||
if let Some(value) = option {
|
if let Some(value) = option {
|
||||||
Type::Option(Some(Box::new(value.r#type())))
|
Type::Option(Box::new(value.r#type()))
|
||||||
} else {
|
} else {
|
||||||
Type::Option(None)
|
Type::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -346,6 +346,7 @@ module.exports = grammar({
|
|||||||
'float',
|
'float',
|
||||||
'int',
|
'int',
|
||||||
'map',
|
'map',
|
||||||
|
'none',
|
||||||
'num',
|
'num',
|
||||||
'str',
|
'str',
|
||||||
seq('[', $.type, ']'),
|
seq('[', $.type, ']'),
|
||||||
|
@ -1104,6 +1104,10 @@
|
|||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": "map"
|
"value": "map"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "none"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
"value": "num"
|
"value": "num"
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user