about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-02-27T19·51+0200
committertazjin <mail@tazj.in>2021-02-27T20·19+0000
commit56f6a6e9f20236cb97d2e6bc2a7819762ecb0fe7 (patch)
tree0eb60beb7fb0473a0afe95e989963b57f5330056
parent7778a58f8d80147a5b180e0a889c245b47d573a5 (diff)
feat(tazjin/rlox): Implement parser precedence rules r/2242
Change-Id: Idcf3c84126603086bbf7e8d54773bccb3ae3b5ab
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2561
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
-rw-r--r--users/tazjin/rlox/src/bytecode/compiler/mod.rs28
1 files changed, 24 insertions, 4 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler/mod.rs b/users/tazjin/rlox/src/bytecode/compiler/mod.rs
index fab06fe39cf2..58a5c1b98a02 100644
--- a/users/tazjin/rlox/src/bytecode/compiler/mod.rs
+++ b/users/tazjin/rlox/src/bytecode/compiler/mod.rs
@@ -183,12 +183,26 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
     fn parse_precedence(&mut self, precedence: Precedence) -> LoxResult<()> {
         self.advance();
         let rule: ParseRule<T> = rule_for(&self.previous().kind);
-
-        if let Some(func) = rule.prefix {
-            func(self)?;
+        let prefix_fn = match rule.prefix {
+            None => unimplemented!("expected expression or something, unclear"),
+            Some(func) => func,
+        };
+
+        prefix_fn(self)?;
+
+        while precedence <= rule_for::<T>(&self.current().kind).precedence {
+            self.advance();
+            match rule_for::<T>(&self.previous().kind).infix {
+                Some(func) => {
+                    func(self)?;
+                }
+                None => {
+                    unreachable!("invalid compiler state: error in parse rules")
+                }
+            }
         }
 
-        unimplemented!("expect expression?")
+        Ok(())
     }
 
     fn consume(
@@ -224,6 +238,12 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
             .expect("invalid internal compiler state: missing previous token")
     }
 
+    fn current(&self) -> &Token {
+        self.current
+            .as_ref()
+            .expect("invalid internal compiler state: missing current token")
+    }
+
     fn error_at(&mut self, token: &Token, kind: ErrorKind) {
         if self.panic {
             return;