Parse string literals
This commit is contained in:
parent
867595b5b9
commit
82e5b589e1
2 changed files with 41 additions and 7 deletions
|
|
@ -61,8 +61,6 @@ pub enum StringLitElem {
|
||||||
Unicode(char),
|
Unicode(char),
|
||||||
/// `\\`
|
/// `\\`
|
||||||
Backslash,
|
Backslash,
|
||||||
/// `\'`
|
|
||||||
SingleQuote,
|
|
||||||
/// `\"'`
|
/// `\"'`
|
||||||
DoubleQuote,
|
DoubleQuote,
|
||||||
/// `\t`
|
/// `\t`
|
||||||
|
|
@ -77,8 +75,8 @@ pub enum StringLitElem {
|
||||||
/// - `""`
|
/// - `""`
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct StringLit {
|
pub struct StringLit {
|
||||||
elems: Vec<StringLitElem>,
|
pub elems: Vec<StringLitElem>,
|
||||||
span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasSpan for StringLit {
|
impl HasSpan for StringLit {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use chumsky::prelude::*;
|
use chumsky::prelude::*;
|
||||||
|
|
||||||
use crate::ast::{Expr, Ident, Lit, NumLit, NumLitStr, Space, StringLit, TableLit, TableLitElem};
|
use crate::ast::{
|
||||||
|
Expr, Ident, Lit, NumLit, NumLitStr, Space, StringLit, StringLitElem, TableLit, TableLitElem,
|
||||||
|
};
|
||||||
use crate::builtin::Builtin;
|
use crate::builtin::Builtin;
|
||||||
|
|
||||||
use super::basic::{EParser, Error};
|
use super::basic::{EParser, Error};
|
||||||
|
|
@ -78,9 +80,43 @@ fn num_lit() -> impl Parser<char, NumLit, Error = Error> {
|
||||||
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
.map_with_span(|(value, str), span| NumLit { value, str, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn string_lit_elem() -> impl Parser<char, StringLitElem, Error = Error> {
|
||||||
|
let plain = filter(|c: &char| !matches!(c, '"' | '\\'))
|
||||||
|
.repeated()
|
||||||
|
.at_least(1)
|
||||||
|
.collect::<String>()
|
||||||
|
.map(StringLitElem::Plain);
|
||||||
|
|
||||||
|
let unicode_char = num_lit_str_radix(16).try_map(|(n, _), span| {
|
||||||
|
let msg = "not a valid unicode code point";
|
||||||
|
let n: u32 = n.try_into().map_err(|_| Simple::custom(span, msg))?;
|
||||||
|
let c: char = n.try_into().map_err(|_| Simple::custom(span, msg))?;
|
||||||
|
Ok(c)
|
||||||
|
});
|
||||||
|
let unicode = just("\\u{")
|
||||||
|
.ignore_then(unicode_char)
|
||||||
|
.then_ignore(just('}'))
|
||||||
|
.map(StringLitElem::Unicode);
|
||||||
|
let backslash = just("\\\\").to(StringLitElem::Backslash);
|
||||||
|
let double_quote = just("\\\"").to(StringLitElem::DoubleQuote);
|
||||||
|
let tab = just("\\t").to(StringLitElem::Tab);
|
||||||
|
let carriage_return = just("\\r").to(StringLitElem::CarriageReturn);
|
||||||
|
let newline = just("\\n").to(StringLitElem::Newline);
|
||||||
|
|
||||||
|
plain
|
||||||
|
.or(unicode)
|
||||||
|
.or(backslash)
|
||||||
|
.or(double_quote)
|
||||||
|
.or(tab)
|
||||||
|
.or(carriage_return)
|
||||||
|
.or(newline)
|
||||||
|
}
|
||||||
|
|
||||||
fn string_lit() -> impl Parser<char, StringLit, Error = Error> {
|
fn string_lit() -> impl Parser<char, StringLit, Error = Error> {
|
||||||
// TODO Parse string literals
|
string_lit_elem()
|
||||||
filter(|_| false).map(|_| unreachable!())
|
.repeated()
|
||||||
|
.delimited_by(just('"'), just('"'))
|
||||||
|
.map_with_span(|elems, span| StringLit { elems, span })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn table_lit_elem(
|
pub fn table_lit_elem(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue