Skip to content

Commit

Permalink
fix: joined str parse and format & support \$ escape for str interpol…
Browse files Browse the repository at this point in the history
…ation

Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Jul 3, 2024
1 parent e1f8616 commit f195202
Show file tree
Hide file tree
Showing 16 changed files with 609 additions and 69 deletions.
41 changes: 20 additions & 21 deletions kclvm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 15 additions & 11 deletions kclvm/ast_pretty/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -781,21 +781,25 @@ impl<'p, 'ctx> MutSelfTypedResultWalker<'ctx> for Printer<'p> {
}

fn walk_joined_string(&mut self, joined_string: &'ctx ast::JoinedString) -> Self::Result {
let quote_str = if joined_string.is_long_string {
"\"\"\""
if !joined_string.raw_value.is_empty() {
self.write(&joined_string.raw_value)
} else {
"\""
};
self.write(quote_str);
for value in &joined_string.values {
match &value.node {
ast::Expr::StringLit(string_lit) => {
self.write(&string_lit.value.replace('\"', "\\\""));
let quote_str = if joined_string.is_long_string {
"\"\"\""
} else {
"\""
};
self.write(quote_str);
for value in &joined_string.values {
match &value.node {
ast::Expr::StringLit(string_lit) => {
self.write(&string_lit.value.replace('\"', "\\\""));
}
_ => self.expr(value),
}
_ => self.expr(value),
}
self.write(quote_str);
}
self.write(quote_str);
}

fn walk_formatted_value(&mut self, formatted_value: &'ctx ast::FormattedValue) -> Self::Result {
Expand Down
21 changes: 20 additions & 1 deletion kclvm/ast_pretty/src/test_data/codelayout.input
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,23 @@ aaaa = (1 + 2 / 2) if _a == 2 + + 134.3 else ("a"*3)
bbbb = "{}". format(a)
empty_list = []
empty_config = {}
number_suffix = 1Gi
number_suffix = 1Gi
long_string_0 = """
value
"""
long_string_1 = """\
value
"""
long_string_2 = """\
value"""
joined_data_0 = '\"false\" ${item.kind}: ${item.metadata.name}'
joined_data_1 = "\"false\" ${item.kind}: ${item.metadata.name}"
joined_data_2 = '''\
${CC}
'''
joined_data_3 = '''\
$${CC}
'''
joined_data_4 = '''\
\${CC}
'''
19 changes: 19 additions & 0 deletions kclvm/ast_pretty/src/test_data/codelayout.output
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,22 @@ bbbb = "{}".format(a)
empty_list = []
empty_config = {}
number_suffix = 1Gi
long_string_0 = """
value
"""
long_string_1 = """\
value
"""
long_string_2 = """\
value"""
joined_data_0 = '\"false\" ${item.kind}: ${item.metadata.name}'
joined_data_1 = "\"false\" ${item.kind}: ${item.metadata.name}"
joined_data_2 = '''\
${CC}
'''
joined_data_3 = '''\
$${CC}
'''
joined_data_4 = '''\
\${CC}
'''
4 changes: 2 additions & 2 deletions kclvm/ast_pretty/src/test_data/str.output
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ b = "${a}"
c = """1"""
d = """${c}"""
e = '1'
f = "${a}"
f = '${a}'
g = '''1'''
h = """${c}"""
h = '''${c}'''
67 changes: 43 additions & 24 deletions kclvm/parser/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,37 +1640,56 @@ impl<'a> Parser<'a> {
let mut data_off = 0;
let mut raw_off: usize = quote_space;
loop {
if let (Some(i), Some(data_i)) =
if raw_off >= raw_data.len() || data_off >= data.len() {
break;
}
if let (Some(raw_i), Some(data_i)) =
(raw_data[raw_off..].find("${"), data[data_off..].find("${"))
{
if let (Some(j), Some(data_j)) = (
raw_data[raw_off + i..].find('}'),
data[data_off + i..].find('}'),
if let (Some(raw_j), Some(data_j)) = (
raw_data[raw_off + raw_i..].find('}'),
data[data_off + data_i..].find('}'),
) {
let lo: usize = raw_off + i;
let hi: usize = raw_off + i + j + 1;
let raw_lo: usize = raw_off + raw_i;
let raw_hi: usize = raw_off + raw_i + raw_j + 1;

let data_lo: usize = data_off + data_i;
let data_hi: usize = data_off + data_i + data_j + 1;

let s0 = &data[data_off..data_lo];
let s1 = &raw_data[lo..hi];

let s0_expr = node_ref!(Expr::StringLit(StringLit {
is_long_string: false,
raw_value: s0.to_string(),
value: s0.to_string().replace("$$", "$"),
}));

let s1_expr = parse_expr(self, s1, pos + new_byte_pos(lo as u32));

if !s0.is_empty() {
joined_value.values.push(s0_expr);
let s0_raw = &raw_data[raw_off..raw_lo];
let s1_raw = &raw_data[raw_lo..raw_hi];

// Handling \${} Escapes
let is_escape = !s0_raw.is_empty() && &s0_raw[s0_raw.len() - 1..] == "\\";
if is_escape {
let s_raw = &raw_data[raw_off..raw_hi];
let s = &data[data_off..data_hi].replace("\\$", "$");
joined_value
.values
.push(node_ref!(Expr::StringLit(StringLit {
is_long_string: false,
raw_value: s_raw.to_string(),
value: s.to_string(),
})));
} else {
if !s0.is_empty() {
joined_value
.values
.push(node_ref!(Expr::StringLit(StringLit {
is_long_string: false,
raw_value: s0_raw.to_string(),
value: s0.to_string(),
})));
}
joined_value.values.push(parse_expr(
self,
s1_raw,
pos + new_byte_pos(raw_lo as u32),
));
}
joined_value.values.push(s1_expr);

data_off = data_hi;
raw_off = hi;
raw_off = raw_hi;
continue;
} else {
self.sess.struct_message_error(
Expand All @@ -1681,7 +1700,7 @@ impl<'a> Parser<'a> {
.values
.push(node_ref!(Expr::StringLit(StringLit {
is_long_string: false,
raw_value: data[data_off..].to_string(),
raw_value: raw_data[raw_off..].to_string(),
value: data[data_off..].to_string(),
})));
break;
Expand All @@ -1695,8 +1714,8 @@ impl<'a> Parser<'a> {
.values
.push(node_ref!(Expr::StringLit(StringLit {
is_long_string: false,
raw_value: data[data_off..].to_string(),
value: data[data_off..].to_string().replace("$$", "$"),
raw_value: raw_data[raw_off..].to_string(),
value: data[data_off..].to_string(),
})));
break;
}
Expand Down
3 changes: 3 additions & 0 deletions kclvm/parser/src/tests/error_recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ parse_expr_snapshot! { joined_string_recovery_9, r#"'''\
parse_expr_snapshot! { joined_string_recovery_10, r#""""
${CC}
""""# }
parse_expr_snapshot! { joined_string_recovery_11, r#"'\"false\" ${item.kind}: ${item.metadata.name}'"# }
parse_expr_snapshot! { joined_string_recovery_12, r#"'\"false\" ${item.kind}: ${item.metadata.name} \"true\" ${item} '"# }
parse_expr_snapshot! { joined_string_recovery_13, r#"'\"false\" \${item.kind}: a${item.metadata.name} \"true\" \${item} '"# }
parse_expr_snapshot! { lambda_recovery_0, r#"lambda"# }
parse_expr_snapshot! { lambda_recovery_1, r#"lambda {"# }
parse_expr_snapshot! { lambda_recovery_2, r#"lambda {}"# }
Expand Down
Loading

0 comments on commit f195202

Please sign in to comment.