From 4df4ee844b75715870242e2cbe8bfa00ae52ca02 Mon Sep 17 00:00:00 2001 From: YSawc Date: Thu, 15 Oct 2020 23:16:55 +0900 Subject: [PATCH] Implement groval variable. --- src/node_arr/node_arr.rs | 18 ++++-- src/program/program.rs | 82 ++++++++++++++++++++++-- src/tests/parser/tests.rs | 28 ++++---- src/tests/simplified/simplified/tests.rs | 4 +- src/tests/var/tests.rs | 14 ++-- src/var/var.rs | 11 +++- test.sh | 8 +++ 7 files changed, 129 insertions(+), 36 deletions(-) diff --git a/src/node_arr/node_arr.rs b/src/node_arr/node_arr.rs index b1b9771..326edb7 100644 --- a/src/node_arr/node_arr.rs +++ b/src/node_arr/node_arr.rs @@ -1,6 +1,7 @@ use super::super::location::location::*; use super::super::node::node::*; use super::super::parser::error::*; +use super::super::program::program::*; use super::super::simplified::*; use super::super::token::token::*; use super::super::var::var::*; @@ -34,8 +35,8 @@ impl NodeArr { pub fn w_parser( mut it: &mut std::iter::Peekable>>, + g: Vec, ) -> Result { - let et = it.to_owned(); if it.peek().unwrap().value != TokenKind::Fn { return Err(ParseError::OperatorOutOfFnction( @@ -60,7 +61,7 @@ impl NodeArr { } it.next(); - let l = Self::stp(&mut it); + let l = Self::stp(&mut it, g); if isi { match l.to_owned()?.to_owned().ret_node_st.c.value { @@ -95,6 +96,7 @@ impl NodeArr { pub fn stp( mut it: &mut std::iter::Peekable>>, + g: Vec, ) -> Result { let mut uv: Vec = vec![]; let mut nv = vec![]; @@ -127,7 +129,7 @@ impl NodeArr { } } - match Self::find_l(_s.to_owned(), l.to_owned()) { + match Program::find_v(_s.to_owned(), g.to_owned(), l.to_owned()) { Some(mut f) => { match uv.contains(&f.to_owned().s.to_owned()) { true => (), @@ -136,6 +138,7 @@ impl NodeArr { uv.retain(|s| s != &f.to_owned().s.to_owned()); let mut n = vex( &mut n.to_owned().rhs.unwrap().to_owned(), + g.to_owned(), l.to_owned(), &mut uv, ); @@ -148,6 +151,7 @@ impl NodeArr { _ => { let mut n = vex( &mut n.to_owned().rhs.unwrap().to_owned(), + g.to_owned(), l.to_owned(), &mut uv, ); @@ -170,7 +174,7 @@ impl NodeArr { } } - match Self::find_l(_s.to_owned(), l.to_owned()) { + match Program::find_v(_s.to_owned(), g.to_owned(), l.to_owned()) { Some(mut f) => { // println!("uv: {:?}", uv); match uv.contains(&f.to_owned().s.to_owned()) { @@ -179,6 +183,7 @@ impl NodeArr { } let mut n = vex( &mut n.to_owned().rhs.unwrap().to_owned(), + g.to_owned(), l.to_owned(), &mut uv, ); @@ -207,7 +212,7 @@ impl NodeArr { r = n.to_owned(); n } - NodeKind::Ident(s) => match Self::find_l(s, l.to_owned()) { + NodeKind::Ident(s) => match Program::find_v(s, g.to_owned(), l.to_owned()) { Some(v) => { if it.peek().unwrap().to_owned().to_owned().value == TokenKind::RBrace { b = true; @@ -232,6 +237,7 @@ impl NodeArr { } let mut c = vex( &mut n.to_owned().cond.unwrap().to_owned(), + g.to_owned(), l.to_owned(), &mut uv, ); @@ -262,7 +268,7 @@ impl NodeArr { b = true; } - let n = vex(&mut n.to_owned(), l.to_owned(), &mut uv); + let n = vex(&mut n.to_owned(), g.to_owned(), l.to_owned(), &mut uv); if b { r = n.to_owned(); } diff --git a/src/program/program.rs b/src/program/program.rs index 4003a86..22eb828 100644 --- a/src/program/program.rs +++ b/src/program/program.rs @@ -1,9 +1,10 @@ -// use super::super::location::location::*; +use super::super::location::location::*; // use super::super::node::node::*; +use super::super::node::node::*; use super::super::node_arr::node_arr::*; use super::super::parser::error::*; // use super::super::parser::parser::*; -// use super::super::simplified::*; +use super::super::simplified::*; use super::super::token::token::*; use super::super::var::var::*; @@ -37,10 +38,83 @@ impl Program { } pub fn w_parser(vt: Vec) -> Result { - let g: Vec = vec![]; + // let g: Vec = vec![]; let mut na: Vec = vec![]; let mut it = vt.iter().peekable(); - na.push(NodeArr::w_parser(&mut it)?); + + // while it.peek().unwrap().value != TokenKind::Fn {} + let g: Vec = Self::stp(&mut it)?; + // g.puch + + na.push(NodeArr::w_parser(&mut it, g.to_owned())?); Ok(Self::new(g, na)) } + + pub fn stp( + mut it: &mut std::iter::Peekable>>, + ) -> Result, ParseError> { + let mut uv: Vec = vec![]; + let mut _l = vec![]; + let mut g: Vec = vec![]; + // let mut r : NodeSt = NodeSt::default(); + let mut b = false; + while it.peek().unwrap().value != TokenKind::Fn && b == false { + match NodeSt::parser(&mut it) { + Ok(n) => match n.c.value { + NodeKind::Fn => { + b = true; + } + NodeKind::NewAssign => { + let mut _s = String::new(); + match n.to_owned().lhs.unwrap().c.value { + NodeKind::Ident(si) => _s = si, + _ => { + match n.to_owned().lhs.unwrap().lhs.unwrap().c.value { + NodeKind::Ident(si) => _s = si, + _ => unreachable!(), + }; + } + } + match NodeArr::find_l(_s.to_owned(), g.to_owned()) { + Some(mut f) => { + match uv.contains(&f.to_owned().s.to_owned()) { + true => (), + false => return Err(ParseError::UnusedVariable(f.n.c.loc)), + } + uv.retain(|s| s != &f.to_owned().s.to_owned()); + let mut n = vex( + &mut n.to_owned().rhs.unwrap().to_owned(), + g.to_owned(), + _l.to_vec(), + &mut uv, + ); + n = simplified::exec(n); + f.n = n; + let ff = f.to_owned(); + g.retain(|s| s.s != _s.to_owned()); + g.push(ff); + } + _ => { + let mut n = vex( + &mut n.to_owned().rhs.unwrap().to_owned(), + g.to_owned(), + _l.to_vec(), + &mut uv, + ); + n = simplified::exec(n); + let v = Var::new(_s, n); + g.push(v); + } + } + continue; + } + _ => return Err(ParseError::Eof), + }, + Err(e) => return Err(e), + } + } + + println!("g: {:?}", g); + return Ok(g); + } } diff --git a/src/tests/parser/tests.rs b/src/tests/parser/tests.rs index 2761bfe..ffb90cf 100644 --- a/src/tests/parser/tests.rs +++ b/src/tests/parser/tests.rs @@ -13,7 +13,7 @@ use super::super::super::token::token::*; 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).unwrap().ret_node_st; + let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st; let e = { NodeSt { c: Node::plus(Loc::new(14, 15)), @@ -29,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).unwrap().ret_node_st; + let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st; let e = { NodeSt { c: Node::plus(Loc::new(14, 15)), @@ -45,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).unwrap().ret_node_st; + let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st; let e = { NodeSt::num(3, n.to_owned().c.loc) }; assert_eq!(e, n) } @@ -54,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).unwrap().ret_node_st; + let n = NodeArr::w_parser(&mut t, vec![]).unwrap().ret_node_st; let e = NodeSt { c: Node::mul(Loc::new(32, 33)), lhs: Some(n.to_owned().lhs.unwrap()), @@ -69,7 +69,7 @@ fn variable_expansion_test() { fn return_with_unclosed_test() { let t = Token::tokenize("fn int { return 3 }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::NotClosedStmt(_) => true, @@ -83,7 +83,7 @@ fn return_with_unclosed_test() { fn operater_after_return_test() { let t = Token::tokenize("fn int { return 3; 4 }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::OperatorAfterRetrun(_) => true, @@ -97,7 +97,7 @@ fn operater_after_return_test() { fn not_exit_when_failed_parser_test() { let t = Token::tokenize("fn { +3 }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(_) => true, }; @@ -108,7 +108,7 @@ fn not_exit_when_failed_parser_test() { fn not_number_test() { let t = Token::tokenize("fn { 5+ }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::NotNumber(_) => true, @@ -122,7 +122,7 @@ fn not_number_test() { fn unclosed_paren_test() { let t = Token::tokenize("fn { 5+(3+2*2 }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::NotClosedParen(_) => true, @@ -136,7 +136,7 @@ fn unclosed_paren_test() { fn operator_out_of_function_test() { let t = Token::tokenize("0; fn { 12+3; }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::OperatorOutOfFnction(_) => true, @@ -150,7 +150,7 @@ fn operator_out_of_function_test() { fn not_match_return_type_test() { let t = Token::tokenize("fn { 12+3; }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::NotMatchReturnType(_) => true, @@ -164,7 +164,7 @@ fn not_match_return_type_test() { fn match_void_type_test() { let t = Token::tokenize("fn { _ }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => true, _ => false, }; @@ -175,7 +175,7 @@ fn match_void_type_test() { fn not_match_void_type_test() { let t = Token::tokenize("fn int { _ }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::NotMatchReturnType(_) => true, @@ -189,7 +189,7 @@ fn not_match_void_type_test() { fn unexpected_underscore_operator_test() { let t = Token::tokenize("fn int { _; 1 }").unwrap(); let mut t = t.iter().peekable(); - let n = match NodeArr::w_parser(&mut t) { + let n = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::UnexpectedUnderScoreOperator(_) => true, diff --git a/src/tests/simplified/simplified/tests.rs b/src/tests/simplified/simplified/tests.rs index b1e0818..a04ed52 100644 --- a/src/tests/simplified/simplified/tests.rs +++ b/src/tests/simplified/simplified/tests.rs @@ -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).unwrap(); + let n = NodeArr::w_parser(&mut t, vec![]).unwrap(); let n = simplified(n).ret_node_st; let l = NodeSt::num(7, Loc::new(12, 13)); assert_eq!(l, n); @@ -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).unwrap(); + let n = NodeArr::w_parser(&mut t, vec![]).unwrap(); let n = simplified(n).ret_node_st; let l = NodeSt::num(1, Loc::new(12, 13)); assert_eq!(l, n); diff --git a/src/tests/var/tests.rs b/src/tests/var/tests.rs index 624397d..5fc52eb 100644 --- a/src/tests/var/tests.rs +++ b/src/tests/var/tests.rs @@ -13,7 +13,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).unwrap().l; + let l = NodeArr::w_parser(&mut t, vec![]).unwrap().l; let loc = l.to_owned(); let mut il = loc.iter(); let mut e: Vec = Vec::new(); @@ -36,7 +36,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).unwrap().l; + let l = NodeArr::w_parser(&mut t, vec![]).unwrap().l; let loc = l.to_owned(); let mut il = loc.iter(); let mut e: Vec = vec![]; @@ -59,7 +59,7 @@ fn update_variable_test() { fn unused_variable_check_for_used_variable_test() { let t = Token::tokenize("fn int { int a = 3; a; int a = 0; int b = 5; a*b }").unwrap(); let mut t = t.iter().peekable(); - let l = match NodeArr::w_parser(&mut t) { + let l = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => true, Err(_) => false, }; @@ -70,7 +70,7 @@ fn unused_variable_check_for_used_variable_test() { fn unused_variable_check_when_parsed_whole_function_test() { let t = Token::tokenize("fn { int a = 3; int b = a; int c = 5; b }").unwrap(); let mut t = t.iter().peekable(); - let l = match NodeArr::w_parser(&mut t) { + let l = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::UnusedVariable(_) => true, @@ -84,7 +84,7 @@ fn unused_variable_check_when_parsed_whole_function_test() { fn unused_variable_check_just_before_overwrite_variable_test() { let t = Token::tokenize("fn { int a = 3; int a = 0; a }").unwrap(); let mut t = t.iter().peekable(); - let l = match NodeArr::w_parser(&mut t) { + let l = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::UnusedVariable(_) => true, @@ -98,7 +98,7 @@ fn unused_variable_check_just_before_overwrite_variable_test() { fn unused_variable_check_for_update_variable_test() { let t = Token::tokenize("fn int { int a = 3; int b = a; int c = 5; a = 1; 0+c+b }").unwrap(); let mut t = t.iter().peekable(); - let l = match NodeArr::w_parser(&mut t) { + let l = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => true, Err(_) => false, }; @@ -109,7 +109,7 @@ fn unused_variable_check_for_update_variable_test() { fn undefined_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) { + let l = match NodeArr::w_parser(&mut t, vec![]) { Ok(_) => false, Err(e) => match e { ParseError::UndefinedVariable(_) => true, diff --git a/src/var/var.rs b/src/var/var.rs index bb79c43..d5c97c8 100644 --- a/src/var/var.rs +++ b/src/var/var.rs @@ -1,5 +1,6 @@ use super::super::node::node::*; -use super::super::node_arr::node_arr::*; +// use super::super::node_arr::node_arr::*; +use super::super::program::program::*; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Var { @@ -20,10 +21,11 @@ impl Var { } } -pub fn vex(ns: &mut NodeSt, vv: Vec, uv: &mut Vec) -> NodeSt { +pub fn vex(ns: &mut NodeSt, g: Vec, vv: Vec, uv: &mut Vec) -> NodeSt { if ns.lhs != None { let l = Some(Box::new(vex( &mut ns.lhs.as_ref().unwrap().to_owned().as_ref().to_owned(), + g.to_owned(), vv.to_owned(), uv, ))); @@ -35,6 +37,7 @@ pub fn vex(ns: &mut NodeSt, vv: Vec, uv: &mut Vec) -> NodeSt { if ns.rhs != None { let r = Some(Box::new(vex( &mut ns.rhs.as_ref().unwrap().to_owned().as_ref().to_owned(), + g.to_owned(), vv.to_owned(), uv, ))); @@ -45,7 +48,7 @@ pub fn vex(ns: &mut NodeSt, vv: Vec, uv: &mut Vec) -> NodeSt { match ns.c.value.to_owned() { NodeKind::Ident(s) => { - let n = NodeArr::find_l(s, vv.to_owned()).unwrap(); + let n = Program::find_v(s, g.to_owned(), vv.to_owned()).unwrap(); ns.c = n.to_owned().n.c; if uv.contains(&n.to_owned().s.to_owned()) { } else { @@ -54,6 +57,7 @@ pub fn vex(ns: &mut NodeSt, vv: Vec, uv: &mut Vec) -> NodeSt { if n.n.lhs != None { ns.lhs = Some(Box::new(vex( &mut n.n.lhs.as_ref().unwrap().to_owned().as_ref().to_owned(), + g.to_owned(), vv.to_owned(), uv, ))); @@ -61,6 +65,7 @@ pub fn vex(ns: &mut NodeSt, vv: Vec, uv: &mut Vec) -> NodeSt { if n.n.rhs != None { ns.rhs = Some(Box::new(vex( &mut n.n.rhs.as_ref().unwrap().to_owned().as_ref().to_owned(), + g.to_owned(), vv.to_owned(), uv, ))); diff --git a/test.sh b/test.sh index c635c10..3f4725b 100644 --- a/test.sh +++ b/test.sh @@ -70,6 +70,14 @@ assert 0 'fn { _ }' assert 0 'fn { int vvv = 55; 0*vvv*0; _ }' assert 0 'fn { int vvv = 4; 1+2*vvv/4-1; _; }' assert 0 'fn { int vvv = 4; 1+2*vvv/4-1; _ }' simplified +assert 27 'int g = 9; fn int { g*3 }' +assert 8 'int g = 8; fn int { int v = 4; 1+v*g/4-1 }' +assert 8 'int g = 8; fn int { int v = 4; 1+v*g/4-1; }' +# assert 8 'int g = 8; fn int { int v = 4; return 1+v*g/4-1; }' +assert 0 'int g = 2; fn { int v = 4; 1+v*g/4-1; _ }' +assert 0 'int g = 2; fn { int v = 4; 1+v*g/4-1; _ }' simplified +assert 10 'int g = 2; int l = 3; int o = 4; fn int { int v = 4; l+v*o/g-1; }' simplified +assert 0 'int g = 2; int l = 3; int o = 4; fn { int v = 4; l+v*o/g-1; _ }' echo "------------------------------" echo "All test passed!"