about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/bytecode/compiler.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2021-02-28T13·15+0200
committertazjin <mail@tazj.in>2021-02-28T14·36+0000
commit47ffa8071152bcafb4b6ff87a3142bf12dbce12b (patch)
treea97b223762525febc0a2cfefa5be413a7b80e901 /users/tazjin/rlox/src/bytecode/compiler.rs
parent127ef984865500d70176347861b2e8bad29a39be (diff)
feat(tazjin/rlox): Support trivial literals in bytecode compiler r/2252
Adds support for true, false & nil. These each come with a new
separate opcode and are pushed directly on the stack.

Change-Id: I405b5b09496dcf99d514d3411c083e0834377167
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2571
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/tazjin/rlox/src/bytecode/compiler.rs')
-rw-r--r--users/tazjin/rlox/src/bytecode/compiler.rs30
1 files changed, 28 insertions, 2 deletions
diff --git a/users/tazjin/rlox/src/bytecode/compiler.rs b/users/tazjin/rlox/src/bytecode/compiler.rs
index 63f34fad3ea7..95b111dba824 100644
--- a/users/tazjin/rlox/src/bytecode/compiler.rs
+++ b/users/tazjin/rlox/src/bytecode/compiler.rs
@@ -1,9 +1,12 @@
-use super::chunk::{self, Chunk};
+use super::chunk::Chunk;
 use super::errors::{Error, ErrorKind, LoxResult};
 use super::opcode::OpCode;
 use super::value::Value;
 use crate::scanner::{self, Token, TokenKind};
 
+#[cfg(feature = "disassemble")]
+use super::chunk;
+
 struct Compiler<T: Iterator<Item = Token>> {
     tokens: T,
     chunk: Chunk,
@@ -101,6 +104,18 @@ fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
             ParseRule::new(Some(Compiler::number), None, Precedence::None)
         }
 
+        TokenKind::True => {
+            ParseRule::new(Some(Compiler::literal), None, Precedence::None)
+        }
+
+        TokenKind::False => {
+            ParseRule::new(Some(Compiler::literal), None, Precedence::None)
+        }
+
+        TokenKind::Nil => {
+            ParseRule::new(Some(Compiler::literal), None, Precedence::None)
+        }
+
         _ => ParseRule::new(None, None, Precedence::None),
     }
 }
@@ -180,6 +195,17 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
         Ok(())
     }
 
+    fn literal(&mut self) -> LoxResult<()> {
+        match self.previous().kind {
+            TokenKind::Nil => self.emit_op(OpCode::OpNil),
+            TokenKind::True => self.emit_op(OpCode::OpTrue),
+            TokenKind::False => self.emit_op(OpCode::OpFalse),
+            _ => unreachable!("only called for literal value tokens"),
+        }
+
+        Ok(())
+    }
+
     fn parse_precedence(&mut self, precedence: Precedence) -> LoxResult<()> {
         self.advance();
         let rule: ParseRule<T> = rule_for(&self.previous().kind);
@@ -206,7 +232,7 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
     }
 
     fn consume(&mut self, expected: &TokenKind, err: ErrorKind) {
-        if (self.current().kind == *expected) {
+        if self.current().kind == *expected {
             self.advance();
             return;
         }