Skip to content

Commit

Permalink
Implement checker of NotMatchTypeAnotherOneOfStatement.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Nov 8, 2020
1 parent f991dd9 commit 5a23a10
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 21 deletions.
3 changes: 2 additions & 1 deletion src/error/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ impl Error {
| ParseError::UndefinedVariable(loc)
| ParseError::UnusedVariable(loc)
| ParseError::NotMatchReturnType(loc)
| ParseError::UnexpectedUnderScoreOperator(loc) => loc.clone(),
| ParseError::UnexpectedUnderScoreOperator(loc)
| ParseError::NotMatchTypeAnotherOneOfStatement(loc) => loc.clone(),
ParseError::Eof => Loc::new(input.len() as u8, input.len() as u8 + 1),
};
(e, loc)
Expand Down
6 changes: 6 additions & 0 deletions src/fmt/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ impl fmt::Display for ParseError {
"{}: Expected under socre as void return, but used as operator.",
loc
),
ParseError::NotMatchTypeAnotherOneOfStatement(loc) => write!(
f,
"{}: Expected match return type of each statement but not match.",
loc
),

ParseError::Eof => write!(f, "Expected token, but not detected."),
}
}
Expand Down
24 changes: 24 additions & 0 deletions src/node/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,28 @@ impl NodeSt {
_ => unimplemented!(),
}
}

pub fn isi(self) -> bool {
match self.c.value {
NodeKind::Num(_)
| NodeKind::Add
| NodeKind::Sub
| NodeKind::Mul
| NodeKind::Div
| NodeKind::E
| NodeKind::NE
| NodeKind::L
| NodeKind::LE
| NodeKind::G
| NodeKind::GE
| NodeKind::NewAssignG
| NodeKind::NewAssignL
| NodeKind::NewAssign
| NodeKind::Assign
| NodeKind::Ident(_)
| NodeKind::GVar(_)
| NodeKind::LVar(_) => true,
_ => false,
}
}
}
37 changes: 18 additions & 19 deletions src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,27 +154,19 @@ impl NodeArr {
it: &mut TokenIter,
ev: Vec<Vec<Var>>,
) -> Result<(Self, Vec<String>), ParseError> {
let mut a = Self::new();
a.set_env(ev);

expect_token(
TokenKind::LBrace,
ParseError::NotOpenedStmt(it.p.peek().unwrap().to_owned().to_owned()),
it,
)?;

while it.peek_value() != TokenKind::RBrace {
match NodeSt::parser(it)? {
n => match n.c.value {
_ => {
a.set_imm_env();
let n = beta(&mut n.to_owned(), &mut a);
a.node_st_vec.push(n.to_owned());
}
},
}
}
it.p.next().unwrap();
let (a, _) = Self::stp(it, ev)?;

expect_token(
TokenKind::RBrace,
ParseError::NotOpenedStmt(it.p.peek().unwrap().to_owned().to_owned()),
it,
)?;

Ok((a, vec![]))
}
Expand Down Expand Up @@ -352,8 +344,7 @@ impl NodeArr {
let mut c = beta(&mut n.to_owned().cond.unwrap(), &mut a);
c = c.simplified();

let if_stmts_a =
Self::parse_statement(it, a.imm_env_v.to_owned())?.0;
let if_stmts = Self::parse_statement(it, a.imm_env_v.to_owned())?.0;

let mut _else_if_stmts: NodeArr = NodeArr::new();
match it.p.peek().unwrap().value {
Expand All @@ -365,6 +356,15 @@ impl NodeArr {
_ => (),
};

let if_stmts_isi = NodeSt::isi(if_stmts.ret_node_st);
let else_if_stmts_isi = NodeSt::isi(_else_if_stmts.ret_node_st);

if if_stmts_isi != else_if_stmts_isi {
return Err(ParseError::NotMatchTypeAnotherOneOfStatement(
it.p.peek().unwrap().loc.to_owned(),
));
}

match c.c.value {
NodeKind::Num(num) => {
if num == 0 {
Expand All @@ -377,8 +377,7 @@ impl NodeArr {
}
}

a.node_st_vec
.append(&mut if_stmts_a.node_st_vec.to_owned());
a.node_st_vec.append(&mut if_stmts.node_st_vec.to_owned());
}
_ => {
a.set_imm_env();
Expand Down
1 change: 1 addition & 0 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub enum ParseError {
UnusedVariable(Loc),
NotMatchReturnType(Loc),
UnexpectedUnderScoreOperator(Loc),
NotMatchTypeAnotherOneOfStatement(Loc),
// UnexpectedToken(Token),
// NotExpression(Token),
// UnclosedOpenParen(Token),
Expand Down
61 changes: 61 additions & 0 deletions src/tests/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,64 @@ fn unexpected_under_score_operator_test() {
};
assert!(n)
}

#[test]
fn type_match_another_one_of_statement_1_test() {
let mut t = Token::tokenize("fn { int i = 9; if (i) { i; _ } else { 3*4; _ } _ }").unwrap();
let mut it = TokenIter::new(&mut t);
let n = match NodeArr::w_parser(&mut it, vec![]) {
Ok(_) => true,
Err(_) => false,
};
assert!(n)
}

// #[test]
// fn type_match_another_one_of_statement_2_test() {
// let mut t = Token::tokenize("fn { int i = 9; if (i) { i; 0; } else { 3*4; _ } _ }").unwrap();
// let mut it = TokenIter::new(&mut t);
// let n = match NodeArr::w_parser(&mut it, vec![]) {
// Ok(_) => true,
// Err(_) => false
// };
// assert!(n)
// }

#[test]
fn type_match_another_one_of_statement_3_test() {
let mut t = Token::tokenize("fn { int i = 9; if (i) { i; 0 } else { 3*4; 3 } _ }").unwrap();
let mut it = TokenIter::new(&mut t);
let n = match NodeArr::w_parser(&mut it, vec![]) {
Ok(_) => true,
Err(_) => false,
};
assert!(n)
}

#[test]
fn type_not_match_another_one_of_statement_1_test() {
let mut t = Token::tokenize("fn { int i = 9; if (i) { i; _ } else { 3*4; 2; } _ }").unwrap();
let mut it = TokenIter::new(&mut t);
let n = match NodeArr::w_parser(&mut it, vec![]) {
Ok(_) => false,
Err(e) => match e {
ParseError::NotMatchTypeAnotherOneOfStatement(_) => true,
_ => false,
},
};
assert!(n)
}

// #[test]
// fn type_not_match_another_one_of_statement_2_test() {
// let mut t = Token::tokenize("fn { int i = 9; if (i) { i; 0 } else { 3*4; 2; } _ }").unwrap();
// let mut it = TokenIter::new(&mut t);
// let n = match NodeArr::w_parser(&mut it, vec![]) {
// Ok(_) => false,
// Err(e) => match e {
// ParseError::NotMatchTypeAnotherOneOfStatement(_) => true,
// _ => false,
// },
// };
// assert!(n)
// }
3 changes: 2 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ assert_llvm 34 'fn int { int _u = 8; int a = 2; 4+2*a*_u-2 }'
assert_llvm 1 'fn int { int i = 1; if (i) { 0 } else { 0 } i }'
assert_llvm 0 'fn { if (2 == 3) { 1; 2; } else { 3; 4; } _ }'
assert_llvm 0 'fn { int i = 9; if (i) { 1; 2; } else { 3*4; 5; } _ }'
assert_llvm 0 'fn { int i = 9; if (i) { i; 2; } else { 3*4; 5; } _ }'
assert_llvm 0 'fn { int i = 9; if (i) { i; 2 } else { 3*4; 5 } _ }'
assert_llvm 0 'fn { int i = 9; if (i) { i; _ } else { 3*4; _ } _ }'

echo "------------------------------"
echo "All llvm test passed!\n"

0 comments on commit 5a23a10

Please sign in to comment.