Compare commits
No commits in common. "734060193976afedd2eabfaed90b8db554102ed1" and "f59e6a5fd5e25f35116b6360ca33aa150ad7d1c6" have entirely different histories.
7340601939
...
f59e6a5fd5
3 changed files with 8 additions and 90 deletions
|
@ -49,11 +49,8 @@ pub enum InterpreterError {
|
|||
/// Interpreter for the Lox language that executes statements and evaluates expressions.
|
||||
#[derive(Debug)]
|
||||
pub struct Interpreter {
|
||||
/// Global environment containing built-in functions and top-level variables
|
||||
pub globals: Rc<RefCell<Environment>>,
|
||||
/// Current environment for variable lookups and assignments
|
||||
environment: Rc<RefCell<Environment>>,
|
||||
/// Map of expressions to their lexical distance for variable resolution
|
||||
locals: HashMap<Expression, usize>,
|
||||
}
|
||||
|
||||
|
@ -79,8 +76,7 @@ impl Default for Interpreter {
|
|||
}
|
||||
|
||||
impl Interpreter {
|
||||
/// Execute a list of statements in sequence.
|
||||
/// Log errors but continue execution.
|
||||
/// Try to evaluate an expression and return its result.
|
||||
pub fn run(&mut self, statements: Vec<Statement>) -> Result<(), InterpreterError> {
|
||||
for stmt in statements {
|
||||
match self.execute(&stmt) {
|
||||
|
@ -92,12 +88,11 @@ impl Interpreter {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Record the resolved lexical depth for a variable reference.
|
||||
pub fn resolve(&mut self, expression: Expression, depth: usize) {
|
||||
self.locals.insert(expression, depth);
|
||||
}
|
||||
|
||||
/// Execute a statement and return its result value, if any.
|
||||
///Execute a statement.
|
||||
fn execute(&mut self, statement: &Statement) -> Result<Option<Value>, InterpreterError> {
|
||||
match statement {
|
||||
Statement::Block(statements) => {
|
||||
|
@ -159,8 +154,6 @@ impl Interpreter {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
/// Define a new class with methods and optional inheritance.
|
||||
/// Handle superclass setup and method capturing.
|
||||
fn class(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
@ -266,7 +259,6 @@ impl Interpreter {
|
|||
|
||||
/// Call a callable if it is one (meaning it starts with a LeftParen after an identifier),
|
||||
/// otherwise evaluate the expression.
|
||||
/// Evaluate the callee and all arguments before making the call.
|
||||
fn call(
|
||||
&mut self,
|
||||
callee: &Expression,
|
||||
|
@ -288,8 +280,6 @@ impl Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a property from an object instance.
|
||||
/// Properties can be fields or methods.
|
||||
fn get(&mut self, object: &Expression, name: &Token) -> Result<Value, InterpreterError> {
|
||||
match self.evaluate(object)? {
|
||||
Value::Instance(instance) => Ok(instance.borrow().get(name, instance.clone())?),
|
||||
|
@ -297,7 +287,6 @@ impl Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set a property on an object instance to a new value.
|
||||
fn set(
|
||||
&mut self,
|
||||
object: &Expression,
|
||||
|
@ -315,7 +304,6 @@ impl Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Handle super expressions to access methods from a superclass.
|
||||
fn super_expr(
|
||||
&mut self,
|
||||
expression: &Expression,
|
||||
|
@ -435,7 +423,7 @@ impl Interpreter {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
/// Execute the body as long as the loop condition evaluates to true.
|
||||
/// Execute the body as long as the condition evaluates to true.
|
||||
fn while_statement(
|
||||
&mut self,
|
||||
condition: &Expression,
|
||||
|
@ -525,7 +513,7 @@ impl Interpreter {
|
|||
}
|
||||
}
|
||||
|
||||
/// Evaluate a variable reference expression.
|
||||
/// Get the value of a variable.
|
||||
fn var_expression(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
@ -534,8 +522,6 @@ impl Interpreter {
|
|||
self.lookup_var(name, expression)
|
||||
}
|
||||
|
||||
/// Look up a variable's value using static analysis information.
|
||||
/// Use the resolved lexical distance if available, otherwise check globals.
|
||||
fn lookup_var(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
|
|
@ -81,7 +81,6 @@ struct Parser {
|
|||
|
||||
impl Parser {
|
||||
/// Create a new parser instance, fail if the tokens vector is empty.
|
||||
/// Initialize the current token to the first token in the list.
|
||||
fn new(tokens: Vec<Token>) -> Result<Self, ParserError> {
|
||||
let current_token = tokens.first().ok_or(ParserError::NoTokens)?.clone();
|
||||
|
||||
|
@ -93,8 +92,6 @@ impl Parser {
|
|||
}
|
||||
|
||||
/// Parse all tokens to a list of statements for execution.
|
||||
/// Continue parsing until reaching the end of the token stream.
|
||||
/// Handle errors by logging them and synchronizing to continue parsing.
|
||||
fn run(&mut self) -> Result<Vec<Statement>, ParserError> {
|
||||
let mut statements = Vec::new();
|
||||
|
||||
|
@ -113,8 +110,7 @@ impl Parser {
|
|||
|
||||
/// Check if any of the provided types match the type of the current token.
|
||||
///
|
||||
/// If so, advance the current token and return true.
|
||||
/// Otherwise, return false without advancing.
|
||||
/// If so, advance the current token.
|
||||
fn matches(&mut self, types: &[TokenType]) -> bool {
|
||||
let matches = types.iter().any(|x| self.check(x));
|
||||
matches.then(|| self.advance());
|
||||
|
@ -155,7 +151,7 @@ impl Parser {
|
|||
}
|
||||
|
||||
/// Consume the current token if its token type matches the provided token_type and advance the
|
||||
/// current token. Otherwise return None.
|
||||
/// current token. Otherwise return None..
|
||||
fn consume(&mut self, token_type: &TokenType) -> Option<&Token> {
|
||||
if self.check(token_type) {
|
||||
self.advance().ok()
|
||||
|
@ -189,7 +185,6 @@ impl Parser {
|
|||
self.assignment()
|
||||
}
|
||||
|
||||
/// Parse a declaration.
|
||||
fn declaration(&mut self) -> Result<Statement, ParserError> {
|
||||
if self.matches(&[Class]) {
|
||||
self.class_declaration()
|
||||
|
@ -202,7 +197,6 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a statement.
|
||||
fn statement(&mut self) -> Result<Statement, ParserError> {
|
||||
if self.matches(&[For]) {
|
||||
self.for_statement()
|
||||
|
@ -221,7 +215,7 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a for statement by desugaring it into a while loop.
|
||||
/// Build up a while statement from a for statement.
|
||||
fn for_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
self.consume(&LeftParen)
|
||||
|
@ -270,8 +264,6 @@ impl Parser {
|
|||
Ok(body)
|
||||
}
|
||||
|
||||
/// Parse an if statement with a condition, then branch, and optional else branch.
|
||||
/// The condition must be enclosed in parentheses.
|
||||
fn if_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
self.consume(&LeftParen)
|
||||
|
@ -296,8 +288,6 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse a print statement, which consists of an expression followed by a semicolon.
|
||||
/// The expression's value will be printed during execution.
|
||||
fn print_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let value = self.expression()?;
|
||||
let line = self.current_token.line;
|
||||
|
@ -307,8 +297,6 @@ impl Parser {
|
|||
Ok(Statement::Print(value))
|
||||
}
|
||||
|
||||
/// Parse a return statement, which may include a return value expression.
|
||||
/// The return value is optional - if not provided, nil is returned implicitly.
|
||||
fn return_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let keyword = self.previous()?.clone();
|
||||
let value = if self.check(&Semicolon) {
|
||||
|
@ -323,8 +311,6 @@ impl Parser {
|
|||
Ok(Statement::Return { keyword, value })
|
||||
}
|
||||
|
||||
/// Parse a class declaration with a name, optional superclass, and methods.
|
||||
/// A class can inherit from a superclass using the '<' operator.
|
||||
fn class_declaration(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
let name = self
|
||||
|
@ -361,8 +347,6 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse a variable declaration with a name and optional initializer.
|
||||
/// If no initializer is provided, the variable is initialized to nil.
|
||||
fn var_declaration(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
let name = self
|
||||
|
@ -385,8 +369,6 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse a while statement with a condition and body.
|
||||
/// The condition must be enclosed in parentheses.
|
||||
fn while_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
self.consume(&LeftParen)
|
||||
|
@ -405,8 +387,6 @@ impl Parser {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse an expression statement, which is an expression followed by a semicolon.
|
||||
/// The expression is evaluated for its side effects.
|
||||
fn expression_statement(&mut self) -> Result<Statement, ParserError> {
|
||||
let expr = self.expression()?;
|
||||
let line = self.current_token.line;
|
||||
|
@ -416,8 +396,6 @@ impl Parser {
|
|||
Ok(Statement::Expression(expr))
|
||||
}
|
||||
|
||||
/// Parse a function declaration with a name, parameters, and body.
|
||||
/// Used for both standalone functions and class methods.
|
||||
fn function(&mut self) -> Result<Statement, ParserError> {
|
||||
let line = self.current_token.line;
|
||||
let name = self
|
||||
|
@ -455,8 +433,6 @@ impl Parser {
|
|||
Ok(Statement::Function { name, params, body })
|
||||
}
|
||||
|
||||
/// Parse a block of statements enclosed in braces.
|
||||
/// A block creates a new scope for variable declarations.
|
||||
fn block(&mut self) -> Result<Vec<Statement>, ParserError> {
|
||||
let mut statements = Vec::new();
|
||||
|
||||
|
@ -471,8 +447,6 @@ impl Parser {
|
|||
Ok(statements)
|
||||
}
|
||||
|
||||
/// Parse an assignment expression, which can assign to a variable or object property.
|
||||
/// Assignment is right-associative, so we recursively parse the right side.
|
||||
fn assignment(&mut self) -> Result<Expression, ParserError> {
|
||||
let expr = self.or()?;
|
||||
|
||||
|
@ -499,7 +473,6 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a logical expression with a specific operator (AND or OR).
|
||||
fn logical_operator<F>(
|
||||
&mut self,
|
||||
operator: TokenType,
|
||||
|
@ -524,12 +497,10 @@ impl Parser {
|
|||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Parse a logical OR expression.
|
||||
fn or(&mut self) -> Result<Expression, ParserError> {
|
||||
self.logical_operator(Or, Self::and)
|
||||
}
|
||||
|
||||
/// Parse a logical AND expression.
|
||||
fn and(&mut self) -> Result<Expression, ParserError> {
|
||||
self.logical_operator(And, Self::equality)
|
||||
}
|
||||
|
@ -569,7 +540,6 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a call expression or property access.
|
||||
fn call(&mut self) -> Result<Expression, ParserError> {
|
||||
let mut expr = self.primary()?;
|
||||
|
||||
|
@ -595,8 +565,6 @@ impl Parser {
|
|||
Ok(expr)
|
||||
}
|
||||
|
||||
/// Complete parsing a function call after seeing the opening parenthesis.
|
||||
/// Parse the arguments and closing parenthesis.
|
||||
fn finish_call(&mut self, callee: Expression) -> Result<Expression, ParserError> {
|
||||
let mut args = Vec::new();
|
||||
|
||||
|
@ -675,8 +643,6 @@ impl Parser {
|
|||
}
|
||||
}
|
||||
|
||||
/// Synchronize the parser after an error by advancing to the next statement boundary.
|
||||
/// This allows parsing to continue after encountering a syntax error.
|
||||
fn synchronize(&mut self) {
|
||||
let _ = self.advance();
|
||||
while !self.is_at_end()
|
||||
|
|
|
@ -37,7 +37,7 @@ enum ClassType {
|
|||
Subclass,
|
||||
}
|
||||
|
||||
/// Resolve variable references and perform static analysis before interpretation.
|
||||
/// Resolve variable references and performs static analysis before interpretation.
|
||||
#[derive(Debug)]
|
||||
pub struct Resolver<'a> {
|
||||
scopes: Vec<HashMap<String, bool>>,
|
||||
|
@ -47,7 +47,6 @@ pub struct Resolver<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
/// Create a new resolver with a reference to the interpreter
|
||||
pub fn new(interpreter: &'a mut Interpreter) -> Self {
|
||||
Self {
|
||||
scopes: Vec::default(),
|
||||
|
@ -57,7 +56,6 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Resolve all statements in a program
|
||||
pub fn resolve(&mut self, statements: &[Statement]) -> Result<(), ResolverError> {
|
||||
for stm in statements {
|
||||
self.resolve_statement(stm)?;
|
||||
|
@ -65,7 +63,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a single statement.
|
||||
fn resolve_statement(&mut self, statement: &Statement) -> Result<(), ResolverError> {
|
||||
match statement {
|
||||
Statement::Block(statements) => self.resolve_block(statements),
|
||||
|
@ -94,7 +91,6 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Resolve an expression.
|
||||
fn resolve_expression(&mut self, expr: &Expression) -> Result<(), ResolverError> {
|
||||
match expr {
|
||||
Expression::Assign { name, value } => self.resolve_assign_expr(expr, name, value),
|
||||
|
@ -136,19 +132,14 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Create a new scope for variable declarations.
|
||||
fn begin_scope(&mut self) {
|
||||
self.scopes.push(HashMap::new());
|
||||
}
|
||||
|
||||
/// Remove the current scope.
|
||||
fn end_scope(&mut self) {
|
||||
self.scopes.pop();
|
||||
}
|
||||
|
||||
/// Declare a variable in the current scope and mark it as not initialized yet (false).
|
||||
///
|
||||
/// Error if the variable is already declared in this scope.
|
||||
fn declare(&mut self, name: &Token) -> Result<(), ResolverError> {
|
||||
if let Some(scope) = self.scopes.last_mut() {
|
||||
if scope.contains_key(&name.lexeme) {
|
||||
|
@ -161,15 +152,12 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Mark a variable as initialized (true) in the current scope.
|
||||
fn define(&mut self, name: &Token) {
|
||||
if let Some(scope) = self.scopes.last_mut() {
|
||||
scope.insert(name.lexeme.clone(), true);
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve a block statement by creating a new scope.
|
||||
/// Resolve all statements in the block, then remove the scope.
|
||||
fn resolve_block(&mut self, statements: &[Statement]) -> Result<(), ResolverError> {
|
||||
self.begin_scope();
|
||||
self.resolve(statements)?;
|
||||
|
@ -178,8 +166,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a class declaration with methods and optional inheritance.
|
||||
/// Handle special cases for 'this', 'super', and initializers.
|
||||
fn resolve_class_stmt(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
@ -239,7 +225,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a return statement, checking for invalid returns (top-level code and value returns from initializers).
|
||||
fn resolve_return_stmt(
|
||||
&mut self,
|
||||
keyword: &Token,
|
||||
|
@ -258,7 +243,6 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Declare the variable, resolve its initializer if any, then define it.
|
||||
fn resolve_var(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
@ -274,8 +258,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a variable reference expression.
|
||||
/// Check that the variable is not being used in its own initializer.
|
||||
fn resolve_var_expr(&mut self, expr: &Expression, name: &Token) -> Result<(), ResolverError> {
|
||||
if let Some(scope) = self.scopes.last() {
|
||||
if !scope.get(&name.lexeme).unwrap_or(&true) {
|
||||
|
@ -286,8 +268,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve an assignment expression.
|
||||
/// Resolve the value being assigned, then resolve the variable being assigned to.
|
||||
fn resolve_assign_expr(
|
||||
&mut self,
|
||||
expr: &Expression,
|
||||
|
@ -299,7 +279,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a binary expression by resolving both operands.
|
||||
fn resolve_binary_expr(
|
||||
&mut self,
|
||||
left: &Expression,
|
||||
|
@ -310,8 +289,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a function declaration.
|
||||
/// Declare and define the function name, then resolve the function body.
|
||||
fn resolve_function_stmt(
|
||||
&mut self,
|
||||
name: &Token,
|
||||
|
@ -325,8 +302,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a function call expression.
|
||||
/// Resolve the callee and all arguments.
|
||||
fn resolve_call_expr(
|
||||
&mut self,
|
||||
callee: &Expression,
|
||||
|
@ -341,8 +316,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a property assignment expression.
|
||||
/// Resolve both the object and the value being assigned.
|
||||
fn resolve_set_expression(
|
||||
&mut self,
|
||||
object: &Expression,
|
||||
|
@ -354,7 +327,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a super expression, checking for invalid uses (outside of classes, classes with no superclass).
|
||||
fn resolve_super_expression(
|
||||
&mut self,
|
||||
keyword: &Token,
|
||||
|
@ -369,7 +341,6 @@ impl<'a> Resolver<'a> {
|
|||
self.resolve_local(expression, keyword)
|
||||
}
|
||||
|
||||
/// Resolve an if statement by resolving the condition and both branches.
|
||||
fn resolve_if_stmt(
|
||||
&mut self,
|
||||
condition: &Expression,
|
||||
|
@ -386,7 +357,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a while statement by resolving the condition and body.
|
||||
fn resolve_while_stmt(
|
||||
&mut self,
|
||||
condition: &Expression,
|
||||
|
@ -398,8 +368,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a function definition with parameters and body.
|
||||
/// Create a new scope for the function body and declare all parameters.
|
||||
fn resolve_function(
|
||||
&mut self,
|
||||
params: &[Token],
|
||||
|
@ -424,8 +392,6 @@ impl<'a> Resolver<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Resolve a local variable reference by finding its scope.
|
||||
/// Tell the interpreter the number of scopes between the reference and definition.
|
||||
fn resolve_local(
|
||||
&mut self,
|
||||
expression: &Expression,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue