Add type definitions to maps

This commit is contained in:
Jeff 2023-12-20 18:29:18 -05:00
parent 8a7f05acda
commit d2dcc665bb
6 changed files with 7959 additions and 7669 deletions

View File

@ -17,7 +17,7 @@ pub enum ValueNode {
String(String), String(String),
List(Vec<Expression>), List(Vec<Expression>),
Empty, Empty,
Map(BTreeMap<String, Statement>), Map(BTreeMap<String, (Statement, Option<Type>)>),
} }
impl AbstractTree for ValueNode { impl AbstractTree for ValueNode {
@ -105,6 +105,7 @@ impl AbstractTree for ValueNode {
"map" => { "map" => {
let mut child_nodes = BTreeMap::new(); let mut child_nodes = BTreeMap::new();
let mut current_key = "".to_string(); let mut current_key = "".to_string();
let mut current_type = None;
for index in 0..child.child_count() - 1 { for index in 0..child.child_count() - 1 {
let child_syntax_node = child.child(index).unwrap(); let child_syntax_node = child.child(index).unwrap();
@ -113,14 +114,21 @@ impl AbstractTree for ValueNode {
current_key = current_key =
Identifier::from_syntax_node(source, child_syntax_node, context)? Identifier::from_syntax_node(source, child_syntax_node, context)?
.take_inner(); .take_inner();
current_type = None;
}
if child_syntax_node.kind() == "type_definition" {
current_type = Some(
TypeDefinition::from_syntax_node(source, child_syntax_node, context)?
.take_inner(),
);
} }
if child_syntax_node.kind() == "statement" { if child_syntax_node.kind() == "statement" {
let key = current_key.clone();
let statement = let statement =
Statement::from_syntax_node(source, child_syntax_node, context)?; Statement::from_syntax_node(source, child_syntax_node, context)?;
child_nodes.insert(key, statement); child_nodes.insert(current_key.clone(), (statement, current_type.clone()));
} }
} }
@ -162,10 +170,10 @@ impl AbstractTree for ValueNode {
let map = Map::new(); let map = Map::new();
{ {
for (key, statement) in key_statement_pairs { for (key, (statement, r#type)) in key_statement_pairs {
let value = statement.run(source, context)?; let value = statement.run(source, context)?;
map.set(key.clone(), value, None)?; map.set(key.clone(), value, r#type.clone())?;
} }
} }
@ -273,6 +281,25 @@ mod tests {
assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map))); assert_eq!(evaluate("{ x = 1, foo = 'bar' }"), Ok(Value::Map(map)));
} }
#[test]
fn evaluate_map_types() {
let map = Map::new();
map.set("x".to_string(), Value::Integer(1), Some(Type::Integer))
.unwrap();
map.set(
"foo".to_string(),
Value::String("bar".to_string()),
Some(Type::String),
)
.unwrap();
assert_eq!(
evaluate("{ x <int> = 1, foo <str> = 'bar' }"),
Ok(Value::Map(map))
);
}
#[test] #[test]
fn evaluate_function() { fn evaluate_function() {
let result = evaluate("(fn) <int> { 1 }"); let result = evaluate("(fn) <int> { 1 }");

View File

@ -17,6 +17,44 @@ Simple Map
(value (value
(integer))))))))) (integer)))))))))
================================================================================
Map with Types
================================================================================
{
answer <num> = 42
stuff <[str]> = [ "some" "stuff" ]
}
--------------------------------------------------------------------------------
(root
(statement
(expression
(value
(map
(identifier)
(type_definition
(type))
(statement
(expression
(value
(integer))))
(identifier)
(type_definition
(type
(type)))
(statement
(expression
(value
(list
(expression
(value
(string)))
(expression
(value
(string))))))))))))
================================================================================ ================================================================================
Nested Maps Nested Maps
================================================================================ ================================================================================

View File

@ -167,6 +167,7 @@ module.exports = grammar({
repeat( repeat(
seq( seq(
$.identifier, $.identifier,
optional($.type_definition),
'=', '=',
$.statement, $.statement,
optional(','), optional(','),

View File

@ -496,6 +496,18 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "identifier" "name": "identifier"
}, },
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "type_definition"
},
{
"type": "BLANK"
}
]
},
{ {
"type": "STRING", "type": "STRING",
"value": "=" "value": "="

View File

@ -339,6 +339,10 @@
{ {
"type": "statement", "type": "statement",
"named": true "named": true
},
{
"type": "type_definition",
"named": true
} }
] ]
} }

File diff suppressed because it is too large Load Diff