implement multiline nested comments

This commit is contained in:
Theis Pieter Hollebeek 2023-02-07 14:20:14 +01:00
parent 3fadfac622
commit 6f347a5744

View File

@ -116,12 +116,15 @@ fn make_number<T: Iterator<Item = char>>(
*col += 1;
if result.contains(&'.') {
iter.next();
return Err(TokenError {
let error = TokenError {
error: "unexpected token".to_string(),
col: *col,
line: *line,
});
};
*col += 1;
return Err(error);
}
*col += 1;
iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
result.push('.');
@ -209,13 +212,67 @@ fn make_comment<T: Iterator<Item = char>>(
*col += 2;
match second_character {
'/' => loop {
*col += 1;
match iter.peek() {
Some('\n') | None => break Ok(Token::SlComment(String::from_iter(result))),
_ => result.push(iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE)),
}
},
'*' => {
todo!();
let mut current = if let Some(c) = iter.next() {
c
} else {
return Err(TokenError {
error: "unexpected EOF".to_string(),
col: *col,
line: *line,
});
};
let mut nesting = 0;
loop {
if let Some(next) = iter.peek() {
println!("{current:?}|{next:?}|{result:?}");
if current == '/' {
if *next == '*' {
result.push(current);
current = iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
result.push(current);
current = iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
nesting += 1;
}
} else if current == '*' {
if *next == '/' {
result.push(current);
current = iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
result.push(current);
if nesting == 0 {
break Ok(Token::MlComment(String::from_iter(result)));
}
if iter.peek().is_none() {
return Err(TokenError {
error: "unexpected EOF".to_string(),
col: *col,
line: *line,
});
}
current = iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
nesting -= 1;
}
} else {
result.push(current);
current = iter.next().expect(NO_MUT_PEEK_NEXT_MESSAGE);
}
} else {
break Err(TokenError {
error: "unexpected EOF".to_string(),
col: *col,
line: *line,
});
}
}
}
c => Err(TokenError {
error: format!("unexpected token {c}"),
@ -356,4 +413,21 @@ mod tests {
]
)
}
#[test]
fn unnested_multiline_comment() {
let text = "/* hello */";
let tokens = lexer(text);
assert_eq!(tokens, vec![Token::MlComment("/* hello */".to_string()),])
}
#[test]
fn nested_multiline_comment() {
let text = "/* /* hello */ */";
let tokens = lexer(text);
assert_eq!(
tokens,
vec![Token::MlComment("/* /* hello */ */".to_string()),]
)
}
}