Add BacktickString building.

This commit is contained in:
Jesse Brault 2025-05-17 08:44:39 -05:00
parent 78e7271950
commit 2de45817d4
4 changed files with 50 additions and 25 deletions

View File

@ -1277,25 +1277,12 @@ fn build_single_quote_string(file_id: usize, pair: Pair<Rule>) -> Literal {
fn build_double_quote_string(file_id: usize, pair: Pair<Rule>) -> Literal { fn build_double_quote_string(file_id: usize, pair: Pair<Rule>) -> Literal {
let mut parts: Vec<DStringPart> = vec![]; let mut parts: Vec<DStringPart> = vec![];
let inner = pair.into_inner(); handle_d_backtick_strings_inner(
for inner_pair in inner { Rule::DStringInner,
match inner_pair.as_rule() { file_id,
Rule::DStringInner => { pair,
parts.push(DStringPart::from_string(inner_pair.as_span().as_str())); &mut parts,
} );
Rule::DStringExpression => {
let expression_pair = inner_pair.into_inner().next().unwrap();
parts.push(DStringPart::from_expression(expect_and_use(
file_id,
expression_pair,
Rule::Expression,
build_expression,
)));
}
_ => unreachable!(),
}
}
if parts.len() == 1 && parts[0].is_string() { if parts.len() == 1 && parts[0].is_string() {
Literal::String(parts.pop().unwrap().unwrap_string()) Literal::String(parts.pop().unwrap().unwrap_string())
} else { } else {
@ -1304,7 +1291,42 @@ fn build_double_quote_string(file_id: usize, pair: Pair<Rule>) -> Literal {
} }
fn build_backtick_string(file_id: usize, pair: Pair<Rule>) -> Literal { fn build_backtick_string(file_id: usize, pair: Pair<Rule>) -> Literal {
todo!() let mut parts: Vec<DStringPart> = vec![];
handle_d_backtick_strings_inner(
Rule::BacktickInner,
file_id,
pair,
&mut parts,
);
if parts.len() == 1 && parts[0].is_string() {
Literal::String(parts.pop().unwrap().unwrap_string())
} else {
Literal::BacktickString(DString(parts))
}
}
fn handle_d_backtick_strings_inner(
inner_rule: Rule,
file_id: usize,
pair: Pair<Rule>,
parts: &mut Vec<DStringPart>,
) {
for inner_pair in pair.into_inner() {
let as_rule = inner_pair.as_rule();
if as_rule == inner_rule {
parts.push(DStringPart::from_string(inner_pair.as_span().as_str()));
} else if as_rule == Rule::DStringExpression {
let expression_pair = inner_pair.into_inner().next().unwrap();
parts.push(DStringPart::from_expression(expect_and_use(
file_id,
expression_pair,
Rule::Expression,
build_expression,
)));
} else {
unreachable!()
}
}
} }
#[cfg(test)] #[cfg(test)]
@ -1369,7 +1391,7 @@ mod tests {
#[test] #[test]
fn d_string_literal_and_expression() { fn d_string_literal_and_expression() {
assert_builds("fn main() { \"Hello, ${foo}!\" }"); assert_builds("fn main() { \"Hello, ${foo}\" }");
} }
#[test] #[test]

View File

@ -600,6 +600,7 @@ pub enum Literal {
USize(usize), USize(usize),
String(String), String(String),
DString(DString), DString(DString),
BacktickString(DString),
Boolean(bool), Boolean(bool),
} }
@ -616,25 +617,25 @@ impl DStringPart {
pub fn from_string(s: &str) -> DStringPart { pub fn from_string(s: &str) -> DStringPart {
DStringPart::String(String::from(s)) DStringPart::String(String::from(s))
} }
pub fn from_expression(e: Expression) -> DStringPart { pub fn from_expression(e: Expression) -> DStringPart {
DStringPart::Expression(Box::new(e)) DStringPart::Expression(Box::new(e))
} }
pub fn is_string(&self) -> bool { pub fn is_string(&self) -> bool {
match self { match self {
DStringPart::String(_) => true, DStringPart::String(_) => true,
_ => false, _ => false,
} }
} }
pub fn unwrap_string(self) -> String { pub fn unwrap_string(self) -> String {
match self { match self {
DStringPart::String(s) => s, DStringPart::String(s) => s,
_ => panic!(), _ => panic!(),
} }
} }
pub fn is_expression(&self) -> bool { pub fn is_expression(&self) -> bool {
match self { match self {
DStringPart::Expression(_) => true, DStringPart::Expression(_) => true,

View File

@ -878,6 +878,7 @@ impl PrettyPrint for Literal {
USize(u) => writer.writeln_indented(&format!("USize({})", u)), USize(u) => writer.writeln_indented(&format!("USize({})", u)),
String(s) => writer.writeln_indented(&format!("String({})", s)), String(s) => writer.writeln_indented(&format!("String({})", s)),
DString(d_string) => d_string.pretty_print(writer), DString(d_string) => d_string.pretty_print(writer),
BacktickString(d_string) => d_string.pretty_print(writer),
Boolean(b) => writer.writeln_indented(&format!("Boolean({})", b)), Boolean(b) => writer.writeln_indented(&format!("Boolean({})", b)),
} }
} }

View File

@ -1043,6 +1043,7 @@ impl Unparse for Literal {
USize(u) => writer.write(&format!("{}", u)), USize(u) => writer.write(&format!("{}", u)),
String(s) => writer.write(&format!("\"{}\"", s)), String(s) => writer.write(&format!("\"{}\"", s)),
DString(d_string) => d_string.unparse(writer), DString(d_string) => d_string.unparse(writer),
BacktickString(d_string) => d_string.unparse(writer),
Boolean(b) => writer.write(&format!("{}", b)), Boolean(b) => writer.write(&format!("{}", b)),
} }
} }