diff --git a/src/main/java/org/perlonjava/core/Configuration.java b/src/main/java/org/perlonjava/core/Configuration.java index 2522435f3..74bebc7a5 100644 --- a/src/main/java/org/perlonjava/core/Configuration.java +++ b/src/main/java/org/perlonjava/core/Configuration.java @@ -33,14 +33,14 @@ public final class Configuration { * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitId = "3611e23bd"; + public static final String gitCommitId = "4623fa856"; /** * Git commit date of the build (ISO format: YYYY-MM-DD). * Automatically populated by Gradle/Maven during build. * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String gitCommitDate = "2026-04-23"; + public static final String gitCommitDate = "2026-04-24"; /** * Build timestamp in Perl 5 "Compiled at" format (e.g., "Apr 7 2026 11:20:00"). @@ -48,7 +48,7 @@ public final class Configuration { * Parsed by App::perlbrew and other tools via: perl -V | grep "Compiled at" * DO NOT EDIT MANUALLY - this value is replaced at build time. */ - public static final String buildTimestamp = "Apr 24 2026 12:28:51"; + public static final String buildTimestamp = "Apr 24 2026 13:01:40"; // Prevent instantiation private Configuration() { diff --git a/src/main/java/org/perlonjava/frontend/parser/StringDoubleQuoted.java b/src/main/java/org/perlonjava/frontend/parser/StringDoubleQuoted.java index ba9812f6e..1446b489b 100644 --- a/src/main/java/org/perlonjava/frontend/parser/StringDoubleQuoted.java +++ b/src/main/java/org/perlonjava/frontend/parser/StringDoubleQuoted.java @@ -56,14 +56,6 @@ public class StringDoubleQuoted extends StringSegmentParser { */ private final Stack caseModifiers = new Stack<>(); - /** - * Flag indicating whether we're inside a \Q...\E quotemeta region. - * - *

When true, all special characters (including $ and @) are treated as literals, - * and escape sequences are not processed (except \E to end the region). - */ - private boolean inQuotemeta = false; - /** * Private constructor for StringDoubleQuoted parser. * @@ -357,37 +349,20 @@ private Node createJoinNode(List nodes) { /** * Parses escape sequences based on context. * - *

This method delegates to different escape handling based on the - * parseEscapes flag and quotemeta mode: + *

Delegates to different escape handling based on the parseEscapes flag: *

+ * + *

Note: \Q...\E quotemeta regions are handled via the case-modifier stack + * (pushing a "Q" modifier in the \Q handler and applying it in \E), so no + * special in-string state is needed. Inside \Q, escape sequences and variable + * interpolation continue to work normally; the accumulated content is wrapped + * in quotemeta() at the point where \E is encountered. */ @Override protected void parseEscapeSequence() { - if (inQuotemeta) { - // In quotemeta mode, everything is literal except \E - var token = tokens.get(parser.tokenIndex); - if (token.text.startsWith("E")) { - // End quotemeta mode - TokenUtils.consumeChar(parser); - flushCurrentSegment(); - if (!caseModifiers.isEmpty() && caseModifiers.peek().type.equals("Q")) { - applyCaseModifier(caseModifiers.pop()); - } - inQuotemeta = false; - } else if (token.text.startsWith("Q")) { - // In quotemeta mode, \Q is idempotent and should be ignored. - TokenUtils.consumeChar(parser); - } else { - // Everything else is literal, including the backslash - currentSegment.append("\\"); - } - return; - } - if (parseEscapes) { parseDoubleQuotedEscapes(); } else { @@ -423,7 +398,6 @@ private void parseDoubleQuotedEscapesRegex() { // Quotemeta modifier case "Q" -> { flushCurrentSegment(); - inQuotemeta = true; caseModifiers.push(new CaseModifier("Q", false)); } @@ -525,7 +499,6 @@ private void parseDoubleQuotedEscapes() { // Quotemeta modifier case "Q" -> { flushCurrentSegment(); - inQuotemeta = true; caseModifiers.push(new CaseModifier("Q", false)); }