1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use crate::semantic::pattern::PatternLen;
use crate::NumberUnsigned;
//Describe a Block/Pattern possible len
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConstructorPatternLen {
/// Cases with the pattern call it own table, NOTE: the table can only call
/// itself once.
/// self-Recursive, non-growing, basically unrestricted, but indicating
/// to tables that this don't change the table.pattern_len directly.
/// Value is the len that this constructor will generate, not including
/// the recursive itself
NonGrowingRecursive(PatternLen),
/// self-Recrusive, growing, similat to NonGrowing, but is possible that this
/// keep calling itself, in a infinite growing patter. It is the context job
/// to limit the size of it.
/// grow, is the len of the size that will be added to the len, and non_grow,
/// is the value that was taken from NonGrowing Recursive
GrowingRecursive {
grow: PatternLen,
non_grow: PatternLen,
},
/// the final state, this means the len have a possible final value,
/// although it could be restricted further, eg: len is 2-8bytes, but is
/// found that the len is never bigger then 6, so len is update to 2-6bytes.
Basic(PatternLen),
}
impl ConstructorPatternLen {
pub fn single_len(&self) -> Option<NumberUnsigned> {
match self {
Self::Basic(basic) => basic.single_len(),
Self::NonGrowingRecursive(_) | Self::GrowingRecursive { .. } => None,
}
}
pub fn is_basic(&self) -> bool {
matches!(self, Self::Basic(_))
}
pub fn basic(&self) -> Option<PatternLen> {
match self {
Self::Basic(basic) => Some(*basic),
Self::NonGrowingRecursive(_) | Self::GrowingRecursive { .. } => None,
}
}
///if is some kind of recursive
pub fn is_recursive(&self) -> bool {
match self {
Self::Basic(basic) => basic.is_recursive(),
Self::NonGrowingRecursive(_) | Self::GrowingRecursive { .. } => true,
}
}
///the min possible pattern len size, None means the min can't be calculated
///because this is a recursive and the len depends on the other constructors
pub fn min(&self) -> Option<NumberUnsigned> {
self.basic().map(|len| len.min())
}
///the max possible pattern len size, None is infinite maximum possible len
pub fn max(&self) -> Option<NumberUnsigned> {
self.basic().and_then(|len| len.max())
}
//TODO replace Option with Result?
pub fn add(self, other: Self) -> Option<Self> {
match (self, other) {
(Self::Basic(x), Self::Basic(y)) => Some(Self::Basic(x.concat(y))),
//NonGrowingRecursize concat with a basic block, result in a
//GrowingRecursive
(Self::NonGrowingRecursive(non_grow), Self::Basic(basic))
| (Self::Basic(basic), Self::NonGrowingRecursive(non_grow)) => {
Some(Self::GrowingRecursive {
grow: basic,
non_grow,
})
}
//Growing Recursive concat with a basic, just grows
(Self::GrowingRecursive { grow, non_grow }, Self::Basic(basic))
| (Self::Basic(basic), Self::GrowingRecursive { grow, non_grow }) => {
Some(Self::GrowingRecursive {
grow: grow.concat(basic),
non_grow,
})
}
//a pattern can only have one SelfRecursive, so this is invalid
(
Self::GrowingRecursive { .. } | Self::NonGrowingRecursive(_),
Self::GrowingRecursive { .. } | Self::NonGrowingRecursive(_),
) => None,
}
}
pub fn greater(self, other: Self) -> Option<Self> {
match (self, other) {
(
Self::GrowingRecursive { .. } | Self::NonGrowingRecursive(_),
Self::GrowingRecursive { .. } | Self::NonGrowingRecursive(_),
) => None,
(Self::Basic(x), Self::Basic(y)) => Some(Self::Basic(x.greater(y))),
(
Self::Basic(x) | Self::NonGrowingRecursive(x),
Self::Basic(y) | Self::NonGrowingRecursive(y),
) => Some(Self::NonGrowingRecursive(x.greater(y))),
(Self::Basic(_), Self::GrowingRecursive { .. })
| (Self::GrowingRecursive { .. }, Self::Basic(_)) => {
//This only happen if recursive block is in a sub_pattern
//what i think is not allowed
unimplemented!()
}
}
}
}
impl From<PatternLen> for ConstructorPatternLen {
fn from(value: PatternLen) -> Self {
Self::Basic(value)
}
}