fix: make repl remember variables between invocations

I forgot to make environment global between run() function calls.
To fix this, I just create the environment and pass it to interpret()
instead of creating it there
This commit is contained in:
Seymur Bagirov 2025-01-13 08:41:04 +04:00
parent 9262620e07
commit 31e348643f
2 changed files with 13 additions and 6 deletions

View File

@ -21,8 +21,10 @@ impl RuntimeError {
} }
} }
pub fn interpret(statements: &Vec<Stmt>) -> Result<(), RuntimeError> { pub fn interpret(
let environment = Rc::new(RefCell::new(Environment::new())); statements: &Vec<Stmt>,
environment: &Rc<RefCell<Environment>>,
) -> Result<(), RuntimeError> {
for statement in statements { for statement in statements {
execute(statement, &environment)?; execute(statement, &environment)?;
} }

View File

@ -1,9 +1,12 @@
use std::{ use std::{
cell::RefCell,
error::Error, error::Error,
fs, fs,
io::{self, Write}, io::{self, Write},
rc::Rc,
}; };
use environment::Environment;
use interpreter::RuntimeError; use interpreter::RuntimeError;
use parser::{ParseError, Parser}; use parser::{ParseError, Parser};
use scanner::Scanner; use scanner::Scanner;
@ -34,12 +37,13 @@ impl<E: Error + 'static> From<E> for RunError {
pub fn run_file(path: &str) -> Result<(), RunError> { pub fn run_file(path: &str) -> Result<(), RunError> {
let file = fs::read_to_string(path).map_err(RunError::FileReadError)?; let file = fs::read_to_string(path).map_err(RunError::FileReadError)?;
let environment = Rc::new(RefCell::new(Environment::new()));
run(&file)?; run(&file, &environment)?;
Ok(()) Ok(())
} }
pub fn run(src: &str) -> Result<(), RunError> { pub fn run(src: &str, environment: &Rc<RefCell<Environment>>) -> Result<(), RunError> {
let mut scanner = Scanner::new(src.to_string()); let mut scanner = Scanner::new(src.to_string());
let tokens = scanner.scan_tokens()?; let tokens = scanner.scan_tokens()?;
@ -63,7 +67,7 @@ pub fn run(src: &str) -> Result<(), RunError> {
let statements = statements.into_iter().flatten().collect(); let statements = statements.into_iter().flatten().collect();
interpreter::interpret(&statements) interpreter::interpret(&statements, environment)
.inspect_err(runtime_error) .inspect_err(runtime_error)
.map_err(RunError::RuntimeError)?; .map_err(RunError::RuntimeError)?;
@ -73,12 +77,13 @@ pub fn run(src: &str) -> Result<(), RunError> {
pub fn run_prompt() -> Result<(), Box<dyn Error>> { pub fn run_prompt() -> Result<(), Box<dyn Error>> {
let stdin = io::stdin(); let stdin = io::stdin();
let input = &mut String::new(); let input = &mut String::new();
let environment = Rc::new(RefCell::new(Environment::new()));
loop { loop {
input.clear(); input.clear();
print!("> "); print!("> ");
io::stdout().flush()?; io::stdout().flush()?;
stdin.read_line(input)?; stdin.read_line(input)?;
let _ = run(input); let _ = run(input, &environment);
} }
} }