diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 18:33:20 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-28 18:33:20 +0200 |
commit | 384878703dd1fb97a3d3d60e56e12edb5234ad95 (patch) | |
tree | 75c457dffac419f9976906aa4fd20ce1e2ff5cd4 | |
parent | f24dabd0897e802d30e8b652f0b633b84c78865b (diff) | |
download | rebel-384878703dd1fb97a3d3d60e56e12edb5234ad95.tar rebel-384878703dd1fb97a3d3d60e56e12edb5234ad95.zip |
rebel-parse, rebel-lang: rename Map types to Struct
As fields can have different types, calling this a struct is more
appropriate, and it frees up the Map name for actual maps that support
dynamic lookup and iteration.
-rw-r--r-- | crates/rebel-lang/src/typing.rs | 42 | ||||
-rw-r--r-- | crates/rebel-lang/src/value.rs | 22 | ||||
-rw-r--r-- | crates/rebel-parse/src/ast.rs | 8 | ||||
-rw-r--r-- | crates/rebel-parse/src/grammar/recipe.rs | 8 |
4 files changed, 43 insertions, 37 deletions
diff --git a/crates/rebel-lang/src/typing.rs b/crates/rebel-lang/src/typing.rs index 1455732..94c84ba 100644 --- a/crates/rebel-lang/src/typing.rs +++ b/crates/rebel-lang/src/typing.rs @@ -29,7 +29,7 @@ pub enum Type { Str, Tuple(Vec<Type>), Array(Box<Type>, ArrayLen), - Map(HashMap<String, Type>), + Struct(HashMap<String, Type>), Fn(Box<FuncType>), } @@ -60,19 +60,21 @@ impl Type { Box::new(self_inner.unify(*other_inner, coerce)?), ArrayLen::unify(self_len, other_len, coerce)?, ), - (Map(self_entries), Map(mut other_entries)) => { + (Struct(self_entries), Struct(mut other_entries)) => { if self_entries.len() != other_entries.len() { return Err(TypeError); } - Map(self_entries - .into_iter() - .map(|(k, v)| { - let Some(v2) = other_entries.remove(&k) else { - return Err(TypeError); - }; - Ok((k, v.unify(v2, coerce)?)) - }) - .collect::<Result<_>>()?) + Struct( + self_entries + .into_iter() + .map(|(k, v)| { + let Some(v2) = other_entries.remove(&k) else { + return Err(TypeError); + }; + Ok((k, v.unify(v2, coerce)?)) + }) + .collect::<Result<_>>()?, + ) } _ => return Err(TypeError), }) @@ -247,7 +249,7 @@ impl Type { let index: usize = name.parse().or(Err(TypeError))?; elems.into_iter().nth(index).ok_or(TypeError)? } - Map(mut entries) => entries.remove(name).ok_or(TypeError)?, + Struct(mut entries) => entries.remove(name).ok_or(TypeError)?, _ => return Err(TypeError), }) } @@ -308,12 +310,14 @@ impl Type { })?), ArrayLen::Fixed(elems.len()), ), - Literal::Map(entries) => Map(entries - .iter() - .map(|ast::MapEntry { key, value }| { - Ok(((*key).to_owned(), Self::ast_expr_type(ctx, value)?)) - }) - .collect::<Result<_>>()?), + Literal::Struct(entries) => Struct( + entries + .iter() + .map(|ast::StructField { key, value }| { + Ok(((*key).to_owned(), Self::ast_expr_type(ctx, value)?)) + }) + .collect::<Result<_>>()?, + ), }) } } @@ -342,7 +346,7 @@ impl Display for Type { f.write_str(")") } Type::Array(typ, len) => write!(f, "[{typ}{len}]"), - Type::Map(entries) => { + Type::Struct(entries) => { let mut first = true; f.write_str("{")?; for (key, typ) in entries { diff --git a/crates/rebel-lang/src/value.rs b/crates/rebel-lang/src/value.rs index 1e5750e..db15d10 100644 --- a/crates/rebel-lang/src/value.rs +++ b/crates/rebel-lang/src/value.rs @@ -25,7 +25,7 @@ pub enum Value { Str(String), Tuple(Vec<Value>), Array(Vec<Value>), - Map(HashMap<String, Value>), + Struct(HashMap<String, Value>), Fn(Box<Func>), } @@ -46,7 +46,7 @@ impl Value { Box::new(Self::array_elem_type(elems)?), ArrayLen::Fixed(elems.len()), ), - Value::Map(entries) => Type::Map( + Value::Struct(entries) => Type::Struct( entries .iter() .map(|(k, v)| Ok((k.clone(), v.typ()?))) @@ -238,7 +238,7 @@ impl Value { let index: usize = name.parse().or(Err(EvalError))?; elems.into_iter().nth(index).ok_or(EvalError)? } - Map(mut entries) => entries.remove(name).ok_or(EvalError)?, + Struct(mut entries) => entries.remove(name).ok_or(EvalError)?, _ => return Err(EvalError), }) } @@ -281,12 +281,14 @@ impl Value { .map(|elem| Self::eval(ctx, elem)) .collect::<Result<_>>()?, ), - Literal::Map(entries) => Map(entries - .iter() - .map(|ast::MapEntry { key, value }| { - Ok(((*key).to_owned(), Self::eval(ctx, value)?)) - }) - .collect::<Result<_>>()?), + Literal::Struct(entries) => Struct( + entries + .iter() + .map(|ast::StructField { key, value }| { + Ok(((*key).to_owned(), Self::eval(ctx, value)?)) + }) + .collect::<Result<_>>()?, + ), }) } } @@ -325,7 +327,7 @@ impl Display for Value { } f.write_str("]") } - Value::Map(entries) => { + Value::Struct(entries) => { let mut first = true; f.write_str("{")?; for (key, value) in entries { diff --git a/crates/rebel-parse/src/ast.rs b/crates/rebel-parse/src/ast.rs index 88853d7..490c2f1 100644 --- a/crates/rebel-parse/src/ast.rs +++ b/crates/rebel-parse/src/ast.rs @@ -250,7 +250,7 @@ pub enum Literal<'a> { }, Tuple(Vec<Expr<'a>>), Array(Vec<Expr<'a>>), - Map(Vec<MapEntry<'a>>), + Struct(Vec<StructField<'a>>), } impl<'a> Literal<'a> { @@ -296,9 +296,9 @@ impl<'a> Literal<'a> { } Ok(()) } - Literal::Map(entries) => { + Literal::Struct(entries) => { let mut keys = HashSet::new(); - for MapEntry { key, value } in entries { + for StructField { key, value } in entries { if !keys.insert(key) { return Err(ValidationError::DuplicateKey); } @@ -334,7 +334,7 @@ impl<'a> TryFrom<&token::StrPiece<'a>> for StrPiece<'a> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct MapEntry<'a> { +pub struct StructField<'a> { pub key: &'a str, pub value: Expr<'a>, } diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index aaa40d2..c23786b 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -118,13 +118,13 @@ peg::parser! { / p('[') elements:delimited(<expr()>, <p(',')>) p(']') { ast::Literal::Array(elements) } - / p('{') entries:delimited(<map_entry()>, <p(',')>) p('}') { - ast::Literal::Map(entries) + / p('{') entries:delimited(<struct_field()>, <p(',')>) p('}') { + ast::Literal::Struct(entries) } - rule map_entry() -> ast::MapEntry<'a> + rule struct_field() -> ast::StructField<'a> = key:field() p('=') value:expr() { - ast::MapEntry { key: key.name, value } + ast::StructField { key: key.name, value } } rule path() -> ast::Path<'a> |