Skip to content

Commit

Permalink
Merge branch 'topic/1454' into 'master'
Browse files Browse the repository at this point in the history
Fix interpolated string support

Closes #1454

See merge request eng/libadalang/libadalang!1786
  • Loading branch information
raph-amiard committed Sep 17, 2024
2 parents 81fc3a2 + e49cbf1 commit 6bfa946
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 9 deletions.
22 changes: 18 additions & 4 deletions ada/nodes.lkt
Original file line number Diff line number Diff line change
Expand Up @@ -12080,13 +12080,22 @@ class DeclExpr: Expr {
class FormatStringLiteral: Expr {
@parse_field opening_chunk: FormatStringTokStart
@parse_field mid_exprs: ASTList[FormatStringChunk]
@parse_field trailing_expr: FormatStringChunk

# This field is null when no expressions to expand are given in the
# interpolated string, for example with `f"a dummy interpolated string"`.
@parse_field @nullable trailing_expr: FormatStringChunk

@with_dynvars(env, origin, entry_point)
fun xref_equation(): Equation = (
(
%predicate(BaseTypeDecl.allows_string_literal, node.expected_type_var(), error_location=node) and %eq(node.expected_type_var(), node.type_var())
) and self.trailing_expr.sub_equation()
%predicate(
BaseTypeDecl.allows_string_literal,
node.expected_type_var(),
error_location=node
) and %eq(node.expected_type_var(), node.type_var())
and self.trailing_expr.do(
(te) => te.sub_equation(),
default_val=%true
)
) and self.mid_exprs.logic_all((m) => m.expr.sub_equation())
}

Expand Down Expand Up @@ -15801,6 +15810,11 @@ class FormatStringTokMid: FormatStringTokNode implements TokenNode {
class FormatStringTokStart: FormatStringTokNode implements TokenNode {
}

|" Node holding a formatting "string" token. This token is used when the
|" corresponding interpolated string doesn't have any expression to expand.
class FormatStringTokString: FormatStringTokStart implements TokenNode {
}

|" List of statements, with optional exception handlers (:rmlink:`11.2`).
@snaps
class HandledStmts: AdaNode {
Expand Down
18 changes: 13 additions & 5 deletions ada/parser.lkt
Original file line number Diff line number Diff line change
Expand Up @@ -898,11 +898,19 @@ grammar ada_grammar {
identifier <- Identifier(@Identifier)
char_literal <- CharLiteral(@Char)
string_literal <- StringLiteral(@String)
format_string_literal <- FormatStringLiteral(
FormatStringTokStart(@FormatStringStart)
list*(FormatStringChunk(expr
FormatStringTokMid(@FormatStringMid)))
FormatStringChunk(expr FormatStringTokEnd(@FormatStringEnd))
format_string_literal <- or(
# String interpolation with interpolated expressions
FormatStringLiteral(
FormatStringTokStart(@FormatStringStart)
list*(FormatStringChunk(expr FormatStringTokMid(@FormatStringMid)))
FormatStringChunk(expr FormatStringTokEnd(@FormatStringEnd))
)

# String interpolation without interpolated expressions
| FormatStringLiteral(
FormatStringTokString(@FormatStringString)
null(ASTList[FormatStringChunk]) null(FormatStringChunk)
)
)
defining_id <- DefiningName(identifier)
dec_literal <- RealLiteral(@Decimal)
Expand Down
5 changes: 5 additions & 0 deletions ada/tokens.lkt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ lexer ada_lexer {
val p_format_string_start = p"f\\\"(\\\"\\\"|{bracket_char}|[^\\n\\\"\\{])*\\{"
val p_format_string_mid = p"\\}(\\\"\\\"|{bracket_char}|[^\\n\\\"\\{])*\\{"
val p_format_string_end = p"\\}(\\\"\\\"|{bracket_char}|[^\\n\\\"\\{])*\\\""

# Simple format string literal without expressions to expand
val p_format_string_string = p"f\\\"(\\\"\\\"|{bracket_char}|[^\\n\\\"\\{])*\\\""

val p_percent_string = p"%(%%|{bracket_char}|[^\\n%])*%"
val digit = p"[0-9]"
val extended_digit = p"[0-9a-zA-Z]"
Expand Down Expand Up @@ -161,6 +165,7 @@ lexer ada_lexer {
}

String <- or(p"{p_string}" | p"{p_percent_string}")
FormatStringString <- p"{p_format_string_string}"
FormatStringStart <- p"{p_format_string_start}"
FormatStringMid <- p"{p_format_string_mid}"
FormatStringEnd <- p"{p_format_string_end}"
Expand Down
1 change: 1 addition & 0 deletions contrib/highlight/highlighter.adb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package body Highlighter is
Ada_Format_String_End
| Ada_Format_String_Mid
| Ada_Format_String_Start
| Ada_Format_String_String
| Ada_String
=> String_Literal,

Expand Down
1 change: 1 addition & 0 deletions testsuite/tests/parser/interpolated_string_0/input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f"a{A}B{B}C{C}D{D}"
26 changes: 26 additions & 0 deletions testsuite/tests/parser/interpolated_string_0/test.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FormatStringLiteral[1:1-1:20]
|f_opening_chunk:
| FormatStringTokStart[1:1-1:5]: f"a{
|f_mid_exprs:
| FormatStringChunkList[1:5-1:17]
| | FormatStringChunk[1:5-1:9]
| | |f_expr:
| | | Id[1:5-1:6]: A
| | |f_string_tok:
| | | FormatStringTokMid[1:6-1:9]: }B{
| | FormatStringChunk[1:9-1:13]
| | |f_expr:
| | | Id[1:9-1:10]: B
| | |f_string_tok:
| | | FormatStringTokMid[1:10-1:13]: }C{
| | FormatStringChunk[1:13-1:17]
| | |f_expr:
| | | Id[1:13-1:14]: C
| | |f_string_tok:
| | | FormatStringTokMid[1:14-1:17]: }D{
|f_trailing_expr:
| FormatStringChunk[1:17-1:20]
| |f_expr:
| | Id[1:17-1:18]: D
| |f_string_tok:
| | FormatStringTokEnd[1:18-1:20]: }"
2 changes: 2 additions & 0 deletions testsuite/tests/parser/interpolated_string_0/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
driver: parser
rule: format_string_literal
1 change: 1 addition & 0 deletions testsuite/tests/parser/interpolated_string_1/input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
f"lol"
6 changes: 6 additions & 0 deletions testsuite/tests/parser/interpolated_string_1/test.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FormatStringLiteral[1:1-1:7]
|f_opening_chunk:
| FormatStringTokString[1:1-1:7]: f"lol"
|f_mid_exprs:
| FormatStringChunkList[1:7-1:7]: <empty list>
|f_trailing_expr: <null>
2 changes: 2 additions & 0 deletions testsuite/tests/parser/interpolated_string_1/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
driver: parser
rule: format_string_literal

0 comments on commit 6bfa946

Please sign in to comment.