Skip to content

Commit 0448b47

Browse files
committed
(lexer) add: multi-line strings
Strings on multiple lines, with '\' escape or simply with successive double quotes
1 parent fde4549 commit 0448b47

File tree

5 files changed

+29
-6
lines changed

5 files changed

+29
-6
lines changed

src/lexer/lex_content.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ fn lex_line(
189189
break;
190190
}
191191
}
192-
end_current(lex_status, lex_data, location);
192+
if escape_state != EscapeStatus::Single {
193+
end_current(lex_status, lex_data, location);
194+
}
193195
if line.trim_end().ends_with('\\') {
194196
if line.ends_with(char::is_whitespace) {
195197
lex_data.push_err(location.to_suggestion(

src/lexer/types/lexing_data.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ impl LexingData {
3737
}
3838

3939
pub fn push_token(&mut self, token: Token) {
40-
self.tokens.push(token);
40+
if let TokenValue::Str(val) = token.get_value()
41+
&& let Some(TokenValue::Str(old)) = self.tokens.last_mut().map(Token::get_value_mut)
42+
{
43+
old.push_str(val);
44+
} else {
45+
self.tokens.push(token);
46+
}
4147
}
4248

4349
pub const fn set_end_line(&mut self) {

src/lexer/types/tokens_types.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ impl Token {
137137
&self.value
138138
}
139139

140+
pub(crate) const fn get_value_mut(&mut self) -> &mut TokenValue {
141+
&mut self.value
142+
}
143+
140144
pub(crate) fn into_value_location(self) -> (TokenValue, Location) {
141145
(self.value, self.location)
142146
}

src/parser/tree/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ impl fmt::Display for Literal {
116116
match self {
117117
Self::Empty => EMPTY.fmt(f),
118118
Self::Nullptr => "NULL".fmt(f),
119-
Self::Char(val) => val.fmt(f),
120-
Self::Str(val) => val.fmt(f),
119+
Self::Char(val) => write!(f, "'{val}'"),
120+
Self::Str(val) => write!(f, "\"{val}\""),
121121
Self::Number(val) => val.fmt(f),
122122
Self::ConstantBool(val) => val.fmt(f),
123123
Self::Variable(val) => val.fmt(f),

tests/strings.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use c_parser::*;
22

3+
const SEP: &str = "\n--------------------\n";
4+
35
fn test_string(content: &str, output: &str) {
46
let files = &[(String::new(), content)];
57
let mut location = Location::from(String::new());
8+
eprintln!("{SEP}Content = {content}{SEP}");
69
let tokens = lex_file(content, &mut location).unwrap_or_display(files, "lexer");
7-
eprintln!("Tokens = {}", display_tokens(&tokens));
10+
eprintln!("{SEP}Tokens = {}{SEP}", display_tokens(&tokens));
811
let node = parse_tokens(tokens).unwrap_or_display(files, "parser");
912
assert!(
1013
output == format!("{node}"),
11-
"Mismatch! Expected:\n{output}\n!= Computed\n{node}\n"
14+
"{SEP}Mismatch! Expected:\n{output}\n!= Computed\n{node}{SEP}"
1215
);
1316
}
1417

@@ -40,6 +43,14 @@ macro_rules! make_string_tests {
4043

4144
make_string_tests!(
4245

46+
multiline_string:
47+
"\"multi\"
48+
\"line\\
49+
strings\"
50+
"
51+
=>
52+
"[\"multiline strings\"..]"
53+
4354
unary_binary:
4455
"a + b * c - d / e % f + g - h * i + j % k * l ^ !m++ & n | o || p && q"
4556
=>

0 commit comments

Comments
 (0)