Skip to content

Commit

Permalink
Implement unused variable checker for global variables.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Oct 18, 2020
1 parent f92df3c commit a8c70e5
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 51 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ A toy compiler implemented by rust.
- [x] [beta](https://github.com/YSawc/lio/commit/dd6dd3de39019f4c7bec2677140fb22e9f06fcc9)
- [x] [simplified](https://github.com/YSawc/lio/commit/9c70dd681b3d85dbfdbd01e9c039cda9a8a7597b)
- [ ] unused variable checker
- [ ] grobal
- [ ] global
- [x] [local](https://github.com/YSawc/lio/commit/da07a3dc4c1985c2116da6e4e94554c51d51e30c)
- [x] [not checkes for under score variable](https://github.com/YSawc/lio/commit/0c95ef3d9c57e8578d584aaef5dc42fca986a3c9)
- [x] [checker for return type](https://github.com/YSawc/lio/commit/cb7864e64982aeb98adda36f606e96cb451b0784)
33 changes: 21 additions & 12 deletions src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl NodeArr {
pub fn w_parser(
mut it: &mut std::iter::Peekable<std::slice::Iter<Annot<TokenKind>>>,
g: Vec<Var>,
) -> Result<Self, ParseError> {
) -> Result<(Self, Vec<String>), ParseError> {
let et = it.to_owned();
if it.peek().unwrap().value != TokenKind::Fn {
return Err(ParseError::OperatorOutOfFnction(
Expand All @@ -64,10 +64,10 @@ impl NodeArr {

let mut ev: Vec<Vec<Var>> = vec![];
ev.push(g.to_owned());
let l = Self::stp(&mut it, ev);
let (l, ugv) = Self::stp(&mut it, ev)?;

if isi {
match l.to_owned()?.to_owned().ret_node_st.c.value {
match l.to_owned().to_owned().ret_node_st.c.value {
NodeKind::Num(_)
| NodeKind::Add
| NodeKind::Sub
Expand All @@ -78,19 +78,19 @@ impl NodeArr {
| NodeKind::L
| NodeKind::LE
| NodeKind::G
| NodeKind::GE => return l,
| NodeKind::GE => return Ok((l, ugv)),
_ => {
return Err(ParseError::NotMatchReturnType(
l.to_owned().unwrap().to_owned().ret_node_st.c.loc,
l.to_owned().to_owned().ret_node_st.c.loc,
))
}
}
} else {
match l.to_owned()?.to_owned().ret_node_st.c.value {
NodeKind::UnderScore => return l,
match l.to_owned().to_owned().ret_node_st.c.value {
NodeKind::UnderScore => return Ok((l, ugv)),
_ => {
return Err(ParseError::NotMatchReturnType(
l.to_owned().unwrap().to_owned().ret_node_st.c.loc,
l.to_owned().to_owned().ret_node_st.c.loc,
))
}
}
Expand All @@ -100,7 +100,7 @@ impl NodeArr {
pub fn stp(
mut it: &mut std::iter::Peekable<std::slice::Iter<Annot<TokenKind>>>,
ev: Vec<Vec<Var>>,
) -> Result<Self, ParseError> {
) -> Result<(Self, Vec<String>), ParseError> {
let mut uv: Vec<String> = vec![];
let mut nv = vec![];
let mut l: Vec<Var> = vec![];
Expand Down Expand Up @@ -235,8 +235,7 @@ impl NodeArr {
{
b = true;
}
if uv.contains(&v.to_owned().s.to_owned()) {
} else {
if !uv.contains(&v.to_owned().s.to_owned()) {
uv.push(v.to_owned().s);
}

Expand Down Expand Up @@ -318,6 +317,16 @@ impl NodeArr {
}
// println!("ret_node_st: {:?}", a.ret_node_st);

Ok(a)
let mut ugv: Vec<String> = vec![];
for evc in ev {
for v in evc {
// println!("v: {:?}", v);
match uv.contains(&v.to_owned().s.to_owned()) {
true => ugv.push(v.to_owned().s.to_owned()),
false => (),
}
}
}
Ok((a, ugv))
}
}
1 change: 0 additions & 1 deletion src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ impl NodeSt {
)?;
let stmt = Self::stmt(it)?;
let mut lhs = Self::new_if(op, cond, stmt);

expect_token(
TokenKind::RBrace,
ParseError::NotClosedStmt(it.peek().unwrap().to_owned().to_owned()),
Expand Down
20 changes: 15 additions & 5 deletions src/program/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,19 @@ impl Program {
let mut it = vt.iter().peekable();
let g: Vec<Var> = Self::stp(&mut it)?;

na.push(NodeArr::w_parser(&mut it, g.to_owned())?);
let (n, mut ugv) = NodeArr::w_parser(&mut it, g.to_owned())?;
for l in g.to_owned() {
if l.to_owned().s.to_owned().as_bytes()[0] == b'_' {
ugv.push(l.to_owned().s);
}
}
for l in g.to_owned() {
match ugv.contains(&l.to_owned().s.to_owned()) {
true => (),
false => return Err(ParseError::UnusedVariable(l.n.c.loc)),
}
}
na.push(n);
Ok(Self::new(g, na))
}

Expand All @@ -53,8 +65,8 @@ impl Program {
let mut b = false;
while it.peek().unwrap().value != TokenKind::Fn && b == false {
let et = it.to_owned();
match NodeSt::parser(&mut it) {
Ok(n) => match n.c.value {
match NodeSt::parser(&mut it)? {
n => match n.c.value {
NodeKind::Fn => {
b = true;
}
Expand Down Expand Up @@ -108,10 +120,8 @@ impl Program {
))
}
},
Err(e) => return Err(e),
}
}

println!("g: {:?}", g);
return Ok(g);
}
Expand Down
30 changes: 4 additions & 26 deletions src/tests/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ use super::super::super::node_arr::node_arr::*;
#[cfg(test)]
use super::super::super::parser::error::*;
#[cfg(test)]
use super::super::super::program::program::*;
#[cfg(test)]
use super::super::super::token::token::*;

#[test]
fn parser_test() {
let t = Token::tokenize("fn int { 12+3; }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st;
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0.ret_node_st;
let e = {
NodeSt {
c: Node::plus(Loc::new(14, 15)),
Expand All @@ -31,7 +29,7 @@ fn parser_test() {
fn evaluation_final_value_test() {
let t = Token::tokenize("fn int { 12+3 }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st;
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0.ret_node_st;
let e = {
NodeSt {
c: Node::plus(Loc::new(14, 15)),
Expand All @@ -47,7 +45,7 @@ fn evaluation_final_value_test() {
fn parser_assign_test() {
let t = Token::tokenize("fn int { int a = 3; a }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st;
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0.ret_node_st;
let e = { NodeSt::num(3, n.to_owned().c.loc) };
assert_eq!(e, n)
}
Expand All @@ -56,7 +54,7 @@ fn parser_assign_test() {
fn variable_expansion_test() {
let t = Token::tokenize("fn int { int a = 3; int b = 5; b*a; }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st;
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0.ret_node_st;
let e = NodeSt {
c: Node::mul(Loc::new(32, 33)),
lhs: Some(n.to_owned().lhs.unwrap()),
Expand Down Expand Up @@ -270,23 +268,3 @@ fn eof_around_closed_else_stmt_test() {
};
assert!(n)
}

// #[test]
// fn unused_variable_check_for_under_score_grobal_variable() {
// let t = Token::tokenize("int _g = 10; fn { _ }").unwrap();
// let n = match Program::w_parser(t) {
// Ok(_) => true,
// Err(_) => false,
// };
// assert!(n)
// }

#[test]
fn unused_variable_check_for_under_score_local_variable() {
let t = Token::tokenize("fn { int _g = 10; _ }").unwrap();
let n = match Program::w_parser(t) {
Ok(_) => true,
Err(_) => false,
};
assert!(n)
}
4 changes: 2 additions & 2 deletions src/tests/simplified/simplified/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::super::super::super::token::token::*;
fn simplified_test() {
let t = Token::tokenize("fn int { 2*(2-1)+5; }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0;
let n = simplified(n).ret_node_st;
let l = NodeSt::num(7, Loc::new(12, 13));
assert_eq!(l, n);
Expand All @@ -23,7 +23,7 @@ fn simplified_test() {
fn simplified_with_minus_test() {
let t = Token::tokenize("fn int { 2*(2-4)+5; }").unwrap();
let mut t = t.iter().peekable();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap();
let n = NodeArr::w_parser(&mut t, vec![]).unwrap().0;
let n = simplified(n).ret_node_st;
let l = NodeSt::num(1, Loc::new(12, 13));
assert_eq!(l, n);
Expand Down
28 changes: 24 additions & 4 deletions src/tests/var/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use super::super::super::var::var::*;
fn simplified_variable_under_initialize_test() {
let t = Token::tokenize("fn int { int a = 2; int b = 8*a; int c = 2*b+a; c; }").unwrap();
let mut t = t.iter().peekable();
let l = NodeArr::w_parser(&mut t, vec![]).unwrap().l;
let l = NodeArr::w_parser(&mut t, vec![]).unwrap().0.l;
let loc = l.to_owned();
let mut il = loc.iter();
let mut e: Vec<Var> = Vec::new();
Expand All @@ -38,7 +38,7 @@ fn simplified_variable_under_initialize_test() {
fn update_variable_test() {
let t = Token::tokenize("fn int { int a = 3; int b = a; int c = 5; a = 1; a+c+b }").unwrap();
let mut t = t.iter().peekable();
let l = NodeArr::w_parser(&mut t, vec![]).unwrap().l;
let l = NodeArr::w_parser(&mut t, vec![]).unwrap().0.l;
let loc = l.to_owned();
let mut il = loc.iter();
let mut e: Vec<Var> = vec![];
Expand Down Expand Up @@ -108,7 +108,7 @@ fn unused_variable_check_for_update_variable_test() {
}

#[test]
fn undefined_variable_test() {
fn undefined_variable_check_for_local_variable_test() {
let t = Token::tokenize("fn { int a = 3; d = 1; a }").unwrap();
let mut t = t.iter().peekable();
let l = match NodeArr::w_parser(&mut t, vec![]) {
Expand All @@ -122,7 +122,17 @@ fn undefined_variable_test() {
}

#[test]
fn unused_variable_fo_groval_for_test() {
fn unused_variable_check_for_under_score_local_variable() {
let t = Token::tokenize("fn { int _g = 10; _ }").unwrap();
let n = match Program::w_parser(t) {
Ok(_) => true,
Err(_) => false,
};
assert!(n)
}

#[test]
fn unused_variable_check_for_global_variable_test() {
let t = Token::tokenize("int g = 10; fn int { int g = 3; g }").unwrap();
let l = match Program::w_parser(t) {
Ok(_) => false,
Expand All @@ -133,3 +143,13 @@ fn unused_variable_fo_groval_for_test() {
};
assert!(l)
}

#[test]
fn unused_variable_check_for_under_score_global_variable() {
let t = Token::tokenize("int _g = 10; fn { _ }").unwrap();
let n = match Program::w_parser(t) {
Ok(_) => true,
Err(_) => false,
};
assert!(n)
}

0 comments on commit a8c70e5

Please sign in to comment.