diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-29 19:02:34 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2024-04-29 19:02:34 +0200 |
commit | 684a6e62b40389dad5875c86c8d50658d676128d (patch) | |
tree | c8665f787b38d56ec797b7f48e840f94f6a68c6e /crates/rebel-parse | |
parent | 8226a8ec820987c99c24b5f6e76a8b379f9efa0a (diff) | |
download | rebel-684a6e62b40389dad5875c86c8d50658d676128d.tar rebel-684a6e62b40389dad5875c86c8d50658d676128d.zip |
rebel-parse: ast: typ: allow to distinguish between free and dynamic array length
Diffstat (limited to 'crates/rebel-parse')
-rw-r--r-- | crates/rebel-parse/src/ast/typ.rs | 9 | ||||
-rw-r--r-- | crates/rebel-parse/src/grammar/recipe.rs | 18 |
2 files changed, 21 insertions, 6 deletions
diff --git a/crates/rebel-parse/src/ast/typ.rs b/crates/rebel-parse/src/ast/typ.rs index 37aa33e..18ea827 100644 --- a/crates/rebel-parse/src/ast/typ.rs +++ b/crates/rebel-parse/src/ast/typ.rs @@ -11,10 +11,17 @@ pub enum Type<'a> { pub enum Literal<'a> { Unit, Tuple(Vec<Type<'a>>), - Array(Box<Type<'a>>, Option<u32>), + Array(Box<Type<'a>>, ArrayLen), Struct(Vec<StructField<'a>>), } +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum ArrayLen { + Free, + Fixed(u32), + Dynamic, +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct StructField<'a> { pub name: &'a str, diff --git a/crates/rebel-parse/src/grammar/recipe.rs b/crates/rebel-parse/src/grammar/recipe.rs index 893d4b7..73ddb2e 100644 --- a/crates/rebel-parse/src/grammar/recipe.rs +++ b/crates/rebel-parse/src/grammar/recipe.rs @@ -66,16 +66,24 @@ peg::parser! { / p('(') elements:(typ() ** p(',')) p(',')? p(')') { typ::Literal::Tuple(elements) } - / p('[') typ:typ() len:tagged(<p(';')>, <number()>)? p(']') { ? - let len = len - .map(|n| u32::try_from(n).or(Err("Invalid array length"))) - .transpose()?; - Ok(typ::Literal::Array(Box::new(typ), len)) + / p('[') typ:typ() len:array_len() p(']') { + typ::Literal::Array(Box::new(typ), len) } / p('{') entries:delimited(<struct_field_typ()>, <p(',')>) p('}') { typ::Literal::Struct(entries) } + rule array_len() -> typ::ArrayLen + = p(';') len:number() { ? + Ok(typ::ArrayLen::Fixed(len.try_into().or(Err("Invalid array length"))?)) + } + / p(';') [Token::Ident(name) if *name == "_"] { + typ::ArrayLen::Free + } + / { + typ::ArrayLen::Dynamic + } + rule pat() -> Pat<'a> = path:path() { Pat::Path(path) } |