Add type definitions as a first-class value

This commit is contained in:
Jeff 2024-01-23 15:20:19 -05:00
parent ed6e4cfd1a
commit 6c4efadb10
10 changed files with 13818 additions and 13373 deletions

View File

@ -4,7 +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, TypeSpecification, Value, List, Map, Result, Statement, Structure, SyntaxNode, Type, TypeDefintion, TypeSpecification,
Value,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -18,7 +19,7 @@ pub enum ValueNode {
Option(Option<Box<Expression>>), Option(Option<Box<Expression>>),
Map(BTreeMap<String, (Statement, Option<Type>)>), Map(BTreeMap<String, (Statement, Option<Type>)>),
BuiltInValue(BuiltInValue), BuiltInValue(BuiltInValue),
Structure(BTreeMap<String, (Option<Statement>, Type)>), StructureDefinition(BTreeMap<String, (Option<Statement>, Type)>),
} }
impl AbstractTree for ValueNode { impl AbstractTree for ValueNode {
@ -159,7 +160,7 @@ impl AbstractTree for ValueNode {
} }
} }
ValueNode::Structure(btree_map) ValueNode::StructureDefinition(btree_map)
} }
_ => { _ => {
return Err(Error::UnexpectedSyntaxNode { return Err(Error::UnexpectedSyntaxNode {
@ -229,7 +230,7 @@ impl AbstractTree for ValueNode {
Value::Map(map) Value::Map(map)
} }
ValueNode::BuiltInValue(built_in_value) => built_in_value.run(source, context)?, ValueNode::BuiltInValue(built_in_value) => built_in_value.run(source, context)?,
ValueNode::Structure(node_map) => { ValueNode::StructureDefinition(node_map) => {
let mut value_map = BTreeMap::new(); let mut value_map = BTreeMap::new();
for (key, (statement_option, r#type)) in node_map { for (key, (statement_option, r#type)) in node_map {
@ -242,7 +243,7 @@ impl AbstractTree for ValueNode {
value_map.insert(key.to_string(), (value_option, r#type.clone())); value_map.insert(key.to_string(), (value_option, r#type.clone()));
} }
Value::Structure(Structure::new(value_map)) Value::TypeDefinition(TypeDefintion::Structure(Structure::new(value_map)))
} }
}; };
@ -286,7 +287,7 @@ impl AbstractTree for ValueNode {
} }
ValueNode::Map(_) => Type::Map(None), ValueNode::Map(_) => Type::Map(None),
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?, ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
ValueNode::Structure(node_map) => { ValueNode::StructureDefinition(node_map) => {
let mut value_map = BTreeMap::new(); let mut value_map = BTreeMap::new();
for (key, (_statement_option, r#type)) in node_map { for (key, (_statement_option, r#type)) in node_map {
@ -356,7 +357,7 @@ impl Format for ValueNode {
output.push('}'); output.push('}');
} }
ValueNode::BuiltInValue(built_in_value) => built_in_value.format(output, indent_level), ValueNode::BuiltInValue(built_in_value) => built_in_value.format(output, indent_level),
ValueNode::Structure(nodes) => { ValueNode::StructureDefinition(nodes) => {
output.push('{'); output.push('{');
for (key, (value_option, r#type)) in nodes { for (key, (value_option, r#type)) in nodes {

View File

@ -8,7 +8,10 @@ pub use crate::{
built_in_functions::BuiltInFunction, built_in_functions::BuiltInFunction,
error::*, error::*,
interpret::*, interpret::*,
value::{function::Function, list::List, map::Map, structure::Structure, Value}, value::{
function::Function, list::List, map::Map, structure::Structure,
type_definition::TypeDefintion, Value,
},
}; };
pub use tree_sitter::Node as SyntaxNode; pub use tree_sitter::Node as SyntaxNode;

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values. //! Types that represent runtime values.
use crate::{ use crate::{
error::{Error, Result}, error::{Error, Result},
Function, Identifier, List, Map, Structure, Type, TypeSpecification, Function, Identifier, List, Map, Type, TypeDefintion, TypeSpecification,
}; };
use serde::{ use serde::{
@ -22,6 +22,7 @@ pub mod function;
pub mod list; pub mod list;
pub mod map; pub mod map;
pub mod structure; pub mod structure;
pub mod type_definition;
/// Dust value representation. /// Dust value representation.
/// ///
@ -38,7 +39,7 @@ pub enum Value {
Integer(i64), Integer(i64),
Boolean(bool), Boolean(bool),
Option(Option<Box<Value>>), Option(Option<Box<Value>>),
Structure(Structure), TypeDefinition(TypeDefintion),
} }
impl Default for Value { impl Default for Value {
@ -99,7 +100,7 @@ impl Value {
Type::None Type::None
} }
} }
Value::Structure(_) => todo!(), Value::TypeDefinition(_) => todo!(),
}; };
r#type r#type
@ -432,7 +433,7 @@ impl PartialEq for Value {
(Value::Map(left), Value::Map(right)) => left == right, (Value::Map(left), Value::Map(right)) => left == right,
(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::Structure(left), Value::Structure(right)) => left == right, (Value::TypeDefinition(left), Value::TypeDefinition(right)) => left == right,
_ => false, _ => false,
} }
} }
@ -469,8 +470,8 @@ impl Ord for Value {
(Value::Map(_), _) => Ordering::Greater, (Value::Map(_), _) => Ordering::Greater,
(Value::Function(left), Value::Function(right)) => left.cmp(right), (Value::Function(left), Value::Function(right)) => left.cmp(right),
(Value::Function(_), _) => Ordering::Greater, (Value::Function(_), _) => Ordering::Greater,
(Value::Structure(left), Value::Structure(right)) => left.cmp(right), (Value::TypeDefinition(left), Value::TypeDefinition(right)) => left.cmp(right),
(Value::Structure(_), _) => Ordering::Greater, (Value::TypeDefinition(_), _) => Ordering::Greater,
(Value::Option(left), Value::Option(right)) => left.cmp(right), (Value::Option(left), Value::Option(right)) => left.cmp(right),
(Value::Option(_), _) => Ordering::Less, (Value::Option(_), _) => Ordering::Less,
} }
@ -500,7 +501,7 @@ impl Serialize for Value {
Value::Option(inner) => inner.serialize(serializer), Value::Option(inner) => inner.serialize(serializer),
Value::Map(inner) => inner.serialize(serializer), Value::Map(inner) => inner.serialize(serializer),
Value::Function(inner) => inner.serialize(serializer), Value::Function(inner) => inner.serialize(serializer),
Value::Structure(inner) => inner.serialize(serializer), Value::TypeDefinition(inner) => inner.serialize(serializer),
} }
} }
} }
@ -522,7 +523,7 @@ impl Display for Value {
Value::List(list) => write!(f, "{list}"), Value::List(list) => write!(f, "{list}"),
Value::Map(map) => write!(f, "{map}"), Value::Map(map) => write!(f, "{map}"),
Value::Function(function) => write!(f, "{function}"), Value::Function(function) => write!(f, "{function}"),
Value::Structure(structure) => write!(f, "{structure}"), Value::TypeDefinition(structure) => write!(f, "{structure}"),
} }
} }
} }

View File

@ -0,0 +1,16 @@
use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use crate::Structure;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum TypeDefintion {
Structure(Structure),
}
impl Display for TypeDefintion {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{self}")
}
}

View File

@ -10,5 +10,9 @@ fn simple_structure() {
btree_map.insert("x".to_string(), (Some(Value::Integer(0)), Type::Integer)); btree_map.insert("x".to_string(), (Some(Value::Integer(0)), Type::Integer));
assert_eq!(Ok(Value::Structure(Structure::new(btree_map))), result); let expected = Ok(Value::TypeDefinition(TypeDefintion::Structure(
Structure::new(btree_map),
)));
assert_eq!(expected, result);
} }

View File

@ -13,13 +13,14 @@ struct {
(statement (statement
(expression (expression
(value (value
(type_definition
(structure (structure
(identifier) (identifier)
(type_specification (type_specification
(type)) (type))
(identifier) (identifier)
(type_specification (type_specification
(type))))))) (type))))))))
================================================================================ ================================================================================
Complex Structure Complex Structure
@ -44,6 +45,7 @@ Foo = struct {
(statement (statement
(expression (expression
(value (value
(type_definition
(structure (structure
(identifier) (identifier)
(type_specification (type_specification
@ -67,4 +69,4 @@ Foo = struct {
(statement (statement
(expression (expression
(value (value
(integer)))))))))))))) (integer)))))))))))))))

View File

@ -85,6 +85,11 @@ module.exports = grammar({
$.map, $.map,
$.option, $.option,
$.built_in_value, $.built_in_value,
$.type_definition,
),
type_definition: $ =>
choice(
$.structure, $.structure,
), ),

View File

@ -249,6 +249,15 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "built_in_value" "name": "built_in_value"
}, },
{
"type": "SYMBOL",
"name": "type_definition"
}
]
},
"type_definition": {
"type": "CHOICE",
"members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "structure" "name": "structure"

View File

@ -602,6 +602,21 @@
] ]
} }
}, },
{
"type": "type_definition",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "structure",
"named": true
}
]
}
},
{ {
"type": "type_specification", "type": "type_specification",
"named": true, "named": true,
@ -662,7 +677,7 @@
"named": true "named": true
}, },
{ {
"type": "structure", "type": "type_definition",
"named": true "named": true
} }
] ]

File diff suppressed because it is too large Load Diff