Skip to content

Commit

Permalink
Implement pipe to expect opened immediate statement.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Nov 24, 2020
1 parent f770ee5 commit 2ecefec
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 42 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/error/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 11 additions & 3 deletions src/fmt/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, "_"),
}
}
Expand Down Expand Up @@ -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."),
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/node/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum NodeKind {
Fn,
LBrace,
RBrace,
Pipe,
UnderScore,
NewVar(i32),
ReAssignVar(i32),
Expand Down Expand Up @@ -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)
}
Expand Down
59 changes: 50 additions & 9 deletions src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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 => {
Expand Down Expand Up @@ -301,6 +302,9 @@ impl NodeArr {
NodeKind::LBrace => {
self.parse_stmt(it, n)?;
}
NodeKind::Pipe => {
self.parse_pipe(it)?;
}
_ => unreachable!(),
}
}
Expand Down Expand Up @@ -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<NodeSt, ParseError> {
pub fn parse_close_imm(&mut self, it: &mut TokenIter) -> Result<NodeSt, ParseError> {
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 => {
Expand All @@ -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(),
)),
}
Expand All @@ -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(),
)),
}
Expand All @@ -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(),
)),
}
Expand All @@ -602,8 +623,28 @@ impl NodeArr {
}
}

pub fn parse_close_imm(&mut self, it: &mut TokenIter) -> Result<NodeSt, ParseError> {
Ok(self.parse_imm(it)?)
pub fn parse_opened_imm(&mut self, it: &mut TokenIter) -> Result<NodeSt, ParseError> {
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),
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
39 changes: 22 additions & 17 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -350,23 +359,19 @@ impl<'a> TokenIter<'a> {
}

pub fn consume_cond(&mut self) -> Result<NodeSt, ParseError> {
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> {
Expand Down
36 changes: 32 additions & 4 deletions src/tests/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,29 +346,57 @@ 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,
},
};
assert!(n)
}

#[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)
}
2 changes: 2 additions & 0 deletions src/token/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub enum TokenKind {
Fn,
LBrace,
RBrace,
Pipe,
UnderScore,
}

Expand Down Expand Up @@ -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
}

Expand Down
7 changes: 4 additions & 3 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"

0 comments on commit 2ecefec

Please sign in to comment.