about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-02-27T17·39+0200
committertazjin <mail@tazj.in>2021-02-27T19·22+0000
commitd2f24c925d67665f74b2707260f88723895b0308 (patch)
treee4ef976b379ea8e3beacda5f6d535529a0cda755
parent1d3d9d32e34c72c84ff72af4583f83d7105bdb98 (diff)
feat(tazjin/rlox): Partial implementation of binary operators r/2240
Change-Id: I6f0bc9f58b51dec2673c918e08b199b52e793ed4
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2559
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
-rw-r--r--users/tazjin/rlox/src/bytecode/compiler/mod.rs50
1 files changed, 49 insertions, 1 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler/mod.rs b/users/tazjin/rlox/src/bytecode/compiler/mod.rs
index 813cf2e26d..a4cc434910 100644
--- a/users/tazjin/rlox/src/bytecode/compiler/mod.rs
+++ b/users/tazjin/rlox/src/bytecode/compiler/mod.rs
@@ -33,6 +33,27 @@ enum Precedence {
     Primary,
 }
 
+impl Precedence {
+    // Return the next highest precedence, if there is one.
+    fn next(&self) -> Self {
+        match self {
+            Precedence::None => Precedence::Assignment,
+            Precedence::Assignment => Precedence::Or,
+            Precedence::Or => Precedence::And,
+            Precedence::And => Precedence::Equality,
+            Precedence::Equality => Precedence::Comparison,
+            Precedence::Comparison => Precedence::Term,
+            Precedence::Term => Precedence::Factor,
+            Precedence::Factor => Precedence::Unary,
+            Precedence::Unary => Precedence::Call,
+            Precedence::Call => Precedence::Primary,
+            Precedence::Primary => panic!(
+                "invalid parser state: no higher precedence than Primary"
+            ),
+        }
+    }
+}
+
 impl<T: Iterator<Item = Token>> Compiler<T> {
     fn compile(&mut self) -> LoxResult<()> {
         self.advance();
@@ -68,7 +89,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
         )
     }
 
-    fn unary(&mut self, kind: &TokenKind) -> LoxResult<()> {
+    fn unary(&mut self) -> LoxResult<()> {
+        // TODO(tazjin): Avoid clone
+        let kind = self.previous().kind.clone();
+
         // Compile the operand
         self.parse_precedence(Precedence::Unary)?;
 
@@ -81,6 +105,30 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
         Ok(())
     }
 
+    fn binary(&mut self) -> LoxResult<()> {
+        // Remember the operator
+        let operator = self.previous().kind.clone();
+
+        // Compile the right operand
+        let rule = self.get_rule(&operator);
+        self.parse_precedence(unimplemented!("rule.precendece.next()"))?;
+
+        // Emit operator instruction
+        match operator {
+            TokenKind::Minus => self.emit_op(OpCode::OpSubtract),
+            TokenKind::Plus => self.emit_op(OpCode::OpAdd),
+            TokenKind::Star => self.emit_op(OpCode::OpMultiply),
+            TokenKind::Slash => self.emit_op(OpCode::OpDivide),
+            _ => unreachable!("only called for binary operator tokens"),
+        }
+
+        unimplemented!()
+    }
+
+    fn get_rule(&mut self, op: &TokenKind) -> usize {
+        unimplemented!();
+    }
+
     fn parse_precedence(&mut self, precedence: Precedence) -> LoxResult<()> {
         unimplemented!("what goes here?")
     }