From 98cc239fc2c8244bd584af5d9f1432685fc8f00c Mon Sep 17 00:00:00 2001 From: DrEden33773 Date: Mon, 25 Dec 2023 21:54:22 +0800 Subject: [PATCH] FIXED BUG: sym table find if exist logic --- examples/correct/fib.pas | 6 +----- examples/correct/multi_arg.pas | 24 +++++++++++++++--------- src/main.rs | 2 +- src/pcode/mod.rs | 13 ------------- src/symbol_table/mod.rs | 32 ++++++++++++-------------------- src/translator/mod.rs | 28 +++++++++++++--------------- 6 files changed, 42 insertions(+), 63 deletions(-) diff --git a/examples/correct/fib.pas b/examples/correct/fib.pas index 51ff0da..ae97a4a 100644 --- a/examples/correct/fib.pas +++ b/examples/correct/fib.pas @@ -1,12 +1,8 @@ - program fibonacci; - const index := 30; - var return,i,a; procedure fib(a,x); - var sum; begin sum := 0; @@ -31,4 +27,4 @@ procedure fib(a,x); write(return); i := i+1 end -end +end \ No newline at end of file diff --git a/examples/correct/multi_arg.pas b/examples/correct/multi_arg.pas index 1ee4043..90efe3e 100644 --- a/examples/correct/multi_arg.pas +++ b/examples/correct/multi_arg.pas @@ -1,19 +1,25 @@ program Add; -const index:=20; +const index := 20; var return,a,b,c,sum; + procedure add(a,b,c); var sum; begin -return:=a+b+c + write(index); + return := a+b+c end; -procedure add1(a,b,c); + +procedure addClosure(a,b,c); +const index := 1; begin -sum:=3 + write(index); + sum := 3 end + begin -read(a,b,c); -call add(b+a,a,c); -call add1(a,b,c); -write(return); -write(sum) + read(a,b,c); + call add(b+a,a,c); + call addClosure(a,b,c); + write(return); + write(sum) end \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 748a75d..58ec31d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,7 @@ mod dbg { #[test] fn dbg() { - let filename = PROJECT_ROOT.to_string() + "/examples/correct/nested_proc.pas"; + let filename = PROJECT_ROOT.to_string() + "/examples/correct/multi_arg.pas"; compile_from_file(&filename); } } diff --git a/src/pcode/mod.rs b/src/pcode/mod.rs index 3bbd783..d37475c 100644 --- a/src/pcode/mod.rs +++ b/src/pcode/mod.rs @@ -21,19 +21,6 @@ pub enum PcodeType { impl Display for PcodeType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // let pcode_type = match self { - // Self::NIL => "NIL", - // Self::LIT => "LIT", - // Self::OPR => "OPR", - // Self::LOD => "LOD", - // Self::STO => "STO", - // Self::CAL => "CAL", - // Self::INT => "INT", - // Self::JMP => "JMP", - // Self::JPC => "JPC", - // Self::RED => "RED", - // Self::WRT => "WRT", - // }; write!(f, "{:?}", self) } } diff --git a/src/symbol_table/mod.rs b/src/symbol_table/mod.rs index 0bb0f56..2e150c3 100644 --- a/src/symbol_table/mod.rs +++ b/src/symbol_table/mod.rs @@ -10,12 +10,7 @@ pub struct SymTable { } impl SymTable { - pub fn try_find_closest_sym( - &self, - name: &str, - curr_level: usize, - curr_scope_list: &[String], - ) -> Option<&TableRow> { + pub fn try_find_closest_sym(&self, name: &str, curr_scope_list: &[String]) -> Option<&TableRow> { // must `rev()` // // you should find a symbol with as higher level as you can @@ -25,7 +20,6 @@ impl SymTable { // another condition: sym.scope_list was totally contained by curr_scope_list self.table.iter().rev().find(|&sym| { sym.name == name - && sym.level <= curr_level && sym .scope_list .iter() @@ -33,15 +27,8 @@ impl SymTable { }) } - pub fn find_closest_sym( - &self, - name: &str, - curr_level: usize, - curr_scope_list: &[String], - ) -> &TableRow { - self - .try_find_closest_sym(name, curr_level, curr_scope_list) - .unwrap() + pub fn find_closest_sym(&self, name: &str, curr_scope_list: &[String]) -> &TableRow { + self.try_find_closest_sym(name, curr_scope_list).unwrap() } pub fn get_proc_in_curr_level(&self) -> Option { @@ -53,18 +40,23 @@ impl SymTable { None } - pub fn is_pre_exists(&self, name: &str, level: usize) -> bool { + pub fn is_pre_exists(&self, name: &str, curr_scope_list: &[String]) -> bool { for sym in &self.table { - if sym.name == name && sym.level <= level { + if sym.name == name + && sym + .scope_list + .iter() + .all(|scope| curr_scope_list.contains(scope)) + { return true; } } false } - pub fn is_now_exists(&self, name: &str, level: usize) -> bool { + pub fn is_now_exists(&self, name: &str, curr_scope_list: &[String]) -> bool { for sym in &self.table { - if sym.name == name && sym.level == level { + if sym.name == name && sym.scope_list == curr_scope_list { return true; } } diff --git a/src/translator/mod.rs b/src/translator/mod.rs index 3c033ad..2f780a6 100644 --- a/src/translator/mod.rs +++ b/src/translator/mod.rs @@ -175,7 +175,7 @@ impl Translator { let name = expr.id.as_ref().0.to_owned(); // duplicate-definition - if self.sym_table.is_now_exists(&name, self.level) { + if self.sym_table.is_now_exists(&name, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(expr.id.as_ref().1) .with_info(format!("`{}` is defined before", name)) @@ -231,7 +231,7 @@ impl Translator { let name = id.as_ref().0.to_owned(); // undefined - if !self.sym_table.is_pre_exists(&name, self.level) { + if !self.sym_table.is_pre_exists(&name, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(id.as_ref().1) .with_info(format!("`{}` is undefined", name)) @@ -243,7 +243,7 @@ impl Translator { // assign to non-var let tmp_sym = self .sym_table - .find_closest_sym(&name, self.level, &self.scope_list) + .find_closest_sym(&name, &self.scope_list) .to_owned(); if !matches!(tmp_sym.ty, SymType::Var) { self.has_error = true; @@ -308,7 +308,7 @@ impl Translator { let name = id.as_ref().0.to_owned(); // undefined - if !self.sym_table.is_pre_exists(&name, self.level) { + if !self.sym_table.is_pre_exists(&name, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(id.as_ref().1) .with_info(format!("`{}` is undefined", name)) @@ -319,7 +319,7 @@ impl Translator { let tmp_sym = self .sym_table - .find_closest_sym(&name, self.level, &self.scope_list) + .find_closest_sym(&name, &self.scope_list) .to_owned(); // call non-proc if !matches!(tmp_sym.ty, SymType::Proc) { @@ -359,7 +359,7 @@ impl Translator { let name = id.as_ref().0.to_owned(); // undefined - if !self.sym_table.is_pre_exists(&name, self.level) { + if !self.sym_table.is_pre_exists(&name, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(id.as_ref().1) .with_info(format!("`{}` is undefined", name)) @@ -370,7 +370,7 @@ impl Translator { let tmp_sym = self .sym_table - .find_closest_sym(&name, self.level, &self.scope_list) + .find_closest_sym(&name, &self.scope_list) .to_owned(); // read to non-var if !matches!(tmp_sym.ty, SymType::Var) { @@ -405,14 +405,14 @@ impl Translator { impl Translator { fn const_decl(&mut self, expr: &ConstDeclExpr) { - self.my_const(&expr.constants); + self.const_decl_unfold(&expr.constants); } - fn my_const(&mut self, expr: &[Box]) { + fn const_decl_unfold(&mut self, expr: &[Box]) { for exp in expr { let id = exp.id.as_ref().0.to_owned(); let val = exp.integer.as_ref().0; - if self.sym_table.is_now_exists(&id, self.level) { + if self.sym_table.is_now_exists(&id, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(exp.id.as_ref().1) .with_info(format!("`{}` is defined before", id)) @@ -431,7 +431,7 @@ impl Translator { // for each id in id_list, you should consider the updating of addr for id_exp in id_list { let id = id_exp.as_ref().0.to_owned(); - if self.sym_table.is_now_exists(&id, self.level) { + if self.sym_table.is_now_exists(&id, &self.scope_list) { self.has_error = true; CompileErrorBuilder::from(id_exp.as_ref().1) .with_info(format!("`{}` is defined before", id)) @@ -511,10 +511,8 @@ impl Translator { FactorExpr::Exp(expr) => self.exp(expr), FactorExpr::Id(expr) => { let id = expr.0.to_owned(); - if self.sym_table.is_pre_exists(&id, self.level) { - let tmp_sym = self - .sym_table - .find_closest_sym(&id, self.level, &self.scope_list); + if self.sym_table.is_pre_exists(&id, &self.scope_list) { + let tmp_sym = self.sym_table.find_closest_sym(&id, &self.scope_list); match tmp_sym.ty { SymType::Nil => { self.has_error = true;