Skip to content

Commit

Permalink
FIXED BUG: sym table find if exist logic
Browse files Browse the repository at this point in the history
  • Loading branch information
DrEden33773 committed Dec 25, 2023
1 parent ddca6d7 commit 98cc239
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 63 deletions.
6 changes: 1 addition & 5 deletions examples/correct/fib.pas
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@

program fibonacci;

const index := 30;

var return,i,a;

procedure fib(a,x);

var sum;
begin
sum := 0;
Expand All @@ -31,4 +27,4 @@ procedure fib(a,x);
write(return);
i := i+1
end
end
end
24 changes: 15 additions & 9 deletions examples/correct/multi_arg.pas
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
13 changes: 0 additions & 13 deletions src/pcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
32 changes: 12 additions & 20 deletions src/symbol_table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,23 +20,15 @@ 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()
.all(|scope| curr_scope_list.contains(scope))
})
}

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<usize> {
Expand All @@ -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;
}
}
Expand Down
28 changes: 13 additions & 15 deletions src/translator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand All @@ -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;
Expand Down Expand Up @@ -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))
Expand All @@ -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) {
Expand Down Expand Up @@ -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))
Expand All @@ -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) {
Expand Down Expand Up @@ -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<ConstExpr>]) {
fn const_decl_unfold(&mut self, expr: &[Box<ConstExpr>]) {
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))
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 98cc239

Please sign in to comment.