From 3ad568bf56578fd201e3f5ea61ea2acb6e81584e Mon Sep 17 00:00:00 2001 From: walonCode Date: Sat, 27 Jun 2026 10:28:09 +0000 Subject: [PATCH] fix the bugs from task 7-12 --- crates/fmt/src/lint_rules.rs | 19 +++++++++++++++---- src/evaluator/evaluator.rs | 16 ++++++++++++++++ src/parser/parser.rs | 14 ++++++++++++-- src/repl/repl.rs | 11 +++++++++++ 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/crates/fmt/src/lint_rules.rs b/crates/fmt/src/lint_rules.rs index 9fab276..969ccda 100644 --- a/crates/fmt/src/lint_rules.rs +++ b/crates/fmt/src/lint_rules.rs @@ -171,9 +171,19 @@ impl Visitor for ShadowedBinding { self.register_pattern(pattern, line, col); } - fn visit_expression(&mut self, expr: &Expression) { - - } + todo!(); /// Task 8 + + // fn visit_expression(&mut self, expr: &Expression) { + // if let Expression::Function { parameter, body, .. } = expr { + // self.scope_stack.push(HashMap::new()); + // for param in parameter { + // if self.scope_stack.contains(param.name) { + + // } + // self.register_pattern(param.name, line, col); + // } + // } + // } } impl LintRule for ShadowedBinding { @@ -407,7 +417,8 @@ impl Visitor for DeadCode { self.visit_statement(s); } - self.returned = saved; + let block_returned = self.returned; + self.returned = saved || block_returned; } walk_statement(self, stmt); diff --git a/src/evaluator/evaluator.rs b/src/evaluator/evaluator.rs index 69e8acf..5b47c9b 100644 --- a/src/evaluator/evaluator.rs +++ b/src/evaluator/evaluator.rs @@ -13,9 +13,16 @@ const MAX_CALL_DEPTH: usize = 500; pub struct Evaluator { pub loop_depth: usize, pub call_depth: usize, + pub call_stack: Vec, pub module_cache: HashMap, } +pub struct CallFrame { + pub name:String, + pub call_line: usize, + pub call_column: usize +} + type Env = Rc>; impl Evaluator { @@ -23,6 +30,7 @@ impl Evaluator { let mut e = Evaluator { loop_depth: 0, call_depth: 0, + call_stack: Vec::new(), module_cache: HashMap::new(), }; e.preload_stdlib(); @@ -1696,9 +1704,17 @@ impl Evaluator { extended.borrow_mut().set(param.name.clone(), val) } + self.call_stack.push(CallFrame{ + name:parameters[0].name.clone(), + call_line:line, + call_column:column + }); + self.call_depth += 1; let result = self.eval_statement(&body, &extended); self.call_depth -= 1; + self.call_stack.pop(); + match result { Object::Return(v) => *v, other => other, diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 56d1fff..a268486 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -226,6 +226,9 @@ impl Parser { } // cur_token is ';' or last token of value expression + if !self.expect_peak(TokenType::Semicolon){ + return None; + } let end_line = self.cur_token.line; let end_column = self.cur_token.column + 1; Some(Statement::Const { @@ -1362,7 +1365,9 @@ impl Parser { fn parse_continue_statement(&mut self) -> Option { let line = self.cur_token.line; let column = self.cur_token.column; - self.expect_peak(TokenType::Semicolon); + if !self.expect_peak(TokenType::Semicolon){ + return None; + } // cur_token is ';' if found, otherwise 'continue' let end_line = self.cur_token.line; let end_column = self.cur_token.column + 1; @@ -1377,7 +1382,9 @@ impl Parser { fn parse_break_statement(&mut self) -> Option { let line = self.cur_token.line; let column = self.cur_token.column; - self.expect_peak(TokenType::Semicolon); + if !self.expect_peak(TokenType::Semicolon){ + return None; + } // cur_token is ';' if found, otherwise 'break' let end_line = self.cur_token.line; let end_column = self.cur_token.column + 1; @@ -1648,6 +1655,9 @@ impl Parser { }; // cur_token is ';' or last token of value + if !self.expect_peak(TokenType::Semicolon){ + return None; + } let end_line = self.cur_token.line; let end_column = self.cur_token.column + 1; Some(Statement::Let { diff --git a/src/repl/repl.rs b/src/repl/repl.rs index 80cc39f..049a774 100644 --- a/src/repl/repl.rs +++ b/src/repl/repl.rs @@ -97,10 +97,16 @@ pub fn run_repl() { if !parser.errors.is_empty() { for err in &parser.errors { show_error(&input, &err.message, err.line, err.column); + if !evaluator.call_stack.is_empty() { + for err in evaluator.call_stack.iter().clone() { + show_error(&input, &err.name, err.call_line, err.call_column); + } + } } continue; } + let result = evaluator.eval(&program, &env); match result { Object::Error { @@ -149,6 +155,11 @@ pub fn execute(input: String) { column, } => { show_error(&input, message, line, column); + if !evaluator.call_stack.is_empty(){ + for e in evaluator.call_stack.iter().clone() { + show_error(&input, &e.name, e.call_line, e.call_column); + } + } std::process::exit(1); } Object::Null => {}