summaryrefslogtreecommitdiff
path: root/src/ast/typed.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2020-11-20 16:22:38 +0000
committerGreg Brown <gmb60@cam.ac.uk>2020-11-20 16:22:38 +0000
commitba1a9b1d5259f022e298c385841a39f420ce4155 (patch)
treed37d0e840c43e8851a1d5ba412ab409bc40fcb15 /src/ast/typed.rs
parentaa7585d8bf84f27adeaf57e35f430e2e82a5d208 (diff)
Implement context traits for Vec
Diffstat (limited to 'src/ast/typed.rs')
-rw-r--r--src/ast/typed.rs122
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;