feat(tazjin/rlox): Implement expression statements

These aren't particularly useful without side effects, but one step at
a time.

This diverges slightly from the book, in that OpPop retains the last
value it "forgot" from the stack in a special field on the
interpreter.

This makes it possible to return values from expression statements,
which helps in cases where Lox is embedded as a scripting
language (please don't do this ever) or in tests.

Change-Id: Ided0bc04c6e80ddb23ba4693d61ac9e08b002d58
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2584
Reviewed-by: tazjin <mail@tazj.in>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2021-03-02 22:26:02 +02:00 committed by tazjin
parent 2cd77ea26d
commit ed3fce2b19
4 changed files with 76 additions and 51 deletions

View file

@ -179,10 +179,10 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
fn statement(&mut self) -> LoxResult<()> {
if self.match_token(&TokenKind::Print) {
return self.print_statement();
self.print_statement()
} else {
self.expression_statement()
}
Ok(())
}
fn print_statement(&mut self) -> LoxResult<()> {
@ -195,6 +195,16 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
Ok(())
}
fn expression_statement(&mut self) -> LoxResult<()> {
self.expression()?;
self.consume(
&TokenKind::Semicolon,
ErrorKind::ExpectedToken("Expected ';' after expression"),
);
self.emit_op(OpCode::OpPop);
Ok(())
}
fn number(&mut self) -> LoxResult<()> {
if let TokenKind::Number(num) = self.previous().kind {
self.emit_constant(Value::Number(num));