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 | |
parent | aa7585d8bf84f27adeaf57e35f430e2e82a5d208 (diff) |
Implement context traits for Vec
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/mod.rs | 10 | ||||
-rw-r--r-- | src/ast/typed.rs | 122 |
2 files changed, 125 insertions, 7 deletions
diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 10054fc..280a646 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -390,11 +390,11 @@ impl Type for Variable { } fn first_set<C: FirstSetContext>(&self, context: &mut C) -> Option<FirstSet> { - context.get_first_set(self.index) + context.get_first_set(self.index).cloned() } fn flast_set<C: FlastSetContext>(&self, context: &mut C) -> Option<FlastSet> { - context.get_flast_set(self.index) + context.get_flast_set(self.index).cloned() } fn well_typed<C: FlastSetContext>(self, context: &mut C) -> Result<Typed, Self::Err> { @@ -587,15 +587,15 @@ pub struct Typed { impl Typed { pub fn is_nullable(&self) -> bool { - todo!() + self.nullable } pub fn first_set(&self) -> &FirstSet { - todo!() + &self.first_set } pub fn flast_set(&self) -> &FlastSet { - todo!() + &self.flast_set } } 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; |