Add DString building.
This commit is contained in:
parent
bae2048aef
commit
78e7271950
@ -11,3 +11,7 @@ fn main(x: String) {
|
|||||||
let test = 'oops.';
|
let test = 'oops.';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod test {
|
||||||
|
|
||||||
|
}
|
@ -1276,7 +1276,31 @@ 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 {
|
||||||
todo!()
|
let mut parts: Vec<DStringPart> = vec![];
|
||||||
|
let inner = pair.into_inner();
|
||||||
|
for inner_pair in inner {
|
||||||
|
match inner_pair.as_rule() {
|
||||||
|
Rule::DStringInner => {
|
||||||
|
parts.push(DStringPart::from_string(inner_pair.as_span().as_str()));
|
||||||
|
}
|
||||||
|
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() {
|
||||||
|
Literal::String(parts.pop().unwrap().unwrap_string())
|
||||||
|
} else {
|
||||||
|
Literal::DString(DString(parts))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_backtick_string(file_id: usize, pair: Pair<Rule>) -> Literal {
|
fn build_backtick_string(file_id: usize, pair: Pair<Rule>) -> Literal {
|
||||||
@ -1290,12 +1314,13 @@ mod tests {
|
|||||||
use crate::parser::DeimosParser;
|
use crate::parser::DeimosParser;
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
|
|
||||||
fn assert_builds(src: &str) -> CompilationUnit {
|
fn assert_builds(src: &str) {
|
||||||
let parse_result = DeimosParser::parse(Rule::CompilationUnit, src);
|
let parse_result = DeimosParser::parse(Rule::CompilationUnit, src);
|
||||||
if let Err(e) = parse_result {
|
if let Err(e) = parse_result {
|
||||||
panic!("Parsing failed.\n{}", e)
|
panic!("Parsing failed.\n{}", e)
|
||||||
} else {
|
} else {
|
||||||
build_ast(0, parse_result.unwrap().next().unwrap())
|
let ast = build_ast(0, parse_result.unwrap().next().unwrap());
|
||||||
|
dbg!(ast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,4 +1356,24 @@ mod tests {
|
|||||||
fn double_literal() {
|
fn double_literal() {
|
||||||
assert_builds("fn main() { 1.0 }");
|
assert_builds("fn main() { 1.0 }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d_string_no_expressions() {
|
||||||
|
assert_builds("fn main() { \"Hello, World!\" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d_string_one_expression() {
|
||||||
|
assert_builds("fn main() { \"${foo}\" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d_string_literal_and_expression() {
|
||||||
|
assert_builds("fn main() { \"Hello, ${foo}!\" }");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn d_string_literal_expression_literal() {
|
||||||
|
assert_builds("fn main() { \"Hello, ${foo}! It is a nice day.\" }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -599,5 +599,46 @@ pub enum Literal {
|
|||||||
Double(f64),
|
Double(f64),
|
||||||
USize(usize),
|
USize(usize),
|
||||||
String(String),
|
String(String),
|
||||||
|
DString(DString),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DString(pub Vec<DStringPart>);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum DStringPart {
|
||||||
|
String(String),
|
||||||
|
Expression(Box<Expression>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DStringPart {
|
||||||
|
pub fn from_string(s: &str) -> DStringPart {
|
||||||
|
DStringPart::String(String::from(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_expression(e: Expression) -> DStringPart {
|
||||||
|
DStringPart::Expression(Box::new(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_string(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
DStringPart::String(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_string(self) -> String {
|
||||||
|
match self {
|
||||||
|
DStringPart::String(s) => s,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_expression(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
DStringPart::Expression(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -877,7 +877,30 @@ impl PrettyPrint for Literal {
|
|||||||
Double(d) => writer.writeln_indented(&format!("Double({})", d)),
|
Double(d) => writer.writeln_indented(&format!("Double({})", d)),
|
||||||
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),
|
||||||
Boolean(b) => writer.writeln_indented(&format!("Boolean({})", b)),
|
Boolean(b) => writer.writeln_indented(&format!("Boolean({})", b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrettyPrint for DString {
|
||||||
|
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
|
writer.writeln_indented("DString")?;
|
||||||
|
writer.increase_indent();
|
||||||
|
for part in &self.0 {
|
||||||
|
part.pretty_print(writer)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrettyPrint for DStringPart {
|
||||||
|
fn pretty_print(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
|
writer.writeln_indented("DStringPart")?;
|
||||||
|
writer.increase_indent();
|
||||||
|
match self {
|
||||||
|
DStringPart::String(s) => writer.writeln_indented(&format!("String({})", s)),
|
||||||
|
DStringPart::Expression(e) => e.pretty_print(writer),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1042,7 +1042,32 @@ impl Unparse for Literal {
|
|||||||
Double(d) => writer.write(&format!("{}", d)),
|
Double(d) => writer.write(&format!("{}", d)),
|
||||||
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),
|
||||||
Boolean(b) => writer.write(&format!("{}", b)),
|
Boolean(b) => writer.write(&format!("{}", b)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Unparse for DString {
|
||||||
|
fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
|
writer.write("\"")?;
|
||||||
|
for part in &self.0 {
|
||||||
|
part.unparse(writer)?;
|
||||||
|
}
|
||||||
|
writer.write("\"")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Unparse for DStringPart {
|
||||||
|
fn unparse(&self, writer: &mut IndentWriter) -> std::io::Result<()> {
|
||||||
|
match self {
|
||||||
|
DStringPart::String(s) => writer.write(s),
|
||||||
|
DStringPart::Expression(e) => {
|
||||||
|
writer.write("${")?;
|
||||||
|
e.unparse(writer)?;
|
||||||
|
writer.write("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -795,14 +795,15 @@ StringChar = {
|
|||||||
DStringInner = @{ DStringChar+ }
|
DStringInner = @{ DStringChar+ }
|
||||||
|
|
||||||
DStringChar = {
|
DStringChar = {
|
||||||
!( "\"" | "\\" ) ~ ANY
|
!( "\"" | "\\" | "${" ) ~ ANY
|
||||||
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" )
|
| "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" )
|
||||||
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
||||||
}
|
}
|
||||||
|
|
||||||
DStringExpression = {
|
DStringExpression = {
|
||||||
"$"
|
"${"
|
||||||
~ BlockStatement
|
~ Expression
|
||||||
|
~ "}"
|
||||||
}
|
}
|
||||||
|
|
||||||
BacktickString = {
|
BacktickString = {
|
||||||
@ -815,7 +816,7 @@ BacktickString = {
|
|||||||
BacktickInner = @{ BacktickStringChar+ }
|
BacktickInner = @{ BacktickStringChar+ }
|
||||||
|
|
||||||
BacktickStringChar = {
|
BacktickStringChar = {
|
||||||
!( "\\`" | "\\" ) ~ ANY
|
!( "\\`" | "\\" | "${" ) ~ ANY
|
||||||
| "\\" ~ ( "`" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" )
|
| "\\" ~ ( "`" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" )
|
||||||
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
| "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} )
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user