feat(tazjin/rlox): Support trivial literals in bytecode compiler

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
This commit is contained in:
Vincent Ambo 2021-02-28 15:15:46 +02:00 committed by tazjin
parent 127ef98486
commit 47ffa80711
5 changed files with 52 additions and 6 deletions

View file

@ -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;
}