chore(tazjin/rlox): Set up some scaffolding for panic mode
This lets us suppress reporting of additional errors from the compiler until a synchronisation point is reached. Change-Id: Iacf90949f868fbdb4349750065b5e458cf74d32a Reviewed-on: https://cl.tvl.fyi/c/depot/+/2557 Reviewed-by: tazjin <mail@tazj.in> Tested-by: BuildkiteCI
This commit is contained in:
parent
ee974b3edd
commit
b13a6736dd
2 changed files with 26 additions and 6 deletions
|
@ -4,10 +4,10 @@ use super::opcode::OpCode;
|
||||||
use crate::scanner;
|
use crate::scanner;
|
||||||
|
|
||||||
struct Compiler<T: Iterator<Item = scanner::Token>> {
|
struct Compiler<T: Iterator<Item = scanner::Token>> {
|
||||||
// panic: bool,
|
|
||||||
errors: Vec<Error>,
|
|
||||||
tokens: T,
|
tokens: T,
|
||||||
chunk: Chunk,
|
chunk: Chunk,
|
||||||
|
panic: bool,
|
||||||
|
errors: Vec<Error>,
|
||||||
|
|
||||||
// TODO(tazjin): Restructure so that these don't need to be Option?
|
// TODO(tazjin): Restructure so that these don't need to be Option?
|
||||||
current: Option<scanner::Token>,
|
current: Option<scanner::Token>,
|
||||||
|
@ -48,16 +48,32 @@ impl<T: Iterator<Item = scanner::Token>> Compiler<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn end_compiler(&mut self) -> LoxResult<()> {
|
fn end_compiler(&mut self) -> LoxResult<()> {
|
||||||
let line = self.previous().line;
|
self.emit_op(OpCode::OpReturn);
|
||||||
self.current_chunk().add_op(OpCode::OpReturn, line);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn emit_op(&mut self, op: OpCode) {
|
||||||
|
let line = self.previous().line;
|
||||||
|
self.current_chunk().add_op(op, line);
|
||||||
|
}
|
||||||
|
|
||||||
fn previous(&self) -> &scanner::Token {
|
fn previous(&self) -> &scanner::Token {
|
||||||
self.previous
|
self.previous
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("invalid internal compiler state: missing previous token")
|
.expect("invalid internal compiler state: missing previous token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn error_at(&mut self, token: &scanner::Token, kind: ErrorKind) {
|
||||||
|
if self.panic {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.panic = true;
|
||||||
|
self.errors.push(Error {
|
||||||
|
kind,
|
||||||
|
line: token.line,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(code: &str) -> Result<Chunk, Vec<Error>> {
|
pub fn compile(code: &str) -> Result<Chunk, Vec<Error>> {
|
||||||
|
@ -68,10 +84,11 @@ pub fn compile(code: &str) -> Result<Chunk, Vec<Error>> {
|
||||||
|
|
||||||
let mut compiler = Compiler {
|
let mut compiler = Compiler {
|
||||||
tokens: tokens.into_iter().peekable(),
|
tokens: tokens.into_iter().peekable(),
|
||||||
|
chunk: Default::default(),
|
||||||
|
panic: false,
|
||||||
errors: vec![],
|
errors: vec![],
|
||||||
current: None,
|
current: None,
|
||||||
previous: None,
|
previous: None,
|
||||||
chunk: Default::default(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
compiler.compile()?;
|
compiler.compile()?;
|
||||||
|
|
|
@ -20,7 +20,10 @@ impl crate::Lox for Interpreter {
|
||||||
Interpreter {}
|
Interpreter {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interpret(&mut self, code: String) -> Result<Self::Value, Vec<Self::Error>> {
|
fn interpret(
|
||||||
|
&mut self,
|
||||||
|
code: String,
|
||||||
|
) -> Result<Self::Value, Vec<Self::Error>> {
|
||||||
let chunk = compiler::compile(&code)?;
|
let chunk = compiler::compile(&code)?;
|
||||||
vm::interpret(chunk).map_err(|e| vec![e])
|
vm::interpret(chunk).map_err(|e| vec![e])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue