Skip to content

Commit

Permalink
Implement underScore operator.
Browse files Browse the repository at this point in the history
  • Loading branch information
YSawc committed Oct 14, 2020
1 parent cb7864e commit 72baca7
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 4 deletions.
4 changes: 4 additions & 0 deletions src/code_gen/gen_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ fn gen_x86(f: &mut fs::File, ns: NodeSt) -> String {
write!(f, " jmp .L.return\n").unwrap();
return l;
}
NodeKind::UnderScore => {
unsafe { write!(f, " mov $0, %{}\n", REGS[CC as usize]).unwrap() };
unsafe { return REGS[CC as usize].to_string() };
}
_ => (),
}

Expand Down
3 changes: 2 additions & 1 deletion src/error/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ impl Error {
| ParseError::OperatorOutOfFnction(loc, ..) => loc.loc.clone(),
ParseError::UndefinedVariable(loc)
| ParseError::UnusedVariable(loc)
| ParseError::NotMatchReturnType(loc) => loc.clone(),
| ParseError::NotMatchReturnType(loc)
| ParseError::UnexpectedUnderScoreOperator(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 @@ -40,6 +40,7 @@ impl fmt::Display for TokenKind {
TokenKind::Fn => write!(f, "fn"),
TokenKind::LBrace => write!(f, "{{"),
TokenKind::RBrace => write!(f, "}}"),
TokenKind::UnderScore => write!(f, "_"),
}
}
}
Expand Down Expand Up @@ -92,6 +93,11 @@ impl fmt::Display for ParseError {
ParseError::UndefinedVariable(loc) => write!(f, "{} Undefined variable detected!", loc),
ParseError::UnusedVariable(loc) => write!(f, "{} Unused variable detected!", loc),
ParseError::NotMatchReturnType(loc) => write!(f, "{}: Return type is not match.", loc),
ParseError::UnexpectedUnderScoreOperator(loc) => write!(
f,
"{}: Expected under socre as void return, but used as operator.",
loc
),
ParseError::Eof => write!(f, "Expected token, but not detected."),
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/node/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum NodeKind {
Fn,
LBrace,
RBrace,
UnderScore,
Default,
}

Expand Down Expand Up @@ -113,6 +114,9 @@ impl Node {
pub fn mfn(loc: Loc) -> Self {
Self::new(NodeKind::Fn, loc)
}
pub fn under_score(loc: Loc) -> Self {
Self::new(NodeKind::UnderScore, loc)
}
}

impl NodeSt {
Expand All @@ -122,4 +126,10 @@ impl NodeSt {
..Default::default()
}
}
pub fn under_score(loc: Loc) -> Self {
NodeSt {
c: Node::under_score(loc),
..Default::default()
}
}
}
13 changes: 12 additions & 1 deletion src/node_arr/node_arr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl NodeArr {
}
} else {
match l.to_owned()?.to_owned().ret_node_st.c.value {
NodeKind::Default => return l,
NodeKind::UnderScore => return l,
_ => {
return Err(ParseError::NotMatchReturnType(
l.to_owned().unwrap().to_owned().ret_node_st.c.loc,
Expand Down Expand Up @@ -195,6 +195,17 @@ impl NodeArr {
}
continue;
}
NodeKind::UnderScore => {
if it.peek().unwrap().to_owned().to_owned().value != TokenKind::RBrace {
return Err(ParseError::UnexpectedUnderScoreOperator(
n.to_owned().c.loc,
));
}
b = true;
let n = NodeSt::under_score(n.c.loc);
r = n.to_owned();
n
}
NodeKind::Ident(s) => match Self::find_l(s, l.to_owned()) {
Some(v) => {
if it.peek().unwrap().to_owned().to_owned().value == TokenKind::RBrace {
Expand Down
1 change: 1 addition & 0 deletions src/parser/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum ParseError {
UndefinedVariable(Loc),
UnusedVariable(Loc),
NotMatchReturnType(Loc),
UnexpectedUnderScoreOperator(Loc),
// UnexpectedToken(Token),
// NotExpression(Token),
// UnclosedOpenParen(Token),
Expand Down
29 changes: 29 additions & 0 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ impl NodeSt {
..Default::default()
}
}
pub fn new_node(c: Node) -> Self {
Self {
c,
..Default::default()
}
}
}

impl NodeSt {
Expand Down Expand Up @@ -176,6 +182,29 @@ impl NodeSt {
_ => return Err(ParseError::NotClosedStmt(et.next().unwrap().to_owned())),
}
}
Token {
value: TokenKind::UnderScore,
loc,
} => {
let mut et = it.clone();
it.next().unwrap();
let u = Node::under_score(loc.to_owned());
let op = Self::new_node(u);
if it.peek() == None {
et.next();
return Err(ParseError::NotClosedStmt(et.next().unwrap().to_owned()));
}
match it.peek().unwrap() {
Token {
value: TokenKind::SemiColon,
..
} => {
it.next();
}
_ => (),
}
return Ok(op);
}
_ => {
let lhs = Self::cmp(it)?;
match it.peek().unwrap() {
Expand Down
2 changes: 1 addition & 1 deletion src/simplified/simplified.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub fn exec(ns: NodeSt) -> NodeSt {
_ => unreachable!(),
}
}
NodeKind::Num(_) => return ns,
NodeKind::Num(_) | NodeKind::UnderScore => return ns,
_ => unreachable!(),
};
}
36 changes: 36 additions & 0 deletions src/tests/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,39 @@ fn not_match_return_type_test() {
};
assert!(l)
}

#[test]
fn match_void_type_test() {
let t = Token::tokenize("fn { _ }").unwrap();
let l = match NodeArr::w_parser(t) {
Ok(_) => true,
_ => false,
};
assert!(l)
}

#[test]
fn not_match_void_type_test() {
let t = Token::tokenize("fn int { _ }").unwrap();
let l = match NodeArr::w_parser(t) {
Ok(_) => false,
Err(e) => match e {
ParseError::NotMatchReturnType(_) => true,
_ => false,
},
};
assert!(l)
}

#[test]
fn unexpected_underscore_operator_test() {
let t = Token::tokenize("fn int { _; 1 }").unwrap();
let l = match NodeArr::w_parser(t) {
Ok(_) => false,
Err(e) => match e {
ParseError::UnexpectedUnderScoreOperator(_) => true,
_ => false,
},
};
assert!(l)
}
2 changes: 2 additions & 0 deletions src/token/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub enum TokenKind {
Fn,
LBrace,
RBrace,
UnderScore,
}

pub type Token = Annot<TokenKind>;
Expand Down Expand Up @@ -149,6 +150,7 @@ impl Token {
map.insert('='.into(), TokenKind::Assign);
map.insert('{'.into(), TokenKind::LBrace);
map.insert('}'.into(), TokenKind::RBrace);
map.insert('_'.into(), TokenKind::UnderScore);
map
}

Expand Down
6 changes: 5 additions & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,14 @@ assert 10 'fn int { if (2 == 3) 5; else 10; }'
assert 31 'fn int { if (2 == 3) 5+3; else 10+21; }' simplified
assert 8 'fn int { if (2 < 3) 5+3; else 10; }'
assert 2 'fn int { int a = 3; a; a = 2; a; }'
# assert 5 'fn int { int a = 5; int b = a; a = 2; b }'
assert 5 'fn int { int a = 5; int b = a; a = 2; b }'
assert 1 'fn int { 1; }'
assert 2 'fn int { 2 }'
assert 3 'fn int { return 3; }'
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

echo "------------------------------"
echo "All test passed!"

0 comments on commit 72baca7

Please sign in to comment.