fix(users/tazjin): rustfmt code with non-default settings

rustfmt only sometimes detects path-based nested config
files (probably some kind of race?), so my users folder uses a
separate formatting check for rustfmt to avoid flaky CI. Enough flakes
around already ...

Change-Id: Ifd862f9974f071b3a256643dd8e56c019116156a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/5242
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-02-07 19:29:52 +03:00 committed by clbot
parent 8b8c98380e
commit 0d0b43ed88
16 changed files with 348 additions and 421 deletions

View file

@ -63,9 +63,11 @@ enum Precedence {
Equality, // == !=
Comparison, // < > <= >=
Term, // + -
Factor, // * /
Unary, // ! -
Call, // . ()
Factor, //
//
// * /
Unary, // ! -
Call, // . ()
Primary,
}
@ -78,11 +80,7 @@ struct ParseRule<T: Iterator<Item = Token>> {
}
impl<T: Iterator<Item = Token>> ParseRule<T> {
fn new(
prefix: Option<ParseFn<T>>,
infix: Option<ParseFn<T>>,
precedence: Precedence,
) -> Self {
fn new(prefix: Option<ParseFn<T>>, infix: Option<ParseFn<T>>, precedence: Precedence) -> Self {
ParseRule {
prefix,
infix,
@ -105,18 +103,16 @@ impl Precedence {
Precedence::Factor => Precedence::Unary,
Precedence::Unary => Precedence::Call,
Precedence::Call => Precedence::Primary,
Precedence::Primary => panic!(
"invalid parser state: no higher precedence than Primary"
),
Precedence::Primary => {
panic!("invalid parser state: no higher precedence than Primary")
}
}
}
}
fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
match token {
TokenKind::LeftParen => {
ParseRule::new(Some(Compiler::grouping), None, Precedence::None)
}
TokenKind::LeftParen => ParseRule::new(Some(Compiler::grouping), None, Precedence::None),
TokenKind::Minus => ParseRule::new(
Some(Compiler::unary),
@ -124,57 +120,33 @@ fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
Precedence::Term,
),
TokenKind::Plus => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Term)
}
TokenKind::Plus => ParseRule::new(None, Some(Compiler::binary), Precedence::Term),
TokenKind::Slash => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Factor)
}
TokenKind::Slash => ParseRule::new(None, Some(Compiler::binary), Precedence::Factor),
TokenKind::Star => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Factor)
}
TokenKind::Star => ParseRule::new(None, Some(Compiler::binary), Precedence::Factor),
TokenKind::Number(_) => {
ParseRule::new(Some(Compiler::number), None, Precedence::None)
}
TokenKind::Number(_) => ParseRule::new(Some(Compiler::number), None, Precedence::None),
TokenKind::True => {
ParseRule::new(Some(Compiler::literal), None, Precedence::None)
}
TokenKind::True => ParseRule::new(Some(Compiler::literal), None, Precedence::None),
TokenKind::False => {
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)
}
TokenKind::Nil => ParseRule::new(Some(Compiler::literal), None, Precedence::None),
TokenKind::Bang => {
ParseRule::new(Some(Compiler::unary), None, Precedence::None)
}
TokenKind::Bang => ParseRule::new(Some(Compiler::unary), None, Precedence::None),
TokenKind::BangEqual => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Equality)
}
TokenKind::BangEqual => ParseRule::new(None, Some(Compiler::binary), Precedence::Equality),
TokenKind::EqualEqual => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Equality)
}
TokenKind::EqualEqual => ParseRule::new(None, Some(Compiler::binary), Precedence::Equality),
TokenKind::Greater => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison)
}
TokenKind::Greater => ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison),
TokenKind::GreaterEqual => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison)
}
TokenKind::Less => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison)
}
TokenKind::Less => ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison),
TokenKind::LessEqual => {
ParseRule::new(None, Some(Compiler::binary), Precedence::Comparison)
@ -184,9 +156,7 @@ fn rule_for<T: Iterator<Item = Token>>(token: &TokenKind) -> ParseRule<T> {
ParseRule::new(Some(Compiler::variable), None, Precedence::None)
}
TokenKind::String(_) => {
ParseRule::new(Some(Compiler::string), None, Precedence::None)
}
TokenKind::String(_) => ParseRule::new(Some(Compiler::string), None, Precedence::None),
_ => ParseRule::new(None, None, Precedence::None),
}
@ -236,9 +206,7 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
fn define_variable(&mut self, var: Option<ConstantIdx>) -> LoxResult<()> {
if self.locals.scope_depth == 0 {
self.emit_op(OpCode::OpDefineGlobal(
var.expect("should be global"),
));
self.emit_op(OpCode::OpDefineGlobal(var.expect("should be global")));
} else {
self.locals
.locals
@ -305,9 +273,7 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
}
fn block(&mut self) -> LoxResult<()> {
while !self.check(&TokenKind::RightBrace)
&& !self.check(&TokenKind::Eof)
{
while !self.check(&TokenKind::RightBrace) && !self.check(&TokenKind::Eof) {
self.declaration()?;
}
@ -712,9 +678,8 @@ impl<T: Iterator<Item = Token>> Compiler<T> {
pub fn compile(code: &str) -> Result<(Interner, Chunk), Vec<Error>> {
let chars = code.chars().collect::<Vec<char>>();
let tokens = scanner::scan(&chars).map_err(|errors| {
errors.into_iter().map(Into::into).collect::<Vec<Error>>()
})?;
let tokens = scanner::scan(&chars)
.map_err(|errors| errors.into_iter().map(Into::into).collect::<Vec<Error>>())?;
let mut compiler = Compiler {
tokens: tokens.into_iter().peekable(),

View file

@ -23,10 +23,7 @@ impl crate::Lox for 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 (strings, chunk) = compiler::compile(&code)?;
vm::interpret(strings, chunk).map_err(|e| vec![e])
}

View file

@ -118,12 +118,7 @@ impl VM {
OpCode::OpNegate => {
let v = self.pop();
with_type!(
self,
v,
Value::Number(num),
self.push(Value::Number(-num))
);
with_type!(self, v, Value::Number(num), self.push(Value::Number(-num)));
}
OpCode::OpSubtract => binary_op!(self, Number, -),
@ -141,15 +136,18 @@ impl VM {
self.push(Value::String(new_s.into()));
}
(Value::Number(n_a), Value::Number(n_b)) =>
self.push(Value::Number(n_a + n_b)),
(Value::Number(n_a), Value::Number(n_b)) => {
self.push(Value::Number(n_a + n_b))
}
_ => return Err(Error {
line: self.chunk.get_line(self.ip - 1),
kind: ErrorKind::TypeError(
"'+' operator only works on strings and numbers".into()
),
})
_ => {
return Err(Error {
line: self.chunk.get_line(self.ip - 1),
kind: ErrorKind::TypeError(
"'+' operator only works on strings and numbers".into(),
),
})
}
}
}
@ -205,8 +203,7 @@ impl VM {
self.stack.len() > local_idx.0,
"stack is not currently large enough for local"
);
self.stack[local_idx.0] =
self.stack.last().unwrap().clone();
self.stack[local_idx.0] = self.stack.last().unwrap().clone();
}
OpCode::OpJumpPlaceholder(_) => {
@ -255,9 +252,7 @@ impl VM {
fn print_value(&self, val: Value) -> String {
match val {
Value::String(LoxString::Heap(s)) => s,
Value::String(LoxString::Interned(id)) => {
self.strings.lookup(id).into()
}
Value::String(LoxString::Interned(id)) => self.strings.lookup(id).into(),
_ => format!("{:?}", val),
}
}

View file

@ -1,8 +1,5 @@
use std::env;
use std::fs;
use std::io;
use std::io::Write;
use std::process;
use std::{env, fs, io, process};
mod bytecode;
mod scanner;
@ -15,10 +12,7 @@ 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() {
@ -29,9 +23,7 @@ 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)),
}
}
@ -46,8 +38,7 @@ 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);
}

View file

@ -106,15 +106,9 @@ 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
@ -234,8 +228,7 @@ 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() {

View file

@ -34,11 +34,7 @@ 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),
@ -50,10 +46,8 @@ 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
@ -109,22 +103,13 @@ 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 => {
@ -137,9 +122,7 @@ 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);
}
}
@ -154,11 +137,7 @@ 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) {
@ -242,22 +221,14 @@ 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")
@ -271,11 +242,10 @@ 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
@ -324,16 +294,10 @@ 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,
@ -348,9 +312,7 @@ 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())?;
@ -369,10 +331,7 @@ 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)?;
@ -381,10 +340,7 @@ 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,
@ -414,9 +370,7 @@ 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,
@ -478,10 +432,7 @@ 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)?);
@ -490,10 +441,7 @@ 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)),
}),
}
}
@ -504,10 +452,7 @@ 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)),
})
}
};
@ -546,10 +491,7 @@ 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);

View file

@ -124,56 +124,54 @@ pub enum Statement {
// Parser
/*
program declaration* EOF ;
declaration funDecl
| varDecl
| statement ;
funDecl "fun" function ;
function IDENTIFIER "(" parameters? ")" block ;
parameters IDENTIFIER ( "," IDENTIFIER )* ;
statement exprStmt
| forStmt
| ifStmt
| printStmt
| returnStmt
| whileStmt
| block ;
forStmt "for" "(" ( varDecl | exprStmt | ";" )
expression? ";"
expression? ")" statement ;
returnStmt "return" expression? ";" ;
whileStmt "while" "(" expression ")" statement ;
exprStmt expression ";" ;
ifStmt "if" "(" expression ")" statement
( "else" statement )? ;
printStmt "print" expression ";" ;
expression assignment ;
assignment IDENTIFIER "=" assignment
| logic_or ;
logic_or logic_and ( "or" logic_and )* ;
logic_and equality ( "and" equality )* ;
equality comparison ( ( "!=" | "==" ) comparison )* ;
comparison term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
term factor ( ( "-" | "+" ) factor )* ;
factor unary ( ( "/" | "*" ) unary )* ;
unary ( "!" | "-" ) unary | call ;
call primary ( "(" arguments? ")" )* ;
arguments expression ( "," expression )* ;
primary NUMBER | STRING | "true" | "false" | "nil"
| "(" expression ")" ;
*/
// program → declaration* EOF ;
//
// declaration → funDecl
// | varDecl
// | statement ;
//
// funDecl → "fun" function ;
// function → IDENTIFIER "(" parameters? ")" block ;
// parameters → IDENTIFIER ( "," IDENTIFIER )* ;
//
//
// statement → exprStmt
// | forStmt
// | ifStmt
// | printStmt
// | returnStmt
// | whileStmt
// | block ;
//
// forStmt → "for" "(" ( varDecl | exprStmt | ";" )
// expression? ";"
// expression? ")" statement ;
//
// returnStmt → "return" expression? ";" ;
//
// whileStmt → "while" "(" expression ")" statement ;
//
// exprStmt → expression ";" ;
//
// ifStmt → "if" "(" expression ")" statement
// ( "else" statement )? ;
//
// printStmt → "print" expression ";" ;
//
// expression → assignment ;
// assignment → IDENTIFIER "=" assignment
// | logic_or ;
// logic_or → logic_and ( "or" logic_and )* ;
// logic_and → equality ( "and" equality )* ;
// equality → comparison ( ( "!=" | "==" ) comparison )* ;
// comparison → term ( ( ">" | ">=" | "<" | "<=" ) term )* ;
// term → factor ( ( "-" | "+" ) factor )* ;
// factor → unary ( ( "/" | "*" ) unary )* ;
// unary → ( "!" | "-" ) unary | call ;
// call → primary ( "(" arguments? ")" )* ;
// arguments → expression ( "," expression )* ;
// primary → NUMBER | STRING | "true" | "false" | "nil"
// | "(" expression ")" ;
struct Parser {
tokens: Vec<Token>,
@ -213,9 +211,7 @@ 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()),
});
}
@ -429,10 +425,7 @@ impl Parser {
return Err(Error {
line: equals.line,
kind: ErrorKind::InvalidAssignmentTarget(format!(
"{:?}",
equals
)),
kind: ErrorKind::InvalidAssignmentTarget(format!("{:?}", equals)),
});
}
@ -495,9 +488,7 @@ 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()?),
@ -557,10 +548,7 @@ 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))));
}
@ -632,11 +620,7 @@ 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());
}

View file

@ -56,13 +56,14 @@ 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(),
),
})
}
},
}
}
@ -79,10 +80,7 @@ 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);
@ -123,17 +121,13 @@ 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(),
),
});
}
@ -143,10 +137,7 @@ 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(())
@ -162,10 +153,7 @@ 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() {
@ -198,10 +186,7 @@ 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.