diff options
author | Greg Brown <gmb60@cam.ac.uk> | 2020-11-20 16:22:38 +0000 |
---|---|---|
committer | Greg Brown <gmb60@cam.ac.uk> | 2020-11-20 16:22:38 +0000 |
commit | ba1a9b1d5259f022e298c385841a39f420ce4155 (patch) | |
tree | d37d0e840c43e8851a1d5ba412ab409bc40fcb15 /src/ast/typed.rs | |
parent | aa7585d8bf84f27adeaf57e35f430e2e82a5d208 (diff) |
Implement context traits for Vec
Diffstat (limited to 'src/ast/typed.rs')
-rw-r--r-- | src/ast/typed.rs | 122 |
1 files changed, 120 insertions, 2 deletions
diff --git a/src/ast/typed.rs b/src/ast/typed.rs index e277cbb..dee13be 100644 --- a/src/ast/typed.rs +++ b/src/ast/typed.rs @@ -87,10 +87,67 @@ pub trait NullContext { fn push_nullable<F: FnOnce(&mut Self::PushNull) -> R, R>(&mut self, nullable: bool, f: F) -> R; } +impl NullContext for Vec<bool> { + type PushNull = Self; + + fn get_depth(&self) -> usize { + self.len() + } + + fn get_nullable(&self, index: usize) -> Option<bool> { + self.get(self.len() - index - 1).copied() + } + + fn push_nullable<F: FnOnce(&mut Self::PushNull) -> R, R>(&mut self, nullable: bool, f: F) -> R { + self.push(nullable); + let res = f(self); + self.pop(); + res + } +} + +impl NullContext for Vec<(bool, FirstSet)> { + type PushNull = Self; + + fn get_depth(&self) -> usize { + self.len() + } + + fn get_nullable(&self, index: usize) -> Option<bool> { + self.get(self.len() - index - 1).map(|(null, _)| null).copied() + } + + fn push_nullable<F: FnOnce(&mut Self::PushNull) -> R, R>(&mut self, nullable: bool, f: F) -> R { + self.push((nullable, FirstSet::new())); + let res = f(self); + self.pop(); + res + } +} + +impl NullContext for Vec<(bool, FirstSet, FlastSet)> { + type PushNull = Self; + + fn get_depth(&self) -> usize { + self.len() + } + + fn get_nullable(&self, index: usize) -> Option<bool> { + self.get(self.len() - index - 1).map(|(null, _, _)| null).copied() + } + + fn push_nullable<F: FnOnce(&mut Self::PushNull) -> R, R>(&mut self, nullable: bool, f: F) -> R { + self.push((nullable, FirstSet::new(), FlastSet::new())); + let res = f(self); + self.pop(); + res + } +} + pub trait FirstSetContext: NullContext { type PushFirstSet: FirstSetContext; - fn get_first_set(&self, index: usize) -> Option<FirstSet>; + fn get_first_set(&self, index: usize) -> Option<&FirstSet>; fn push_first_set<F: FnOnce(&mut Self::PushFirstSet) -> R, R>( &mut self, @@ -100,10 +157,50 @@ pub trait FirstSetContext: NullContext { ) -> R; } +impl FirstSetContext for Vec<(bool, FirstSet)> { + type PushFirstSet = Self; + + fn get_first_set(&self, index: usize) -> Option<&FirstSet> { + self.get(self.len() - index - 1).map(|(_, first_set)| first_set) + } + + fn push_first_set<F: FnOnce(&mut Self::PushFirstSet) -> R, R>( + &mut self, + nullable: bool, + first_set: FirstSet, + f: F, + ) -> R { + self.push((nullable, first_set)); + let res = f(self); + self.pop(); + res + } +} + +impl FirstSetContext for Vec<(bool, FirstSet, FlastSet)> { + type PushFirstSet = Self; + + fn get_first_set(&self, index: usize) -> Option<&FirstSet> { + self.get(self.len() - index - 1).map(|(_, first_set, _)| first_set) + } + + fn push_first_set<F: FnOnce(&mut Self::PushFirstSet) -> R, R>( + &mut self, + nullable: bool, + first_set: FirstSet, + f: F, + ) -> R { + self.push((nullable, first_set, FlastSet::new())); + let res = f(self); + self.pop(); + res + } +} + pub trait FlastSetContext: FirstSetContext { type PushFlastSet: FlastSetContext; - fn get_flast_set(&self, index: usize) -> Option<FlastSet>; + fn get_flast_set(&self, index: usize) -> Option<&FlastSet>; fn push_flast_set<F: FnOnce(&mut Self::PushFlastSet) -> R, R>( &mut self, @@ -114,6 +211,27 @@ pub trait FlastSetContext: FirstSetContext { ) -> R; } +impl FlastSetContext for Vec<(bool, FirstSet, FlastSet)> { + type PushFlastSet = Self; + + fn get_flast_set(&self, index: usize) -> Option<&FlastSet> { + self.get(self.len() - index - 1).map(|(_, _, flast_set)| flast_set) + } + + fn push_flast_set<F: FnOnce(&mut Self::PushFlastSet) -> R, R>( + &mut self, + nullable: bool, + first_set: FirstSet, + flast_set: FlastSet, + f: F, + ) -> R { + self.push((nullable, first_set, flast_set)); + let res = f(self); + self.pop(); + res + } +} + pub trait Type { type Err: Display; |