diff --git a/src/error/error.rs b/src/error/error.rs index 66f9f3d..0a26933 100644 --- a/src/error/error.rs +++ b/src/error/error.rs @@ -58,7 +58,8 @@ impl Error { | ParseError::NotClosedStmt(loc, ..) | ParseError::OperatorAfterRetrun(loc, ..) | ParseError::NotIdent(loc, ..) - | ParseError::NotAssign(loc, ..) => loc.loc.clone(), + | ParseError::NotAssign(loc, ..) + | ParseError::NotDefinitionVar(loc, ..) => loc.loc.clone(), ParseError::Eof => Loc::new(input.len() as u8, input.len() as u8 + 1), }; (e, loc) diff --git a/src/fmt/fmt.rs b/src/fmt/fmt.rs index 0bde1d7..db0e745 100644 --- a/src/fmt/fmt.rs +++ b/src/fmt/fmt.rs @@ -66,6 +66,11 @@ impl fmt::Display for ParseError { ParseError::NotAssign(tok) => { write!(f, "{}: Expected assign but got {}.", tok.loc, tok.value) } + ParseError::NotDefinitionVar(tok) => write!( + f, + "{}: Expected definition var but not detected. Failed ident is {}", + tok.loc, tok.value + ), ParseError::Eof => write!(f, "Expected token, but not detected."), } } diff --git a/src/lib.rs b/src/lib.rs index 3241b32..31b3c9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,3 +8,4 @@ pub mod parser; pub mod simplified; pub mod tests; pub mod token; +pub mod var; diff --git a/src/node_arr/node_arr.rs b/src/node_arr/node_arr.rs index a863ef2..5f0574d 100644 --- a/src/node_arr/node_arr.rs +++ b/src/node_arr/node_arr.rs @@ -1,11 +1,24 @@ use super::super::node::node::*; use super::super::parser::error::*; use super::super::token::token::*; +use super::super::var::var::*; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct NodeArr { pub node_st_vec: Vec, pub ret_node_st: NodeSt, + pub l: Vec, +} + +impl NodeArr { + pub fn find_l(s: String, vv: Vec) -> Option { + for v in vv { + if v.s == s { + return Some(v); + } + } + None + } } impl NodeArr { @@ -13,29 +26,52 @@ impl NodeArr { Self { node_st_vec: v.to_owned(), ret_node_st: v.to_owned().last().unwrap().to_owned(), + l: vec![], } } pub fn w_parser(vt: Vec) -> Result { let mut vti = vt.iter().peekable(); - let mut n = vec![]; + let mut nv = vec![]; + let mut l: Vec = vec![]; while vti.peek() != None { - n.push(match NodeSt::parser(&mut vti) { - Ok(n) => { - // println!("n: {:?}", n); - if n.c.value == NodeKind::Return && vti.peek() != None { - return Err(ParseError::OperatorAfterRetrun( - vti.next().unwrap().to_owned(), - )); + nv.push(match NodeSt::parser(&mut vti) { + Ok(n) => match n.c.value { + NodeKind::Return => { + if vti.peek() != None { + return Err(ParseError::OperatorAfterRetrun( + vti.next().unwrap().to_owned(), + )); + } + n + } + NodeKind::Assign => { + let s = match n.to_owned().lhs.unwrap().lhs.unwrap().c.value { + NodeKind::Ident(s) => s, + _ => unreachable!(), + }; + let n = n.lhs.as_ref().unwrap().as_ref().to_owned(); + let v = Var::new(s, n); + l.push(v); + continue; } - n - } + NodeKind::Ident(s) => match Self::find_l(s, l.to_owned()) { + Some(v) => v.n, + None => { + return Err(ParseError::NotDefinitionVar( + vti.next().unwrap().to_owned(), + )) + } + }, + _ => n, + }, Err(e) => return Err(e), }); } - let a = Self::new(n); + let mut a = Self::new(nv); + a.l = l; Ok(a) } } diff --git a/src/parser/error.rs b/src/parser/error.rs index 439d439..1fb4401 100644 --- a/src/parser/error.rs +++ b/src/parser/error.rs @@ -10,6 +10,7 @@ pub enum ParseError { OperatorAfterRetrun(Token), NotIdent(Token), NotAssign(Token), + NotDefinitionVar(Token), // UnexpectedToken(Token), // NotExpression(Token), // UnclosedOpenParen(Token), diff --git a/src/tests/parser/tests.rs b/src/tests/parser/tests.rs index c8e64a0..74f3725 100644 --- a/src/tests/parser/tests.rs +++ b/src/tests/parser/tests.rs @@ -55,37 +55,13 @@ fn evaluation_final_value_test() { #[test] fn parser_assign_test() { - let t = Token::tokenize("int a = 3;").unwrap(); + let t = Token::tokenize("int a = 3; 1").unwrap(); let l = NodeArr::w_parser(t).unwrap().ret_node_st; let e = { NodeSt { - c: Annot { - value: NodeKind::Assign, - loc: Loc { f: 7, e: 8 }, - }, - lhs: Some(Box::new(NodeSt { - c: Annot { - value: NodeKind::Int, - loc: Loc { f: 0, e: 3 }, - }, - lhs: Some(Box::new(NodeSt { - c: Annot { - value: NodeKind::Ident("a".to_string()), - loc: Loc { f: 4, e: 6 }, - }, - lhs: None, - rhs: None, - })), - rhs: None, - })), - rhs: Some(Box::new(NodeSt { - c: Annot { - value: NodeKind::Num(3), - loc: Loc { f: 10, e: 11 }, - }, - lhs: None, - rhs: None, - })), + c: Node::number(1, Loc::new(14, 15)), + lhs: None, + rhs: None, } }; assert_eq!(e, l) diff --git a/src/var/mod.rs b/src/var/mod.rs new file mode 100644 index 0000000..9b21e5b --- /dev/null +++ b/src/var/mod.rs @@ -0,0 +1 @@ +pub mod var; diff --git a/src/var/var.rs b/src/var/var.rs new file mode 100644 index 0000000..864e8e5 --- /dev/null +++ b/src/var/var.rs @@ -0,0 +1,20 @@ +use super::super::node::node::*; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Var { + pub s: String, + pub n: NodeSt, +} + +impl Var { + pub fn new(s: String, n: NodeSt) -> Self { + Self { s, n } + } + + pub fn default() -> Self { + Self { + s: String::new(), + n: NodeSt::default(), + } + } +} diff --git a/test.sh b/test.sh index f8e8408..3129bee 100644 --- a/test.sh +++ b/test.sh @@ -50,6 +50,8 @@ assert 3 '(1*2>=3-(2*1))+2;' simplified assert 4 '4' assert 3 '2; 3' assert 4 'return 4;' +assert 1 'int a = 3; 1;' +assert 2 'int a = 3; return 2;' echo "------------------------------" echo "All test passed!"