From 2ecefecf6447c71f5dd78fcb442df74989033d66 Mon Sep 17 00:00:00 2001 From: YSawc Date: Wed, 25 Nov 2020 06:52:42 +0900 Subject: [PATCH] Implement pipe to expect opened immediate statement. --- README.md | 1 + src/error/error.rs | 3 +- src/fmt/fmt.rs | 14 ++++++++-- src/node/node.rs | 4 +++ src/node_arr/node_arr.rs | 59 +++++++++++++++++++++++++++++++++------ src/parser/error.rs | 7 ++--- src/parser/parser.rs | 39 +++++++++++++++----------- src/tests/parser/tests.rs | 36 +++++++++++++++++++++--- src/token/token.rs | 2 ++ test.sh | 7 +++-- 10 files changed, 130 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 8466743..e016909 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"` - [x] [checker for return type](https://github.com/YSawc/lio/commit/cb7864e64982aeb98adda36f606e96cb451b0784) - [x] [checker return same types for statements](https://github.com/YSawc/lio/commit/5a23a108d809bf110e7ad18df9791b4fb606fc82) - [x] multiple if label [1](https://github.com/YSawc/lio/commit/3b0f2ec7e102c8cea78baa0c24f715f59339632c), [2](https://github.com/YSawc/lio/commit/52bd10a754e341e00d6080c917420807db17ddd8), [3](https://github.com/YSawc/lio/commit/3b0f2ec7e102c8cea78baa0c24f715f59339632c) +- [ ] touple - [ ] multiple error notification - [x] [tokenize](https://github.com/YSawc/lio/commit/d09ae5afe26fd3daf1dcddd3dd333224cffe247c) - [ ] parser diff --git a/src/error/error.rs b/src/error/error.rs index 3b64302..559ec50 100644 --- a/src/error/error.rs +++ b/src/error/error.rs @@ -82,7 +82,8 @@ impl Error { | ParseError::NotMatchReturnType(loc) | ParseError::UnexpectedUnderScoreOperator(loc) | ParseError::NotMatchTypeAnotherOneOfStatement(loc) - | ParseError::NotImmediate(loc) => loc.clone(), + | ParseError::NotClosedImmediate(loc) + | ParseError::NotOpenedImmediate(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 ce18dca..16387b3 100644 --- a/src/fmt/fmt.rs +++ b/src/fmt/fmt.rs @@ -41,6 +41,7 @@ impl fmt::Display for TokenKind { TokenKind::Fn => write!(f, "fn"), TokenKind::LBrace => write!(f, "{{"), TokenKind::RBrace => write!(f, "}}"), + TokenKind::Pipe => write!(f, "|"), TokenKind::UnderScore => write!(f, "_"), } } @@ -115,9 +116,16 @@ impl fmt::Display for ParseError { "{}: Expected match return type of each statement but not match.", loc ), - ParseError::NotImmediate(loc) => { - write!(f, "{}: Expected immediate statement but not match.", loc) - } + ParseError::NotClosedImmediate(loc) => write!( + f, + "{}: Expected closed immediate statement but not match.", + loc + ), + ParseError::NotOpenedImmediate(loc) => write!( + f, + "{}: Expected opened immediate statement but not match.", + loc + ), ParseError::Eof => write!(f, "Expected token, but not detected."), } } diff --git a/src/node/node.rs b/src/node/node.rs index 216057e..e3c7760 100644 --- a/src/node/node.rs +++ b/src/node/node.rs @@ -29,6 +29,7 @@ pub enum NodeKind { Fn, LBrace, RBrace, + Pipe, UnderScore, NewVar(i32), ReAssignVar(i32), @@ -129,6 +130,9 @@ impl Node { pub fn st(loc: Loc) -> Self { Self::new(NodeKind::LBrace, loc) } + pub fn pipe(loc: Loc) -> Self { + Self::new(NodeKind::Pipe, loc) + } pub fn mfn(loc: Loc) -> Self { Self::new(NodeKind::Fn, loc) } diff --git a/src/node_arr/node_arr.rs b/src/node_arr/node_arr.rs index afe4af0..a8ba4bd 100644 --- a/src/node_arr/node_arr.rs +++ b/src/node_arr/node_arr.rs @@ -161,7 +161,7 @@ impl NodeArr { it.expect_token( TokenKind::RBrace, - ParseError::NotOpenedStmt(it.p.to_owned().peek().unwrap().to_owned().to_owned()), + ParseError::NotClosedStmt(it.p.to_owned().peek().unwrap().to_owned().to_owned()), )?; Ok((narr, uev)) @@ -181,7 +181,8 @@ impl NodeArr { | NodeKind::UnderScore | NodeKind::If | NodeKind::While - | NodeKind::LBrace => { + | NodeKind::LBrace + | NodeKind::Pipe => { // println!("n.c.value: {:?}", n.c.value); match n.c.value { NodeKind::Return => { @@ -301,6 +302,9 @@ impl NodeArr { NodeKind::LBrace => { self.parse_stmt(it, n)?; } + NodeKind::Pipe => { + self.parse_pipe(it)?; + } _ => unreachable!(), } } @@ -520,16 +524,33 @@ impl NodeArr { return Ok(()); } + + pub fn parse_pipe(&mut self, it: &mut TokenIter) -> Result<(), ParseError> { + it.next(); + + it.copy_iter(); + let n = self.parse_opened_imm(it)?; + self.node_st_vec.push(n.to_owned()); + + if it.peek_value() != TokenKind::RBrace { + return Err(ParseError::NotClosedStmt(it.next())); + } + + self.set_end_of_node(); + self.set_ret_node(n.to_owned()); + + Ok(()) + } } impl NodeArr { - pub fn parse_imm(&mut self, it: &mut TokenIter) -> Result { + pub fn parse_close_imm(&mut self, it: &mut TokenIter) -> Result { match NodeSt::parser(it) { Ok(n) => match n.c.value { NodeKind::Return | NodeKind::NewAssign | NodeKind::Assign - | NodeKind::UnderScore => Err(ParseError::NotImmediate( + | NodeKind::UnderScore => Err(ParseError::NotClosedImmediate( it.shadow_p.peek().unwrap().loc.to_owned(), )), NodeKind::If => { @@ -544,7 +565,7 @@ impl NodeArr { .ret_node_st, ) { true => Ok(self.pop_node()), - false => Err(ParseError::NotImmediate( + false => Err(ParseError::NotClosedImmediate( it.shadow_p.peek().unwrap().loc.to_owned(), )), } @@ -561,7 +582,7 @@ impl NodeArr { .ret_node_st, ) { true => Ok(self.pop_node()), - false => Err(ParseError::NotImmediate( + false => Err(ParseError::NotClosedImmediate( it.shadow_p.peek().unwrap().loc.to_owned(), )), } @@ -578,7 +599,7 @@ impl NodeArr { .ret_node_st, ) { true => Ok(self.pop_node()), - false => Err(ParseError::NotImmediate( + false => Err(ParseError::NotClosedImmediate( it.shadow_p.peek().unwrap().loc.to_owned(), )), } @@ -602,8 +623,28 @@ impl NodeArr { } } - pub fn parse_close_imm(&mut self, it: &mut TokenIter) -> Result { - Ok(self.parse_imm(it)?) + pub fn parse_opened_imm(&mut self, it: &mut TokenIter) -> Result { + match NodeSt::parser(it) { + Ok(n) => match n.c.value { + NodeKind::Return + | NodeKind::NewAssign + | NodeKind::Assign + | NodeKind::UnderScore + | NodeKind::If + | NodeKind::While + | NodeKind::LBrace => Err(ParseError::NotOpenedImmediate( + it.shadow_p.peek().unwrap().loc.to_owned(), + )), + _ => { + self.set_imm_env(); + let mut n = n; + n = beta(&mut n, self)?; + n = n.simplified(); + Ok(n) + } + }, + Err(e) => return Err(e), + } } } diff --git a/src/parser/error.rs b/src/parser/error.rs index eb1da0b..3ffc4fe 100644 --- a/src/parser/error.rs +++ b/src/parser/error.rs @@ -23,10 +23,7 @@ pub enum ParseError { NotMatchReturnType(Loc), UnexpectedUnderScoreOperator(Loc), NotMatchTypeAnotherOneOfStatement(Loc), - NotImmediate(Loc), - // UnexpectedToken(Token), - // NotExpression(Token), - // UnclosedOpenParen(Token), - // RedundantExpression(Token), + NotClosedImmediate(Loc), + NotOpenedImmediate(Loc), Eof, } diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 6d132a0..aba147f 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -64,6 +64,7 @@ impl NodeSt { | TokenKind::If | TokenKind::While | TokenKind::LBrace + | TokenKind::Pipe | TokenKind::UnderScore => match it.p.peek().unwrap() { Token { value: TokenKind::Return, @@ -136,6 +137,14 @@ impl NodeSt { let lhs = Self::new_node(st); return Ok(lhs); } + Token { + value: TokenKind::Pipe, + loc, + } => { + let op = Node::pipe(loc.to_owned()); + let lhs = Self::new_node(op); + return Ok(lhs); + } Token { value: TokenKind::UnderScore, loc, @@ -350,23 +359,19 @@ impl<'a> TokenIter<'a> { } pub fn consume_cond(&mut self) -> Result { - self.expect_token( - TokenKind::LParen, - ParseError::NotOpenedParen( - self.p.to_owned().peek().unwrap().to_owned().to_owned(), - ), - )?; - - let cond = NodeSt::cmp(self)?; - - self.expect_token( - TokenKind::RParen, - ParseError::NotClosedStmt( - self.p.to_owned().peek().unwrap().to_owned().to_owned(), - ), - )?; - - Ok(cond) + self.expect_token( + TokenKind::LParen, + ParseError::NotOpenedParen(self.p.to_owned().peek().unwrap().to_owned().to_owned()), + )?; + + let cond = NodeSt::cmp(self)?; + + self.expect_token( + TokenKind::RParen, + ParseError::NotClosedStmt(self.p.to_owned().peek().unwrap().to_owned().to_owned()), + )?; + + Ok(cond) } pub fn unexpect_token(&mut self, ty: TokenKind, err: ParseError) -> Result<(), ParseError> { diff --git a/src/tests/parser/tests.rs b/src/tests/parser/tests.rs index 87fe1ff..77f3114 100644 --- a/src/tests/parser/tests.rs +++ b/src/tests/parser/tests.rs @@ -346,13 +346,13 @@ fn checker_for_not_definition_variable_in_multiple_evaluation_values_test() { } #[test] -fn check_immediate_in_new_assign_test() { +fn check_closed_immediate_in_new_assign_test() { let mut t = Token::tokenize("fn { int aa = return 9; _ }").unwrap(); let mut it = TokenIter::new(&mut t); let n = match NodeArr::w_parser(&mut it, vec![]) { Ok(_) => false, Err(e) => match e { - ParseError::NotImmediate(_) => true, + ParseError::NotClosedImmediate(_) => true, _ => false, }, }; @@ -360,15 +360,43 @@ fn check_immediate_in_new_assign_test() { } #[test] -fn check_immediate_in_assign_test() { +fn check_closed_immediate_in_assign_test() { let mut t = Token::tokenize("fn { int aa = 9; aa; aa = return 3; _ }").unwrap(); let mut it = TokenIter::new(&mut t); let n = match NodeArr::w_parser(&mut it, vec![]) { Ok(_) => false, Err(e) => match e { - ParseError::NotImmediate(_) => true, + ParseError::NotClosedImmediate(_) => true, _ => false, }, }; assert!(n) } + +#[test] +fn check_opened_immediate_in_assign_fail_test() { + let mut t = + Token::tokenize("fn int { int i = 0; i = while (i < 30) { i = i + 1; | { i } } i }") + .unwrap(); + let mut it = TokenIter::new(&mut t); + let n = match NodeArr::w_parser(&mut it, vec![]) { + Ok(_) => false, + Err(e) => match e { + ParseError::NotOpenedImmediate(_) => true, + _ => false, + }, + }; + assert!(n) +} + +#[test] +fn check_opened_immediate_in_assign_pass_test() { + let mut t = + Token::tokenize("fn int { int i = 0; i = while (i < 30) { i = i + 1; | i } i }").unwrap(); + let mut it = TokenIter::new(&mut t); + let n = match NodeArr::w_parser(&mut it, vec![]) { + Ok(_) => true, + Err(_) => false, + }; + assert!(n) +} diff --git a/src/token/token.rs b/src/token/token.rs index 2d0f158..ed103e8 100644 --- a/src/token/token.rs +++ b/src/token/token.rs @@ -32,6 +32,7 @@ pub enum TokenKind { Fn, LBrace, RBrace, + Pipe, UnderScore, } @@ -174,6 +175,7 @@ impl Token { map.insert('='.into(), TokenKind::Assign); map.insert('{'.into(), TokenKind::LBrace); map.insert('}'.into(), TokenKind::RBrace); + map.insert('|'.into(), TokenKind::Pipe); map } diff --git a/test.sh b/test.sh index 3643db2..4f449ef 100644 --- a/test.sh +++ b/test.sh @@ -107,9 +107,10 @@ assert_llvm 0 'fn { { _ } }' assert_llvm 90 'fn int { int i = 3; { int i = i*30; i } }' assert_llvm 3 'fn int { int i = 3; { i*30 } i }' assert_llvm 90 'fn int { int i = 3; i = { i*30 } i }' -assert_llvm 10 'fn int { int i = 0; while(i < 10) { i = i + 1; } i }' -assert_llvm 20 'fn int { int i = 0; while(i < 20) { i = i + 1; i } }' -assert_llvm 30 'fn int { int i = 0; i = while(i < 30) { i = i + 1; i } i }' +assert_llvm 10 'fn int { int i = 0; while (i < 10) { i = i + 1; } i }' +assert_llvm 20 'fn int { int i = 0; while (i < 20) { i = i + 1; i } }' +assert_llvm 30 'fn int { int i = 0; i = while (i < 30) { i = i + 1; i } i }' +assert_llvm 30 'fn int { int i = 0; i = while (i < 30) { i = i + 1; | i } i }' echo "------------------------------" echo "All llvm test passed!\n"