Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
06c4813
test(eo-parser): add test case for auto phi formation with applicatio…
h1alexbel Sep 17, 2025
9bdb52f
test: update test cases to reflect new auto phi formation behavior wi…
h1alexbel Sep 17, 2025
da64738
refactor(XeEoListener): rename APPLICATION_PRECEDENCE to A_PRECEDENCE…
h1alexbel Sep 17, 2025
554385c
bug(#4559): add new transpile pack for auto phi formation with applic…
h1alexbel Sep 17, 2025
d2f2257
bug(#4559): add new transpile pack for auto phi formation with applic…
h1alexbel Sep 17, 2025
2ebe627
bug(#4559): last application
h1alexbel Sep 17, 2025
32c2eec
bug(#4559): add auto-phi-with-application-precendence.yaml test resou…
h1alexbel Sep 19, 2025
18aeaaf
bug(#4559): refine XSL template to exclude positioned objects from au…
h1alexbel Sep 19, 2025
96763d6
bug(#4559): typo
h1alexbel Sep 19, 2025
eb1c1eb
bug(#4559): test case
h1alexbel Sep 22, 2025
d36d73f
bug(#4559): handle fully qualified names in auto-phi formation by str…
h1alexbel Sep 22, 2025
e2a0396
chore(#4559): remove empty line from test resource file
h1alexbel Sep 22, 2025
ece0c48
empty commit to restart pipelines
h1alexbel Sep 22, 2025
7bedfad
bug(#4559): add test case for auto phi formation from FQN precedence …
h1alexbel Sep 24, 2025
82cd9ba
bug(#4559): simplify Q-prefixed application handling by replacing Q w…
h1alexbel Sep 24, 2025
d9bea33
empty commit to restart pipelines
h1alexbel Sep 24, 2025
4ae096f
bug(#4559): auto-phi formation from application with \rho
h1alexbel Sep 25, 2025
ac2de15
bug(#4559): extend identifier pattern to support Unicode letters and …
h1alexbel Sep 25, 2025
0971a90
bug(#4559): redundant loop
h1alexbel Sep 25, 2025
82f1cb7
bug(#4559): typo
h1alexbel Sep 25, 2025
a67b94b
bug(#4559): add support for QQ prefix in EO applications to map to Φ.…
h1alexbel Sep 25, 2025
cfc1e13
bug(#4559): add test case for auto phi formation from nested application
h1alexbel Sep 25, 2025
f384915
bug(#4559): skip auto-phi formation test due to parsing issues with n…
h1alexbel Sep 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
out: []
file: org/eolang/snippets/foo.eo
args: ["org.eolang.snippets.foo"]
eo: |
+alias org.eolang.io.stdout
+alias org.eolang.txt.text
+alias org.eolang.structs.list
+package org.eolang.snippets

[] > foo
"abcdefghijk" > origin
origin > @
[cont-list] > custom-map
mapped. > @
cont-list
(text orgn).contains x >> [x]
origin > orgn!

[] +> test-custom-map
eq. > @
list (* true true)
foo.custom-map (list (* "abc" "ghi"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets:
- /org/eolang/maven/transpile/set-locators.xsl
- /org/eolang/maven/transpile/set-original-names.xsl
- /org/eolang/maven/transpile/classes.xsl
- /org/eolang/maven/transpile/tests.xsl
- /org/eolang/maven/transpile/attrs.xsl
- /org/eolang/maven/transpile/data.xsl
- /org/eolang/maven/transpile/to-java.xsl
asserts:
- /object[not(errors)]
- //java[contains(text(), 'Φ.custom-map.ap🌵46.φ')]
- //java[contains(text(), 'Φ.custom-map.ap🌵46.φ.ρ.ρ.α0')]
- //java[contains(text(), 'Phi rrbb = Phi.Φ.take("org").take("eolang").take("text");')]
- //java[contains(text(), 'rrbb1 = new PhMethod(rrbb1, "orgn");')]
- //java[contains(text(), 'Phi rrb = new PhMethod(rrbb, "what");')]
- //java[contains(text(), 'Phi rrb1 = Phi.Φ.take("org").take("eolang").take("b");')]
- //java[contains(text(), 'Phi rr = new PhMethod(rrb, "ttt");')]
input: |
[cont-list] > custom-map
mapped. > @
cont-list
((text orgn).what b).ttt >> [y]
origin > orgn!
57 changes: 52 additions & 5 deletions eo-parser/src/main/java/org/eolang/parser/XeEoListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
Expand All @@ -35,6 +37,11 @@
"PMD.GodClass"
})
final class XeEoListener implements EoListener, Iterable<Directive> {
/**
* Last application.
*/
private static final Pattern LAST_APPLICATION = Pattern.compile("\\)\\.(\\p{L}[\\p{L}\\p{N}-]*)$");

/**
* Xembly directives we are building (mutable).
*/
Expand Down Expand Up @@ -158,7 +165,9 @@ public void exitObject(final EoParser.ObjectContext ctx) {
@Override
public void enterBound(final EoParser.BoundContext ctx) {
if (ctx.just() != null && ctx.aphi() != null && ctx.just().finisher() != null) {
this.startAutoPhiFormation(ctx, ctx.just().finisher().getText());
this.startAutoPhiFormation(
ctx, XeEoListener.eoApplicationToXmir(ctx.just().finisher().getText())
);
}
}

Expand Down Expand Up @@ -367,7 +376,9 @@ public void exitHapplicationExtended(final EoParser.HapplicationExtendedContext

@Override
public void enterOnlyAphi(final EoParser.OnlyAphiContext ctx) {
this.startAutoPhiFormation(ctx, ctx.happlicationHeadExtended().getText());
this.startAutoPhiFormation(
ctx, XeEoListener.eoApplicationToXmir(ctx.happlicationHeadExtended().getText())
);
}

@Override
Expand Down Expand Up @@ -661,7 +672,12 @@ public void enterVapplicationArgUnbound(final EoParser.VapplicationArgUnboundCon
final EoParser.VapplicationArgUnboundCurrentContext vertical =
ctx.vapplicationArgUnboundCurrent();
if (vertical.just() != null || vertical.method() != null) {
this.startAutoPhiFormation(ctx, XeEoListener.verticalApplicationBase(vertical));
this.startAutoPhiFormation(
ctx,
XeEoListener.eoApplicationToXmir(
XeEoListener.verticalApplicationBase(vertical)
)
);
}
} else {
this.objects.enter();
Expand Down Expand Up @@ -699,7 +715,7 @@ public void enterVapplicationArgUnboundNext(
) {
if (ctx.aphi() != null) {
this.startAutoPhiFormation(
ctx, ctx.vapplicationHead().getText()
ctx, XeEoListener.eoApplicationToXmir(ctx.vapplicationHead().getText())
);
}
}
Expand Down Expand Up @@ -1210,13 +1226,44 @@ private String alphaAttr(final ParserRuleContext ctx, final String msg) {
* @param application Application base
*/
private void startAutoPhiFormation(final ParserRuleContext ctx, final String application) {
final Matcher matcher = XeEoListener.LAST_APPLICATION.matcher(application);
final String abase;
if (matcher.find()) {
abase = String.format(".%s", matcher.group(1));
} else {
abase = application;
}
this.startAbstract(ctx)
.enter().prop("name", new AutoName(ctx, "p").asString())
.start(ctx)
.prop("base", String.format("ξ.ρ.%s", application))
.prop("base", abase)
.prop("name", "φ");
}

/**
* EO application to XMIR base.
* @param application Application to transform
* @return Application base in XMIR format
*/
private static String eoApplicationToXmir(final String application) {
final String transformed = application.replace("^.", "ρ.");
final String base;
if (transformed.startsWith("QQ.")) {
base = transformed.replace("QQ", "Φ.org.eolang");
} else if (transformed.startsWith("Q.")) {
base = transformed.replace("Q.", "Φ.");
} else {
base = transformed;
}
final String result;
if (base.startsWith("ρ.") || base.startsWith("Φ.")) {
result = base;
} else {
result = String.format("ξ.ρ.%s", base);
Copy link
Member

@maxonfjvipon maxonfjvipon Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@h1alexbel again, I strongly believe there's no need to append ξ.ρ. before base, imagine such code:

[] > foo
  5 > x
  [] > bar
    [] > baz
      x.some >> []

You'll translate it to

[] > foo
  5 > x
  [] > bar
    [] > baz
      [] > some-auto-name
        $.^.x.some > @

But this is wrong, should be $.^.^.^.x.some, and it'll be as such, but later, on XSL transformations step

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxonfjvipon please check this. How about we add this test case as disabled with puzzle?

}
return result;
}

/**
* Trim margin from text block.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@
</xsl:copy>
</xsl:template>
<!-- Remove redundant ξ.X for void attributes, located inside the auto-phi formation -->
<xsl:template match="o[starts-with(@base,'ξ.') and ancestor::o[contains(@name,'ap🌵')][descendant::o[@base='∅' and @name=substring-after(current()/@base,'ξ.')]]]"/>
<xsl:template match="o[starts-with(@base,'ξ.') and not(@pos) and ancestor::o[contains(@name,'ap🌵')][descendant::o[@base='∅' and @name=substring-after(current()/@base,'ξ.')]]]"/>
</xsl:stylesheet>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[@name='φ' and @base='.as-j']/o[@base='.as-i']/o[@base='Φ.org.eolang.text']/o[@base='ξ.ρ.args']]
- //o[@base='.as-i' and not(@name)]/o[2][@base='Φ.org.eolang.as-bar.b']
input: |
[args] > foo
bar > i
((text args).as-i as-bar.b).as-j >> [x]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[@name='φ' and @base='ρ.x.ρ.y.ρ.z']]
input: |
[args] > main
a > x1
^.x.^.y.^.z >> [y]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[2][@name='x' and @base='∅' and not(@as)] and o[3][@name='φ' and @base='Φ.a.bca.eaa.boom']/o[1][@base='Φ.org.eolang.number']]
input: |
[] > foo
start > @
Q.a.bca.eaa.boom 42 >> [x]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[@name='φ' and @base='.j']/o[@base='.i']/o[@base='Φ.org.eolang.txt.text']/o[@base='ξ.ρ.args']]
- //o[@base='.i' and not(@name)]/o[2][@base='Φ.org.foo.b']
input: |
[args] > main
foo > app
((Q.org.eolang.txt.text args).i Q.org.foo.b).j >> [y]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
# @todo #4559:60min Enable the test after auto-phi formations under nested abstracts will be parsed
# correctly. For now, we just appending `ξ.ρ` to the application `@base`. We should not do this,
# instead, we keep it as `@base`, allowing XSL transformations resolve the scope correctly. This
# puzzle depends on this issue: https://github.com/objectionary/eo/issues/4557
skip: true
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵68' and o[@name='φ' and @base='ξ.ρ.ρ.ρ.ρ.x.some']]
input: |
[] > foo
5 > x
[] > bar
[] > baz
[] > bus
start > nested
x.some >> []
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[2][@name='x' and @base='∅' and not(@as)] and o[3][@name='φ' and @base='Φ.org.eolang.foo.bar']/o[1][@base='Φ.org.eolang.number']]
input: |
[] > main
start > @
QQ.foo.bar 42 >> [x]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright (c) 2016-2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='ap🌵34' and o[@name='φ' and @base='.ttt']/o[@base='.what']/o[@base='Φ.org.eolang.text']/o[@base='ξ.ρ.orgn']]
- //o[not(@base) and @name='ap🌵54' and o[@name='φ' and @base='.g']/o[@base='.e']/o[@base='.c']]
- //o[not(@base) and @name='ap🌵86' and o[@name='φ' and @base='.contains']/o[@base='Φ.org.eolang.text']/o[@base='ξ.ρ.orgn']]
- //o[not(@base) and @name='ap🌵86' and o[@name='φ' and @base='.contains']/o[@base='ξ.x']]
input: |
[cont-list] > custom-map
foo > boom
((text orgn).what b).ttt >> [y]
bar > dummy
(((a b).c d).e f).g >> [v]
mapped. > @
cont-list
(text orgn).contains x >> [x]
origin > orgn!
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
sheets: []
asserts:
- /object[not(errors)]
- //o[not(@base) and @name='a🌵34' and o[2][@name='i' and @base='∅'] and o[3][@name='φ']]
- //o[@base='Φ.org.eolang.foo' and o[@base='ξ.a🌵34']]
- //o[not(@base) and @name='ap🌵34' and o[2][@name='i' and @base='∅'] and o[3][@name='φ']]
- //o[@base='Φ.org.eolang.foo' and o[@base='ξ.ap🌵34']]
input: |
[] > main
foo > @
Expand Down
Loading