about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/treewalk
diff options
context:
space:
mode:
Diffstat (limited to 'users/tazjin/rlox/src/treewalk')
-rw-r--r--users/tazjin/rlox/src/treewalk/interpreter.rs106
-rw-r--r--users/tazjin/rlox/src/treewalk/parser.rs122
-rw-r--r--users/tazjin/rlox/src/treewalk/resolver.rs43
3 files changed, 91 insertions, 180 deletions
diff --git a/users/tazjin/rlox/src/treewalk/interpreter.rs b/users/tazjin/rlox/src/treewalk/interpreter.rs
index d9fe33661684..3285775bbec6 100644
--- a/users/tazjin/rlox/src/treewalk/interpreter.rs
+++ b/users/tazjin/rlox/src/treewalk/interpreter.rs
@@ -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);
diff --git a/users/tazjin/rlox/src/treewalk/parser.rs b/users/tazjin/rlox/src/treewalk/parser.rs
index 003cc34b4665..5794b42d1577 100644
--- a/users/tazjin/rlox/src/treewalk/parser.rs
+++ b/users/tazjin/rlox/src/treewalk/parser.rs
@@ -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());
         }
diff --git a/users/tazjin/rlox/src/treewalk/resolver.rs b/users/tazjin/rlox/src/treewalk/resolver.rs
index 8231ce5a9e58..3d12973aa089 100644
--- a/users/tazjin/rlox/src/treewalk/resolver.rs
+++ b/users/tazjin/rlox/src/treewalk/resolver.rs
@@ -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.