diff --git a/schala-lang/src/parsing/combinator.rs b/schala-lang/src/parsing/combinator.rs index 4a59f75..bac392d 100644 --- a/schala-lang/src/parsing/combinator.rs +++ b/schala-lang/src/parsing/combinator.rs @@ -841,8 +841,15 @@ fn string_literal(input: Span) -> ParseResult { } fn bare_string_literal(input: Span) -> ParseResult { - let string_escape_transforms = - alt((value("\\", tag("\\")), value("\"", tag("\"")), value("\n", tag("n")), value("\t", tag("t")))); + let string_escape_transforms = alt(( + value('\\', tag("\\")), + value('"', tag("\"")), + value('\n', tag("n")), + value('\t', tag("t")), + map(delimited(tag(r#"u{"#), recognize(digit_group_hex), tag("}")), |value| { + char::from_u32(u32::from_str_radix(value.fragment(), 16).unwrap()).unwrap() + }), + )); alt(( map(tag(r#""""#), |_| String::new()), preceded( diff --git a/schala-lang/src/parsing/test.rs b/schala-lang/src/parsing/test.rs index 17591fb..727e750 100644 --- a/schala-lang/src/parsing/test.rs +++ b/schala-lang/src/parsing/test.rs @@ -190,6 +190,7 @@ fn string_literals() { expr(StringLiteral { s: rc("some bytestring"), prefix: Some(rc("b")) }) ); assert_expr!(r#""Do \n \" escapes work\t""#, expr(strlit("Do \n \" escapes work\t"))); + assert_expr!(r#""Georgian letter jani \u{10ef}""#, expr(strlit("Georgian letter jani ჯ"))); } #[test]