style(tazjin/rlox): Set max_width=80
Change-Id: Ib64831c0b97c94fdfbdbae64f4dfccc86879ef73 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2554 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in>
This commit is contained in:
parent
ebc987f4aa
commit
75750ba683
7 changed files with 153 additions and 50 deletions
1
users/tazjin/rlox/rustfmt.toml
Normal file
1
users/tazjin/rlox/rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
|||
max_width = 80
|
|
@ -78,7 +78,9 @@ pub fn disassemble_instruction(chunk: &Chunk, offset: usize) {
|
|||
}
|
||||
|
||||
match chunk.code.index(offset) {
|
||||
OpCode::OpConstant(idx) => println!("OpConstant({}) '{:?}'", *idx, chunk.constant(*idx)),
|
||||
OpCode::OpConstant(idx) => {
|
||||
println!("OpConstant({}) '{:?}'", *idx, chunk.constant(*idx))
|
||||
}
|
||||
op => println!("{:?}", op),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,10 @@ pub trait Lox {
|
|||
type Error: std::fmt::Display;
|
||||
|
||||
fn create() -> Self;
|
||||
fn interpret(&mut self, source: String) -> Result<Self::Value, Vec<Self::Error>>;
|
||||
fn interpret(
|
||||
&mut self,
|
||||
source: String,
|
||||
) -> Result<Self::Value, Vec<Self::Error>>;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -26,7 +29,9 @@ fn main() {
|
|||
}
|
||||
|
||||
match env::var("LOX_INTERPRETER").as_ref().map(String::as_str) {
|
||||
Ok("treewalk") => pick::<treewalk::interpreter::Interpreter>(args.nth(1)),
|
||||
Ok("treewalk") => {
|
||||
pick::<treewalk::interpreter::Interpreter>(args.nth(1))
|
||||
}
|
||||
_ => pick::<bytecode::Interpreter>(args.nth(1)),
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +46,8 @@ fn pick<I: Lox>(file_arg: Option<String>) {
|
|||
|
||||
// Run Lox code from a file and print results to stdout
|
||||
fn run_file<I: Lox>(file: &str) {
|
||||
let contents = fs::read_to_string(file).expect("failed to read the input file");
|
||||
let contents =
|
||||
fs::read_to_string(file).expect("failed to read the input file");
|
||||
let mut lox = I::create();
|
||||
run(&mut lox, contents);
|
||||
}
|
||||
|
|
|
@ -106,9 +106,15 @@ impl<'a> Scanner<'a> {
|
|||
|
||||
// possible multi-character tokens
|
||||
'!' => self.add_if_next('=', TokenKind::BangEqual, TokenKind::Bang),
|
||||
'=' => self.add_if_next('=', TokenKind::EqualEqual, TokenKind::Equal),
|
||||
'=' => {
|
||||
self.add_if_next('=', TokenKind::EqualEqual, TokenKind::Equal)
|
||||
}
|
||||
'<' => self.add_if_next('=', TokenKind::LessEqual, TokenKind::Less),
|
||||
'>' => self.add_if_next('=', TokenKind::GreaterEqual, TokenKind::Greater),
|
||||
'>' => self.add_if_next(
|
||||
'=',
|
||||
TokenKind::GreaterEqual,
|
||||
TokenKind::Greater,
|
||||
),
|
||||
|
||||
'/' => {
|
||||
// support comments until EOL by discarding characters
|
||||
|
@ -228,7 +234,8 @@ impl<'a> Scanner<'a> {
|
|||
self.advance();
|
||||
}
|
||||
|
||||
let ident: String = self.source[self.start..self.current].iter().collect();
|
||||
let ident: String =
|
||||
self.source[self.start..self.current].iter().collect();
|
||||
|
||||
// Determine whether this is an identifier, or a keyword:
|
||||
let token_kind = match ident.as_str() {
|
||||
|
|
|
@ -34,7 +34,11 @@ impl Callable {
|
|||
}
|
||||
}
|
||||
|
||||
fn call(&self, lox: &mut Interpreter, args: Vec<Value>) -> Result<Value, Error> {
|
||||
fn call(
|
||||
&self,
|
||||
lox: &mut Interpreter,
|
||||
args: Vec<Value>,
|
||||
) -> Result<Value, Error> {
|
||||
match self {
|
||||
Callable::Builtin(builtin) => builtin.call(args),
|
||||
|
||||
|
@ -46,8 +50,10 @@ impl Callable {
|
|||
fn_env.define(param, value)?;
|
||||
}
|
||||
|
||||
let result =
|
||||
lox.interpret_block_with_env(Some(Rc::new(RwLock::new(fn_env))), &func.body);
|
||||
let result = lox.interpret_block_with_env(
|
||||
Some(Rc::new(RwLock::new(fn_env))),
|
||||
&func.body,
|
||||
);
|
||||
|
||||
match result {
|
||||
// extract returned values if applicable
|
||||
|
@ -103,13 +109,22 @@ pub struct Environment {
|
|||
}
|
||||
|
||||
impl Environment {
|
||||
fn define(&mut self, name: &scanner::Token, value: Value) -> Result<(), Error> {
|
||||
fn define(
|
||||
&mut self,
|
||||
name: &scanner::Token,
|
||||
value: Value,
|
||||
) -> Result<(), Error> {
|
||||
let ident = identifier_str(name)?;
|
||||
self.values.insert(ident.into(), value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get(&self, ident: &str, line: usize, depth: usize) -> Result<Value, Error> {
|
||||
fn get(
|
||||
&self,
|
||||
ident: &str,
|
||||
line: usize,
|
||||
depth: usize,
|
||||
) -> Result<Value, Error> {
|
||||
if depth > 0 {
|
||||
match &self.enclosing {
|
||||
None => {
|
||||
|
@ -122,7 +137,9 @@ impl Environment {
|
|||
})
|
||||
}
|
||||
Some(parent) => {
|
||||
let env = parent.read().expect("fatal: environment lock poisoned");
|
||||
let env = parent
|
||||
.read()
|
||||
.expect("fatal: environment lock poisoned");
|
||||
return env.get(ident, line, depth - 1);
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +154,11 @@ impl Environment {
|
|||
})
|
||||
}
|
||||
|
||||
fn assign(&mut self, name: &scanner::Token, value: Value) -> Result<(), Error> {
|
||||
fn assign(
|
||||
&mut self,
|
||||
name: &scanner::Token,
|
||||
value: Value,
|
||||
) -> Result<(), Error> {
|
||||
let ident = identifier_str(name)?;
|
||||
|
||||
match self.values.get_mut(ident) {
|
||||
|
@ -221,14 +242,22 @@ impl Lox for Interpreter {
|
|||
|
||||
impl Interpreter {
|
||||
// Environment modification helpers
|
||||
fn define_var(&mut self, name: &scanner::Token, value: Value) -> Result<(), Error> {
|
||||
fn define_var(
|
||||
&mut self,
|
||||
name: &scanner::Token,
|
||||
value: Value,
|
||||
) -> Result<(), Error> {
|
||||
self.env
|
||||
.write()
|
||||
.expect("environment lock is poisoned")
|
||||
.define(name, value)
|
||||
}
|
||||
|
||||
fn assign_var(&mut self, name: &scanner::Token, value: Value) -> Result<(), Error> {
|
||||
fn assign_var(
|
||||
&mut self,
|
||||
name: &scanner::Token,
|
||||
value: Value,
|
||||
) -> Result<(), Error> {
|
||||
self.env
|
||||
.write()
|
||||
.expect("environment lock is poisoned")
|
||||
|
@ -242,10 +271,11 @@ impl Interpreter {
|
|||
kind: ErrorKind::UndefinedVariable(ident.into()),
|
||||
})?;
|
||||
|
||||
self.env
|
||||
.read()
|
||||
.expect("environment lock is poisoned")
|
||||
.get(ident, var.name.line, depth)
|
||||
self.env.read().expect("environment lock is poisoned").get(
|
||||
ident,
|
||||
var.name.line,
|
||||
depth,
|
||||
)
|
||||
}
|
||||
|
||||
/// Interpret the block in the supplied environment. If no
|
||||
|
@ -294,10 +324,16 @@ impl Interpreter {
|
|||
Value::Literal(Literal::String(output))
|
||||
}
|
||||
Statement::Var(var) => return self.interpret_var(var),
|
||||
Statement::Block(block) => return self.interpret_block_with_env(None, block),
|
||||
Statement::Block(block) => {
|
||||
return self.interpret_block_with_env(None, block)
|
||||
}
|
||||
Statement::If(if_stmt) => return self.interpret_if(if_stmt),
|
||||
Statement::While(while_stmt) => return self.interpret_while(while_stmt),
|
||||
Statement::Function(func) => return self.interpret_function(func.clone()),
|
||||
Statement::While(while_stmt) => {
|
||||
return self.interpret_while(while_stmt)
|
||||
}
|
||||
Statement::Function(func) => {
|
||||
return self.interpret_function(func.clone())
|
||||
}
|
||||
Statement::Return(ret) => {
|
||||
return Err(Error {
|
||||
line: 0,
|
||||
|
@ -312,7 +348,9 @@ impl Interpreter {
|
|||
fn interpret_var(&mut self, var: &parser::Var) -> Result<Value, Error> {
|
||||
let init = var.initialiser.as_ref().ok_or_else(|| Error {
|
||||
line: var.name.line,
|
||||
kind: ErrorKind::InternalError("missing variable initialiser".into()),
|
||||
kind: ErrorKind::InternalError(
|
||||
"missing variable initialiser".into(),
|
||||
),
|
||||
})?;
|
||||
let value = self.eval(init)?;
|
||||
self.define_var(&var.name, value.clone())?;
|
||||
|
@ -331,7 +369,10 @@ impl Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
fn interpret_while(&mut self, stmt: &parser::While) -> Result<Value, Error> {
|
||||
fn interpret_while(
|
||||
&mut self,
|
||||
stmt: &parser::While,
|
||||
) -> Result<Value, Error> {
|
||||
let mut value = Value::Literal(Literal::Nil);
|
||||
while eval_truthy(&self.eval(&stmt.condition)?) {
|
||||
value = self.interpret_stmt(&stmt.body)?;
|
||||
|
@ -340,7 +381,10 @@ impl Interpreter {
|
|||
Ok(value)
|
||||
}
|
||||
|
||||
fn interpret_function(&mut self, func: Rc<parser::Function>) -> Result<Value, Error> {
|
||||
fn interpret_function(
|
||||
&mut self,
|
||||
func: Rc<parser::Function>,
|
||||
) -> Result<Value, Error> {
|
||||
let name = func.name.clone();
|
||||
let value = Value::Callable(Callable::Function {
|
||||
func,
|
||||
|
@ -370,7 +414,9 @@ impl Interpreter {
|
|||
(TokenKind::Minus, Value::Literal(Literal::Number(num))) => {
|
||||
Ok(Literal::Number(-num).into())
|
||||
}
|
||||
(TokenKind::Bang, right) => Ok(Literal::Boolean(!eval_truthy(&right)).into()),
|
||||
(TokenKind::Bang, right) => {
|
||||
Ok(Literal::Boolean(!eval_truthy(&right)).into())
|
||||
}
|
||||
|
||||
(op, right) => Err(Error {
|
||||
line: expr.operator.line,
|
||||
|
@ -432,7 +478,10 @@ impl Interpreter {
|
|||
Ok(value)
|
||||
}
|
||||
|
||||
fn eval_logical(&mut self, logical: &parser::Logical) -> Result<Value, Error> {
|
||||
fn eval_logical(
|
||||
&mut self,
|
||||
logical: &parser::Logical,
|
||||
) -> Result<Value, Error> {
|
||||
let left = eval_truthy(&self.eval(&logical.left)?);
|
||||
let right = eval_truthy(&self.eval(&logical.right)?);
|
||||
|
||||
|
@ -441,7 +490,10 @@ impl Interpreter {
|
|||
TokenKind::Or => Ok(Literal::Boolean(left || right).into()),
|
||||
kind => Err(Error {
|
||||
line: logical.operator.line,
|
||||
kind: ErrorKind::InternalError(format!("Invalid logical operator: {:?}", kind)),
|
||||
kind: ErrorKind::InternalError(format!(
|
||||
"Invalid logical operator: {:?}",
|
||||
kind
|
||||
)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +504,10 @@ impl Interpreter {
|
|||
Value::Literal(v) => {
|
||||
return Err(Error {
|
||||
line: call.paren.line,
|
||||
kind: ErrorKind::RuntimeError(format!("not callable: {:?}", v)),
|
||||
kind: ErrorKind::RuntimeError(format!(
|
||||
"not callable: {:?}",
|
||||
v
|
||||
)),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
@ -491,7 +546,10 @@ fn eval_truthy(lit: &Value) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_enclosing_env(this: &RwLock<Environment>, parent: Rc<RwLock<Environment>>) {
|
||||
fn set_enclosing_env(
|
||||
this: &RwLock<Environment>,
|
||||
parent: Rc<RwLock<Environment>>,
|
||||
) {
|
||||
this.write()
|
||||
.expect("environment lock is poisoned")
|
||||
.enclosing = Some(parent);
|
||||
|
|
|
@ -213,7 +213,9 @@ impl Parser {
|
|||
if params.len() >= 255 {
|
||||
return Err(Error {
|
||||
line: self.peek().line,
|
||||
kind: ErrorKind::InternalError("255 parameter limit exceeded.".into()),
|
||||
kind: ErrorKind::InternalError(
|
||||
"255 parameter limit exceeded.".into(),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -427,7 +429,10 @@ impl Parser {
|
|||
|
||||
return Err(Error {
|
||||
line: equals.line,
|
||||
kind: ErrorKind::InvalidAssignmentTarget(format!("{:?}", equals)),
|
||||
kind: ErrorKind::InvalidAssignmentTarget(format!(
|
||||
"{:?}",
|
||||
equals
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -490,7 +495,9 @@ impl Parser {
|
|||
}
|
||||
|
||||
fn unary(&mut self) -> ExprResult {
|
||||
if self.match_token(&TokenKind::Bang) || self.match_token(&TokenKind::Minus) {
|
||||
if self.match_token(&TokenKind::Bang)
|
||||
|| self.match_token(&TokenKind::Minus)
|
||||
{
|
||||
return Ok(Expr::Unary(Unary {
|
||||
operator: self.previous().clone(),
|
||||
right: Box::new(self.unary()?),
|
||||
|
@ -550,7 +557,10 @@ impl Parser {
|
|||
|
||||
TokenKind::LeftParen => {
|
||||
let expr = self.expression()?;
|
||||
self.consume(&TokenKind::RightParen, ErrorKind::UnmatchedParens)?;
|
||||
self.consume(
|
||||
&TokenKind::RightParen,
|
||||
ErrorKind::UnmatchedParens,
|
||||
)?;
|
||||
return Ok(Expr::Grouping(Grouping(Box::new(expr))));
|
||||
}
|
||||
|
||||
|
@ -622,7 +632,11 @@ impl Parser {
|
|||
&self.tokens[self.current - 1]
|
||||
}
|
||||
|
||||
fn consume(&mut self, kind: &TokenKind, err: ErrorKind) -> Result<Token, Error> {
|
||||
fn consume(
|
||||
&mut self,
|
||||
kind: &TokenKind,
|
||||
err: ErrorKind,
|
||||
) -> Result<Token, Error> {
|
||||
if self.check_token(kind) {
|
||||
return Ok(self.advance());
|
||||
}
|
||||
|
|
|
@ -56,14 +56,13 @@ impl<'a> Resolver<'a> {
|
|||
// The resolver does not clone references, so unless
|
||||
// the interpreter is called before the resolver this
|
||||
// case should never happen.
|
||||
None => {
|
||||
return Err(Error {
|
||||
line: 0,
|
||||
kind: ErrorKind::InternalError(
|
||||
"multiple function references before interpretation".into(),
|
||||
),
|
||||
})
|
||||
}
|
||||
None => return Err(Error {
|
||||
line: 0,
|
||||
kind: ErrorKind::InternalError(
|
||||
"multiple function references before interpretation"
|
||||
.into(),
|
||||
),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +79,10 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_function(&mut self, func: &'a mut parser::Function) -> Result<(), Error> {
|
||||
fn resolve_function(
|
||||
&mut self,
|
||||
func: &'a mut parser::Function,
|
||||
) -> Result<(), Error> {
|
||||
self.declare(&func.name.lexeme);
|
||||
self.define(&func.name.lexeme);
|
||||
|
||||
|
@ -121,13 +123,17 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_variable(&mut self, var: &'a mut parser::Variable) -> Result<(), Error> {
|
||||
fn resolve_variable(
|
||||
&mut self,
|
||||
var: &'a mut parser::Variable,
|
||||
) -> Result<(), Error> {
|
||||
if let Some(scope) = self.scopes.last_mut() {
|
||||
if let Some(false) = scope.get(var.name.lexeme.as_str()) {
|
||||
return Err(Error {
|
||||
line: var.name.line,
|
||||
kind: ErrorKind::StaticError(
|
||||
"can't read local variable in its own initialiser".into(),
|
||||
"can't read local variable in its own initialiser"
|
||||
.into(),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -137,7 +143,10 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_assign(&mut self, assign: &'a mut parser::Assign) -> Result<(), Error> {
|
||||
fn resolve_assign(
|
||||
&mut self,
|
||||
assign: &'a mut parser::Assign,
|
||||
) -> Result<(), Error> {
|
||||
self.resolve_expr(&mut assign.value)?;
|
||||
assign.depth = self.resolve_local(&assign.name);
|
||||
Ok(())
|
||||
|
@ -153,7 +162,10 @@ impl<'a> Resolver<'a> {
|
|||
None
|
||||
}
|
||||
|
||||
fn resolve_call(&mut self, call: &'a mut parser::Call) -> Result<(), Error> {
|
||||
fn resolve_call(
|
||||
&mut self,
|
||||
call: &'a mut parser::Call,
|
||||
) -> Result<(), Error> {
|
||||
self.resolve_expr(&mut call.callee)?;
|
||||
|
||||
for arg in call.args.iter_mut() {
|
||||
|
@ -186,7 +198,10 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn resolve(globals: &[String], block: &mut parser::Block) -> Result<(), Error> {
|
||||
pub fn resolve(
|
||||
globals: &[String],
|
||||
block: &mut parser::Block,
|
||||
) -> Result<(), Error> {
|
||||
let mut resolver: Resolver = Default::default();
|
||||
|
||||
// Scope for static globals only starts, never ends.
|
||||
|
|
Loading…
Reference in a new issue