From f7e9e7bfe6e9cab161328457cfe864fa9947784d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Tue, 9 Jan 2024 16:59:19 +0100 Subject: [PATCH 01/16] Simplify format for lkql error messages --- .../functions/NodeCheckerFunction.java | 3 --- .../functions/UnitCheckerFunction.java | 2 -- .../lkql_jit/utils/functions/CheckerUtils.java | 11 ++--------- .../tests/gnatcheck_errors/lkql_error/test.out | 18 +++++++++--------- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/NodeCheckerFunction.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/NodeCheckerFunction.java index 67a43ccd9..041786436 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/NodeCheckerFunction.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/NodeCheckerFunction.java @@ -224,8 +224,6 @@ private void executeCheckers( currentNode.getUnit(), currentNode.getSourceLocationRange().start, e.getLoc().toString(), - StringUtils.concat( - "LANGKIT_SUPPORT.ERRORS.", e.getKind()), e.getMsg(), context); } @@ -238,7 +236,6 @@ private void executeCheckers( currentNode.getUnit(), currentNode.getSourceLocationRange().start, e.getLocationString(), - "LKQL.ERRORS.STOP_EVALUATION_ERROR", e.getRawMessage(), context); } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java index 8226d62a7..e1f8996e0 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java @@ -113,7 +113,6 @@ public Object executeGeneric(VirtualFrame frame) { unit, Libadalang.SourceLocation.create(1, (short) 1), e.getLoc().toString(), - StringUtils.concat("LANGKIT_SUPPORT.ERRORS.", e.getKind()), e.getMsg(), context); } @@ -126,7 +125,6 @@ public Object executeGeneric(VirtualFrame frame) { unit, Libadalang.SourceLocation.create(1, (short) 1), e.getLocationString(), - "LKQL.ERRORS.STOP_EVALUATION_ERROR", e.getRawMessage(), context); } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/CheckerUtils.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/CheckerUtils.java index 3f47f89bd..b29f401eb 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/CheckerUtils.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/CheckerUtils.java @@ -100,7 +100,6 @@ void emitMissingFile( * @param unit The analysis unit in which the error occurred. * @param adaLocation The location in the unit of the error. * @param errorLocation The location in the LKQL code which rose the exception. - * @param errorName The name of the error. * @param errorMessage The message of the error. * @param context The context to output the message. */ @@ -109,7 +108,6 @@ void emitInternalError( Libadalang.AnalysisUnit unit, Libadalang.SourceLocation adaLocation, String errorLocation, - String errorName, String errorMessage, LKQLContext context); } @@ -155,13 +153,12 @@ public void emitInternalError( final Libadalang.AnalysisUnit unit, final Libadalang.SourceLocation adaLocation, final String errorLocation, - final String errorName, final String errorMessage, final LKQLContext context) { context.println( unit.getFileName(false) - + ":1:01: internal error: " - + errorName + + ":" + + adaLocation.toString() + ":" + errorLocation + ": " @@ -293,7 +290,6 @@ public void emitInternalError( final Libadalang.AnalysisUnit unit, final Libadalang.SourceLocation adaLocation, final String errorLocation, - final String errorName, final String errorMessage, final LKQLContext context) { context.println( @@ -306,9 +302,6 @@ public void emitInternalError( + "internal error at " + errorLocation + ": " - + "raised " - + errorName - + " : " + errorMessage + " [" + ruleName.toLowerCase() diff --git a/testsuite/tests/gnatcheck_errors/lkql_error/test.out b/testsuite/tests/gnatcheck_errors/lkql_error/test.out index 0f724cc99..70492b547 100644 --- a/testsuite/tests/gnatcheck_errors/lkql_error/test.out +++ b/testsuite/tests/gnatcheck_errors/lkql_error/test.out @@ -32,14 +32,14 @@ Total gnatcheck failures: 9 6. Gnatcheck internal errors -main.adb:1:01: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:1:01: internal error at foo_unit.lkql:4:22: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:1:11: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:1:18: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:2:06: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:3:04: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:3:08: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:4:05: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access -main.adb:4:10: internal error at foo.lkql:4:17: raised LKQL.ERRORS.STOP_EVALUATION_ERROR : Null receiver in dot access +main.adb:1:01: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:1:01: internal error at foo_unit.lkql:4:22: Null receiver in dot access +main.adb:1:11: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:1:18: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:2:06: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:3:04: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:3:08: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:4:05: internal error at foo.lkql:4:17: Null receiver in dot access +main.adb:4:10: internal error at foo.lkql:4:17: Null receiver in dot access >>>program returned status code 2 From a66aac53f71ef86250eb6848835b2189d9cfd2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Mon, 8 Jan 2024 13:28:47 +0100 Subject: [PATCH 02/16] Prepare for work on pattern matching more than nodes & strings * Make matchers have a unique `executeValue` function rather than two specialized `executeNode` & `executeString` functions Those were already becoming a maintenance burden in some cases. * Allow selectors, selector lists, & LKQLDepthValue to store anything (not only nodes). * DepthNode values should never be exposed, so make selectors `FunCall`s return LKQLLists rather than selector lists. * Rework DetailValue & descendants to use specializations --- .../com/adacore/lkql_jit/LKQLTypeSystem.java | 35 ----------- .../built_ins/functions/MapFunction.java | 2 +- .../built_ins/selectors/ReadBuiltInThis.java | 3 +- ...LKQLDepthNode.java => LKQLDepthValue.java} | 43 ++++++-------- .../built_ins/values/lists/LKQLLazyList.java | 6 +- .../values/lists/LKQLListComprehension.java | 2 +- .../values/lists/LKQLSelectorList.java | 59 ++++++++++++------- .../passes/TranslationPass.java | 7 +-- .../declarations/selector/SelectorArm.java | 17 +++--- .../nodes/dispatchers/SelectorDispatcher.java | 8 +-- .../lkql_jit/nodes/expressions/FunCall.java | 5 +- .../lkql_jit/nodes/expressions/Query.java | 17 ++---- .../nodes/expressions/match/MatchArm.java | 49 ++------------- .../nodes/expressions/operators/IsClause.java | 2 +- .../lkql_jit/nodes/patterns/BasePattern.java | 18 +----- .../nodes/patterns/BindingPattern.java | 25 ++------ .../nodes/patterns/FilteredPattern.java | 9 +-- .../lkql_jit/nodes/patterns/NotPattern.java | 19 +----- .../lkql_jit/nodes/patterns/NullPattern.java | 9 +-- .../lkql_jit/nodes/patterns/OrPattern.java | 25 ++------ .../lkql_jit/nodes/patterns/ParenPattern.java | 19 +----- .../lkql_jit/nodes/patterns/RegexPattern.java | 31 ++++------ .../lkql_jit/nodes/patterns/SelectorCall.java | 19 +++--- .../nodes/patterns/UniversalPattern.java | 17 +----- .../chained_patterns/ChainedNodePattern.java | 8 +-- .../chained_patterns/ChainedPatternLink.java | 4 +- .../patterns/node_patterns/DetailExpr.java | 46 +++++++++------ .../patterns/node_patterns/DetailPattern.java | 37 ++---------- .../patterns/node_patterns/DetailValue.java | 2 +- .../node_patterns/ExtendedNodePattern.java | 31 ++++++---- .../node_patterns/NodeKindPattern.java | 8 +-- .../nodes/root_nodes/SelectorRootNode.java | 16 ++--- .../com/adacore/lkql_jit/LKQLLauncher.java | 2 + .../tests/interop/selector_list/Main.java | 33 ----------- .../tests/interop/selector_list/test.out | 10 ---- .../tests/interop/selector_list/test.yaml | 1 - 36 files changed, 205 insertions(+), 439 deletions(-) rename lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/{LKQLDepthNode.java => LKQLDepthValue.java} (79%) delete mode 100644 testsuite/tests/interop/selector_list/Main.java delete mode 100644 testsuite/tests/interop/selector_list/test.out delete mode 100644 testsuite/tests/interop/selector_list/test.yaml diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java index 5af1aa15c..00f089bda 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java @@ -145,39 +145,4 @@ public static boolean asBoolean(Object value) { public static BigInteger longToBigInteger(long value) { return BigInteger.valueOf(value); } - - // ----- Node value methods ----- - - /** - * Check is a value is an ada node. - * - * @param nodeObject The object to check. - * @return True if the object is an ada node, false else. - */ - @TypeCheck(Libadalang.AdaNode.class) - public static boolean isAdaNode(Object nodeObject) { - return nodeObject instanceof Libadalang.AdaNode || nodeObject instanceof LKQLDepthNode; - } - - /** - * Cast a generic value to an ada node. - * - * @param nodeObject The node object. - * @return The object cast to an ada node. - */ - @TypeCast(Libadalang.AdaNode.class) - public static Libadalang.AdaNode asAdaNode(Object nodeObject) { - // If the value is a node - if (nodeObject instanceof Libadalang.AdaNode adaNode) { - return adaNode; - } - - // If the value is a depth node - else if (nodeObject instanceof LKQLDepthNode depthNode) { - return depthNode.getNode(); - } - - // Return the default value - return LKQLNull.INSTANCE; - } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/MapFunction.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/MapFunction.java index 29e01873a..9e1d3acc9 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/MapFunction.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/MapFunction.java @@ -94,7 +94,7 @@ public Object executeGeneric(VirtualFrame frame) { this.callNode.getArgList().getArgs()[1]); } - // Verify the function arrity + // Verify the function arity if (mapFunction.parameterNames.length != 1) { throw LKQLRuntimeException.fromMessage( "Function passed to map should have arity of one", diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java index 562e2385a..983b29264 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java @@ -22,6 +22,7 @@ package com.adacore.lkql_jit.built_ins.selectors; +import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; import com.adacore.lkql_jit.nodes.expressions.Expr; import com.oracle.truffle.api.frame.VirtualFrame; @@ -45,7 +46,7 @@ public ReadBuiltInThis() { */ @Override public Object executeGeneric(VirtualFrame frame) { - return frame.getArguments()[1]; + return ((LKQLDepthValue) frame.getArguments()[1]).value; } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthNode.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java similarity index 79% rename from lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthNode.java rename to lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java index dd95351ca..248dccdff 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthNode.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.built_ins.values; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.built_ins.values.bases.BasicLKQLValue; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Fallback; @@ -37,32 +36,22 @@ * all Libadalang objects will be wrapped in interop LKQL values (#154). */ @ExportLibrary(InteropLibrary.class) -public final class LKQLDepthNode extends BasicLKQLValue { +public final class LKQLDepthValue extends BasicLKQLValue { // ----- Attributes ----- /** The depth of the node. */ - private final int depth; + public final int depth; /** The decorated node. */ - private final Libadalang.AdaNode node; + public final Object value; // ----- Constructors ----- /** Create a new depth node. */ - public LKQLDepthNode(int depth, Libadalang.AdaNode node) { + public LKQLDepthValue(int depth, Object value) { this.depth = depth; - this.node = node; - } - - // ----- Getters ----- - - public int getDepth() { - return depth; - } - - public Libadalang.AdaNode getNode() { - return node; + this.value = value; } // ----- Value methods ----- @@ -72,14 +61,15 @@ public Libadalang.AdaNode getNode() { public static class IsIdenticalOrUndefined { /** Compare two LKQL depth nodes. */ @Specialization - protected static TriState onNode(final LKQLDepthNode left, final LKQLDepthNode right) { - return TriState.valueOf(left.node.equals(right.node)); + @CompilerDirectives.TruffleBoundary + protected static TriState onNode(final LKQLDepthValue left, final LKQLDepthValue right) { + return TriState.valueOf(left.value.equals(right.value)); } /** Do the comparison with another element. */ @Fallback protected static TriState onOther( - @SuppressWarnings("unused") final LKQLDepthNode receiver, + @SuppressWarnings("unused") final LKQLDepthValue receiver, @SuppressWarnings("unused") final Object other) { return TriState.UNDEFINED; } @@ -88,33 +78,36 @@ protected static TriState onOther( /** Return the identity hash code for the given LKQL depth node. */ @ExportMessage @CompilerDirectives.TruffleBoundary - public static int identityHashCode(final LKQLDepthNode receiver) { + public static int identityHashCode(final LKQLDepthValue receiver) { return System.identityHashCode(receiver); } /** Get the displayable string for the interop library. */ @ExportMessage + @CompilerDirectives.TruffleBoundary public String toDisplayString(@SuppressWarnings("unused") final boolean allowSideEffects) { - return this.node.toString(); + return this.toString(); } // ----- Override methods ----- @Override + @CompilerDirectives.TruffleBoundary public String toString() { - return this.node.toString(); + return ""; } @Override @CompilerDirectives.TruffleBoundary public int hashCode() { - return this.node.hashCode(); + return this.value.hashCode(); } @Override + @CompilerDirectives.TruffleBoundary public boolean equals(Object o) { if (o == this) return true; - if (!(o instanceof LKQLDepthNode other)) return false; - return this.node.equals(other.node); + if (!(o instanceof LKQLDepthValue other)) return false; + return this.value.equals(other.value); } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java index a0fe64c59..c4dcac1f4 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java @@ -53,19 +53,19 @@ protected LKQLLazyList() { * Initialize the lazy list cache to the given index. If n < 0 then initialize all the lazy list * values. */ - public abstract void initCache(long n); + public abstract void computeItemAt(long n); // ----- List required methods ----- @Override public long size() { - this.initCache(-1); + this.computeItemAt(-1); return this.cache.size(); } @Override public Object get(long i) throws InvalidIndexException { - this.initCache(i); + this.computeItemAt(i); try { return this.cache.get((int) i); } catch (IndexOutOfBoundsException e) { diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLListComprehension.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLListComprehension.java index 55d41f86e..d0eae0f68 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLListComprehension.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLListComprehension.java @@ -80,7 +80,7 @@ public LKQLListComprehension( // ----- Lazy list required methods ----- @Override - public void initCache(long n) { + public void computeItemAt(long n) { while (this.pointer < this.argumentsList.length && (this.cache.size() - 1 < n || n < 0)) { final Object[] currentArguments = this.argumentsList[this.pointer++]; System.arraycopy(currentArguments, 0, this.arguments, 1, currentArguments.length); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java index 8cf4df625..b40e8b648 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java @@ -24,7 +24,9 @@ import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; +import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; +import com.adacore.lkql_jit.exception.LKQLRuntimeException; +import com.adacore.lkql_jit.exception.utils.InvalidIndexException; import com.adacore.lkql_jit.nodes.dispatchers.SelectorDispatcher; import com.adacore.lkql_jit.nodes.dispatchers.SelectorDispatcherNodeGen; import com.adacore.lkql_jit.nodes.root_nodes.SelectorRootNode; @@ -53,10 +55,10 @@ public class LKQLSelectorList extends LKQLLazyList { private final SelectorDispatcher dispatcher; /** The cache of already explored nodes. */ - private final HashSet alreadyVisited; + private final HashSet alreadyVisited; /** The list of the node to recurs on. */ - private final List recursList; + private final List recursList; /** The maximal depth for the return. */ private final int maxDepth; @@ -65,7 +67,7 @@ public class LKQLSelectorList extends LKQLLazyList { private final int minDepth; /** The precise depth to get from the selector. */ - private final int depth; + private final int exactDepth; // ----- Constructors ----- @@ -94,17 +96,17 @@ public LKQLSelectorList( this.recursList = new LinkedList<>(); this.maxDepth = maxDepth; this.minDepth = minDepth; - this.depth = depth; - this.recursList.add(new LKQLDepthNode(0, adaNode)); + this.exactDepth = depth; + this.recursList.add(new LKQLDepthValue(0, adaNode)); } // ----- Lazy list required methods ----- @Override - public void initCache(long n) { + public void computeItemAt(long n) { while (!(this.recursList.size() == 0) && (this.cache.size() - 1 < n || n == -1)) { // Get the first recurse item and execute the selector on it - LKQLDepthNode nextNode = this.recursList.remove(0); + LKQLDepthValue nextNode = this.recursList.remove(0); SelectorRootNode.SelectorCallResult result = this.dispatcher.executeDispatch( this.rootNode, this.closure.getContent(), nextNode); @@ -124,19 +126,21 @@ public void initCache(long n) { @CompilerDirectives.TruffleBoundary private void addResult(Object toAdd) { // If the object is just a node - if (toAdd instanceof LKQLDepthNode node) { + if (toAdd instanceof LKQLDepthValue node) { if (!this.alreadyVisited.contains(node)) { this.addNodeResult(node); } } // If the object is an array of node - else if (toAdd instanceof LKQLDepthNode[] nodes) { - for (LKQLDepthNode node : nodes) { + else if (toAdd instanceof LKQLDepthValue[] nodes) { + for (LKQLDepthValue node : nodes) { if (!this.alreadyVisited.contains(node)) { this.addNodeResult(node); } } + } else { + throw LKQLRuntimeException.shouldNotHappen("Should not happen"); } } @@ -144,15 +148,15 @@ else if (toAdd instanceof LKQLDepthNode[] nodes) { @CompilerDirectives.TruffleBoundary private void addRecurs(Object toAdd) { // If the object is just a node - if (toAdd instanceof LKQLDepthNode node) { + if (toAdd instanceof LKQLDepthValue node) { if (!this.alreadyVisited.contains(node)) { this.recursList.add(node); } } // If the object is an array of node - else if (toAdd instanceof LKQLDepthNode[] nodes) { - for (LKQLDepthNode node : nodes) { + else if (toAdd instanceof LKQLDepthValue[] nodes) { + for (LKQLDepthValue node : nodes) { if (!this.alreadyVisited.contains(node)) { this.recursList.add(node); } @@ -164,7 +168,7 @@ else if (toAdd instanceof LKQLDepthNode[] nodes) { @CompilerDirectives.TruffleBoundary private void addRecursAndResult(Object toAdd) { // If the object is just a node - if (toAdd instanceof LKQLDepthNode node) { + if (toAdd instanceof LKQLDepthValue node) { if (!this.alreadyVisited.contains(node)) { this.addNodeResult(node); this.recursList.add(node); @@ -172,8 +176,8 @@ private void addRecursAndResult(Object toAdd) { } // If the object is an array of node - else if (toAdd instanceof LKQLDepthNode[] nodes) { - for (LKQLDepthNode node : nodes) { + else if (toAdd instanceof LKQLDepthValue[] nodes) { + for (LKQLDepthValue node : nodes) { if (!this.alreadyVisited.contains(node)) { this.addNodeResult(node); this.recursList.add(node); @@ -184,11 +188,11 @@ else if (toAdd instanceof LKQLDepthNode[] nodes) { /** Add a node in the result and hashed cache with all verifications. */ @CompilerDirectives.TruffleBoundary - private void addNodeResult(LKQLDepthNode node) { + private void addNodeResult(LKQLDepthValue node) { // If there is no defined depth - if (this.depth < 0) { - if ((this.maxDepth < 0 || node.getDepth() <= this.maxDepth) - && (this.minDepth < 0 || node.getDepth() >= this.minDepth)) { + if (this.exactDepth < 0) { + if ((this.maxDepth < 0 || node.depth <= this.maxDepth) + && (this.minDepth < 0 || node.depth >= this.minDepth)) { this.cache.add(node); this.alreadyVisited.add(node); } @@ -196,13 +200,24 @@ private void addNodeResult(LKQLDepthNode node) { // Else, only get the wanted nodes else { - if (node.getDepth() == this.depth) { + if (node.depth == this.exactDepth) { this.cache.add(node); this.alreadyVisited.add(node); } } } + @Override + public Object get(long i) throws InvalidIndexException { + this.computeItemAt(i); + try { + var cache = this.cache.get((int) i); + return ((LKQLDepthValue) cache).value; + } catch (IndexOutOfBoundsException e) { + throw new InvalidIndexException(); + } + } + // ----- Value methods ----- /** Return the identity hash code for the given LKQL selector list. */ diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java index bcf86251f..3ab4be566 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java @@ -50,7 +50,6 @@ import com.adacore.lkql_jit.nodes.expressions.literals.*; import com.adacore.lkql_jit.nodes.expressions.match.Match; import com.adacore.lkql_jit.nodes.expressions.match.MatchArm; -import com.adacore.lkql_jit.nodes.expressions.match.MatchArmNodeGen; import com.adacore.lkql_jit.nodes.expressions.operators.*; import com.adacore.lkql_jit.nodes.expressions.value_read.*; import com.adacore.lkql_jit.nodes.patterns.*; @@ -921,7 +920,7 @@ public LKQLNode visit(Liblkqllang.RegexPattern regexPattern) { regex = regex.substring(1, regex.length() - 1); // Return the new regex pattern node - return new RegexPattern(loc(regexPattern), regex); + return RegexPatternNodeGen.create(loc(regexPattern), regex); } /** @@ -1567,7 +1566,7 @@ public LKQLNode visit(Liblkqllang.DetailExpr detailExpr) { final Expr expr = (Expr) detailExpr.fExprValue().accept(this); // Return the new detail expression node - return new DetailExpr(loc(detailExpr), expr); + return DetailExprNodeGen.create(loc(detailExpr), expr); } /** @@ -1780,7 +1779,7 @@ public LKQLNode visit(Liblkqllang.MatchArm matchArm) { this.scriptFrames.exitFrame(); // Return the new match arm - return MatchArmNodeGen.create(loc(matchArm), pattern, expr); + return new MatchArm(loc(matchArm), pattern, expr); } @Override diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java index ef1a3e3e4..7f5db70aa 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java @@ -23,7 +23,7 @@ package com.adacore.lkql_jit.nodes.declarations.selector; import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; +import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.LKQLNode; import com.adacore.lkql_jit.nodes.patterns.BasePattern; @@ -97,22 +97,21 @@ public Object executeGeneric(VirtualFrame frame) { * @param node The node to match. * @return The result of the arm execution or null if the arm doesn't match. */ - public SelectorRootNode.SelectorCallResult executeArm(VirtualFrame frame, LKQLDepthNode node) { - if (this.pattern.executeNode(frame, node.getNode())) { + public SelectorRootNode.SelectorCallResult executeArm(VirtualFrame frame, LKQLDepthValue node) { + if (this.pattern.executeValue(frame, node.value)) { // Execute the selector expression Object res = this.expr.executeGeneric(frame); // If the result of the expression is an array if (res instanceof Object[] resList) { - List depthNodes = new ArrayList<>(resList.length); + List depthNodes = new ArrayList<>(resList.length); for (Object obj : resList) { // For each object of the array, verify that it is a node try { if (!LKQLTypeSystemGen.isNullish(obj)) { depthNodes.add( - new LKQLDepthNode( - node.getDepth() + 1, - LKQLTypeSystemGen.expectAdaNode(obj))); + new LKQLDepthValue( + node.depth + 1, LKQLTypeSystemGen.expectAdaNode(obj))); } } @@ -123,7 +122,7 @@ public SelectorRootNode.SelectorCallResult executeArm(VirtualFrame frame, LKQLDe } } return new SelectorRootNode.SelectorCallResult( - this.expr.getMode(), depthNodes.toArray(new LKQLDepthNode[0])); + this.expr.getMode(), depthNodes.toArray(new LKQLDepthValue[0])); } // If the result of the expression is nullish @@ -135,7 +134,7 @@ else if (LKQLTypeSystemGen.isNullish(res)) { else if (LKQLTypeSystemGen.isAdaNode(res)) { return new SelectorRootNode.SelectorCallResult( this.expr.getMode(), - new LKQLDepthNode(node.getDepth() + 1, LKQLTypeSystemGen.asAdaNode(res))); + new LKQLDepthValue(node.depth + 1, LKQLTypeSystemGen.asAdaNode(res))); } // Throw an exception diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java index 2bc47df35..7c060f08b 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java @@ -22,7 +22,7 @@ package com.adacore.lkql_jit.nodes.dispatchers; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; +import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; import com.adacore.lkql_jit.nodes.root_nodes.SelectorRootNode; import com.adacore.lkql_jit.runtime.Cell; import com.oracle.truffle.api.dsl.Cached; @@ -40,7 +40,7 @@ public abstract class SelectorDispatcher extends Node { /** Function to execute the selector root node and get the result. */ public abstract SelectorRootNode.SelectorCallResult executeDispatch( - SelectorRootNode rootNode, Cell[] closure, LKQLDepthNode node); + SelectorRootNode rootNode, Cell[] closure, LKQLDepthValue node); /** * Execute the selector root node with the direct path. @@ -54,7 +54,7 @@ public abstract SelectorRootNode.SelectorCallResult executeDispatch( protected static SelectorRootNode.SelectorCallResult executeCached( SelectorRootNode rootNode, Cell[] closure, - LKQLDepthNode node, + LKQLDepthValue node, @Cached("create(rootNode.getRealCallTarget())") DirectCallNode directCallNode) { return (SelectorRootNode.SelectorCallResult) directCallNode.call(closure, node); } @@ -71,7 +71,7 @@ protected static SelectorRootNode.SelectorCallResult executeCached( protected static SelectorRootNode.SelectorCallResult executeUncached( SelectorRootNode rootNode, Cell[] closure, - LKQLDepthNode node, + LKQLDepthValue node, @Cached IndirectCallNode indirectCallNode) { return (SelectorRootNode.SelectorCallResult) indirectCallNode.call(rootNode.getRealCallTarget(), closure, node); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java index 7859ccaec..0fddc8d9d 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java @@ -24,10 +24,7 @@ import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.built_ins.BuiltInFunctionValue; -import com.adacore.lkql_jit.built_ins.values.LKQLFunction; -import com.adacore.lkql_jit.built_ins.values.LKQLProperty; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.built_ins.values.LKQLUnit; +import com.adacore.lkql_jit.built_ins.values.*; import com.adacore.lkql_jit.built_ins.values.interfaces.Nullish; import com.adacore.lkql_jit.built_ins.values.lists.LKQLSelectorList; import com.adacore.lkql_jit.exception.LKQLRuntimeException; diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java index 861b17875..90ae61132 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java @@ -25,7 +25,6 @@ import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.LKQLLanguage; import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; import com.adacore.lkql_jit.built_ins.values.LKQLNull; import com.adacore.lkql_jit.built_ins.values.LKQLSelector; import com.adacore.lkql_jit.built_ins.values.interfaces.Iterable; @@ -163,7 +162,7 @@ else if (LKQLTypeSystemGen.isLKQLList(fromObject)) { // If the query mode is all if (this.kind == Kind.ALL) { // Prepare the result - List resNodes = new LinkedList<>(); + List resNodes = new ArrayList<>(); // For each root node, explore it and return the result for (int i = fromNodes.length - 1; i >= 0; i--) { @@ -205,10 +204,7 @@ private List exploreAll(VirtualFrame frame, Iterator nodeIte // Iterate on all node in the iterator while (nodeIterator.hasNext()) { // Get the current node - Libadalang.AdaNode adaNode = - this.throughExpr == null - ? (Libadalang.AdaNode) nodeIterator.next() - : ((LKQLDepthNode) nodeIterator.next()).getNode(); + Libadalang.AdaNode adaNode = (Libadalang.AdaNode) nodeIterator.next(); // If the pattern is a chained one if (this.pattern instanceof ChainedNodePattern chainedNodePattern) { @@ -220,7 +216,7 @@ private List exploreAll(VirtualFrame frame, Iterator nodeIte // Else, the pattern is a basic one else { - if (this.pattern.executeNode(frame, adaNode)) { + if (this.pattern.executeValue(frame, adaNode)) { resList.add(adaNode); } } @@ -241,10 +237,7 @@ private Libadalang.AdaNode exploreFirst(VirtualFrame frame, Iterator nodeIterato // Iterate on all node in the iterator while (nodeIterator.hasNext()) { // Get the current node - Libadalang.AdaNode adaNode = - this.throughExpr == null - ? (Libadalang.AdaNode) nodeIterator.next() - : ((LKQLDepthNode) nodeIterator.next()).getNode(); + Libadalang.AdaNode adaNode = (Libadalang.AdaNode) nodeIterator.next(); // If the pattern is a chained one if (this.pattern instanceof ChainedNodePattern chainedNodePattern) { @@ -256,7 +249,7 @@ private Libadalang.AdaNode exploreFirst(VirtualFrame frame, Iterator nodeIterato // Else, the pattern is a basic one else { - if (this.pattern.executeNode(frame, adaNode)) { + if (this.pattern.executeValue(frame, adaNode)) { return adaNode; } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/match/MatchArm.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/match/MatchArm.java index 0301d07fa..9454561f4 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/match/MatchArm.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/match/MatchArm.java @@ -22,14 +22,11 @@ package com.adacore.lkql_jit.nodes.expressions.match; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.LKQLNode; import com.adacore.lkql_jit.nodes.expressions.Expr; import com.adacore.lkql_jit.nodes.patterns.BasePattern; import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; /** @@ -37,7 +34,7 @@ * * @author Hugo GUERRIER */ -public abstract class MatchArm extends LKQLNode { +public class MatchArm extends LKQLNode { // ----- Children ----- @@ -60,7 +57,7 @@ public abstract class MatchArm extends LKQLNode { * @param pattern The pattern of the match arm. * @param expr The result of the match arm. */ - protected MatchArm(SourceLocation location, BasePattern pattern, Expr expr) { + public MatchArm(SourceLocation location, BasePattern pattern, Expr expr) { super(location); this.pattern = pattern; this.expr = expr; @@ -93,52 +90,14 @@ public final Object executeGeneric(VirtualFrame frame) { * @param toMatch The node to match. * @return The result of the arm expression if the pattern is valid, null else. */ - public abstract Object executeArm(VirtualFrame frame, Object toMatch); - - /** - * Execute the matching arm on a node value. - * - * @param frame The frame to execute in. - * @param node The node value. - * @return The match expression if the pattern is valid. - */ - @Specialization - protected Object onNode(VirtualFrame frame, Libadalang.AdaNode node) { - if (this.pattern.executeNode(frame, node)) { - return this.expr.executeGeneric(frame); - } else { - return null; - } - } - - /** - * Execute the matching arm on a string value. - * - * @param frame The frame to execute in. - * @param str The string value. - * @return The match expression if the pattern is valid. - */ - @Specialization - protected Object onString(VirtualFrame frame, String str) { - if (this.pattern.executeString(frame, str)) { + public Object executeArm(VirtualFrame frame, Object toMatch) { + if (this.pattern.executeValue(frame, toMatch)) { return this.expr.executeGeneric(frame); } else { return null; } } - /** - * Fallback when the value cannot be matched. - * - * @param frame The frame to execute in. - * @param other The value. - * @return Just null. - */ - @Fallback - protected Object onOther(VirtualFrame frame, Object other) { - return null; - } - // ----- Override methods ----- /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/operators/IsClause.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/operators/IsClause.java index f80774467..2b6e52256 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/operators/IsClause.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/operators/IsClause.java @@ -80,7 +80,7 @@ protected IsClause(SourceLocation location, DummyLocation nodeLocation, BasePatt */ @Specialization protected boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return this.pattern.executeNode(frame, node); + return this.pattern.executeValue(frame, node); } /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BasePattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BasePattern.java index 3cf20de73..d6117b232 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BasePattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BasePattern.java @@ -22,10 +22,8 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.LKQLNode; -import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -58,20 +56,8 @@ public final Object executeGeneric(VirtualFrame frame) { * Execute the pattern and get if the node fulfills it. * * @param frame The frame to execute the pattern in. - * @param node The node to verify. + * @param value The node to verify. * @return True of the node verify the pattern, false else. */ - public abstract boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node); - - /** - * Execute the pattern on a string. - * - * @param frame The frame to execute in. - * @param str The string to verify. - * @return True the string fulfills the pattern, false else. - */ - public boolean executeString(VirtualFrame frame, String str) { - throw LKQLRuntimeException.wrongType( - LKQLTypesHelper.ADA_NODE, LKQLTypesHelper.LKQL_STRING, this); - } + public abstract boolean executeValue(VirtualFrame frame, Object value); } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java index 61b4cc173..c0e701b23 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.utils.functions.FrameUtils; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -64,31 +63,15 @@ public BindingPattern(SourceLocation location, int slot, ValuePattern pattern) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { + public boolean executeValue(VirtualFrame frame, Object value) { // Do the node binding - FrameUtils.writeLocal(frame, this.slot, node); + FrameUtils.writeLocal(frame, this.slot, value); // Execute the pattern with the binding done - return this.pattern.executeNode(frame, node); - } - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { - // Do the node binding - FrameUtils.writeLocal(frame, this.slot, str); - - // Execute the pattern with the binding done - return this.pattern.executeString(frame, str); + return this.pattern.executeValue(frame, value); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/FilteredPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/FilteredPattern.java index 2116a9c37..e062f5d75 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/FilteredPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/FilteredPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.expressions.Expr; import com.adacore.lkql_jit.utils.LKQLTypesHelper; @@ -67,14 +66,12 @@ public FilteredPattern(SourceLocation location, UnfilteredPattern pattern, Expr // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { + public boolean executeValue(VirtualFrame frame, Object value) { // If the pattern match, execute the predicate - if (this.pattern.executeNode(frame, node)) { + if (this.pattern.executeValue(frame, value)) { // Try to execute the predicate in a boolean try { return this.predicate.executeBoolean(frame); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NotPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NotPattern.java index 266e1ec41..9051b6aa0 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NotPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NotPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -56,23 +55,11 @@ public NotPattern(SourceLocation location, ValuePattern pattern) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return !this.pattern.executeNode(frame, node); - } - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { - return !this.pattern.executeString(frame, str); + public boolean executeValue(VirtualFrame frame, Object value) { + return !this.pattern.executeValue(frame, value); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NullPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NullPattern.java index 2e701d786..8981e55b2 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NullPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/NullPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.built_ins.values.LKQLNull; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -48,13 +47,11 @@ public NullPattern(SourceLocation location) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return node == LKQLNull.INSTANCE; + public boolean executeValue(VirtualFrame frame, Object value) { + return value == LKQLNull.INSTANCE; } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/OrPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/OrPattern.java index 2956fb247..a08fe072e 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/OrPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/OrPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -63,31 +62,15 @@ public OrPattern(SourceLocation location, BasePattern left, BasePattern right) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { + public boolean executeValue(VirtualFrame frame, Object value) { // Do the short circuit - if (this.left.executeNode(frame, node)) { + if (this.left.executeValue(frame, value)) { return true; } else { - return this.right.executeNode(frame, node); - } - } - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { - if (this.left.executeString(frame, str)) { - return true; - } else { - return this.right.executeString(frame, str); + return this.right.executeValue(frame, value); } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/ParenPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/ParenPattern.java index 83b0d049b..042d2dc0a 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/ParenPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/ParenPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -56,23 +55,11 @@ public ParenPattern(SourceLocation location, BasePattern pattern) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return this.pattern.executeNode(frame, node); - } - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { - return this.pattern.executeString(frame, str); + public boolean executeValue(VirtualFrame frame, Object value) { + return this.pattern.executeValue(frame, value); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/RegexPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/RegexPattern.java index ff624b256..ae8641f12 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/RegexPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/RegexPattern.java @@ -26,6 +26,8 @@ import com.adacore.lkql_jit.built_ins.values.LKQLNull; import com.adacore.lkql_jit.built_ins.values.LKQLPattern; import com.adacore.lkql_jit.utils.source_location.SourceLocation; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; /** @@ -33,7 +35,7 @@ * * @author Hugo GUERRIER */ -public final class RegexPattern extends ValuePattern { +public abstract class RegexPattern extends ValuePattern { // ----- Attributes ----- @@ -53,26 +55,19 @@ public RegexPattern(SourceLocation location, String regex) { this.pattern = new LKQLPattern(this, regex, true); } - // ----- Execution methods ----- + @Specialization + public boolean onAdaNode(VirtualFrame frame, Libadalang.AdaNode node) { + return node != LKQLNull.INSTANCE && this.pattern.contains(node.getText()); + } - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) - */ - @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return this.pattern.contains(node.getText()) && node != LKQLNull.INSTANCE; + @Specialization + public boolean onString(VirtualFrame frame, String value) { + return pattern.contains(value); } - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { - return pattern.contains(str); + @Fallback + public boolean onOther(VirtualFrame frame, Object other) { + return false; } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java index 5e64eabea..3cc0f6cf7 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java @@ -24,7 +24,6 @@ import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; import com.adacore.lkql_jit.built_ins.values.LKQLSelector; import com.adacore.lkql_jit.built_ins.values.lists.LKQLList; import com.adacore.lkql_jit.built_ins.values.lists.LKQLSelectorList; @@ -263,8 +262,8 @@ private boolean isAll( // Iterate on nodes Iterator iterator = selectorListValue.iterator(); while (iterator.hasNext()) { - LKQLDepthNode depthNode = (LKQLDepthNode) iterator.next(); - if (!pattern.executeNode(frame, depthNode.getNode())) return false; + Object value = iterator.next(); + if (!pattern.executeValue(frame, value)) return false; } // Return validation of all nodes @@ -284,8 +283,8 @@ private boolean isAny( // Iterate on nodes Iterator iterator = selectorListValue.iterator(); while (iterator.hasNext()) { - LKQLDepthNode depthNode = (LKQLDepthNode) iterator.next(); - if (pattern.executeNode(frame, depthNode.getNode())) return true; + Object val = iterator.next(); + if (pattern.executeValue(frame, val)) return true; } // Return false if no node verify the pattern @@ -303,19 +302,19 @@ private boolean isAny( private LKQLList getFilteredList( VirtualFrame frame, LKQLSelectorList selectorListValue, BasePattern pattern) { // Prepare the result - List resList = new ArrayList<>(); + List resList = new ArrayList<>(); // Iterate on nodes Iterator iterator = selectorListValue.iterator(); while (iterator.hasNext()) { - LKQLDepthNode depthNode = (LKQLDepthNode) iterator.next(); - if (pattern.executeNode(frame, depthNode.getNode())) { - resList.add(depthNode.getNode()); + Object value = iterator.next(); + if (pattern.executeValue(frame, value)) { + resList.add(value); } } // Return the result - return new LKQLList(resList.toArray(new Libadalang.AdaNode[0])); + return new LKQLList(resList.toArray(new Object[0])); } /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/UniversalPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/UniversalPattern.java index d8bf28560..098c01572 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/UniversalPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/UniversalPattern.java @@ -22,7 +22,6 @@ package com.adacore.lkql_jit.nodes.patterns; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -47,22 +46,10 @@ public UniversalPattern(SourceLocation location) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return true; - } - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeString(com.oracle.truffle.api.frame.VirtualFrame, - * String) - */ - @Override - public boolean executeString(VirtualFrame frame, String str) { + public boolean executeValue(VirtualFrame frame, Object value) { return true; } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java index 0314d8cfe..d6cf4563c 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java @@ -68,12 +68,10 @@ public ChainedNodePattern( // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { + public boolean executeValue(VirtualFrame frame, Object value) { throw LKQLRuntimeException.wrongPatternType("ChainedNodePattern", this); } @@ -85,7 +83,7 @@ public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { * @return The result of the chained pattern. */ public Libadalang.AdaNode[] executeChained(VirtualFrame frame, Libadalang.AdaNode node) { - if (this.nodePattern.executeNode(frame, node)) { + if (this.nodePattern.executeValue(frame, node)) { return this.executeLink(frame, 0, node); } else { return new Libadalang.AdaNode[0]; diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java index 6068b614b..4575158db 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java @@ -97,7 +97,7 @@ protected Libadalang.AdaNode[] doPatternFiltering(VirtualFrame frame, Object res // If the result object is a node if (LKQLTypeSystemGen.isAdaNode(resultObject)) { - if (this.pattern.executeNode(frame, LKQLTypeSystemGen.asAdaNode(resultObject))) { + if (this.pattern.executeValue(frame, LKQLTypeSystemGen.asAdaNode(resultObject))) { resList.add(LKQLTypeSystemGen.asAdaNode(resultObject)); } } @@ -108,7 +108,7 @@ else if (LKQLTypeSystemGen.isLKQLList(resultObject)) { for (int i = 0; i < listValue.size(); i++) { try { Libadalang.AdaNode toVerify = LKQLTypeSystemGen.expectAdaNode(listValue.get(i)); - if (this.pattern.executeNode(frame, toVerify)) { + if (this.pattern.executeValue(frame, toVerify)) { resList.add(toVerify); } } catch (UnexpectedResultException e) { diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailExpr.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailExpr.java index 4e09c9149..80b7d1d0d 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailExpr.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailExpr.java @@ -23,9 +23,13 @@ package com.adacore.lkql_jit.nodes.patterns.node_patterns; import com.adacore.lkql_jit.LKQLTypeSystemGen; +import com.adacore.lkql_jit.built_ins.values.interfaces.LKQLValue; import com.adacore.lkql_jit.nodes.expressions.Expr; import com.adacore.lkql_jit.utils.functions.ObjectUtils; import com.adacore.lkql_jit.utils.source_location.SourceLocation; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; @@ -34,7 +38,7 @@ * * @author Hugo GUERRIER */ -public final class DetailExpr extends DetailValue { +public abstract class DetailExpr extends DetailValue { // ----- Children ----- @@ -56,26 +60,32 @@ public DetailExpr(SourceLocation location, Expr expr) { this.expr = expr; } - // ----- Execution methods ----- + @Specialization(guards = {"other != null"}) + public boolean onLKQLValues( + VirtualFrame frame, + LKQLValue value, + @Cached("getExprAsLKQLValue(frame)") LKQLValue other) { + InteropLibrary valueLibrary = InteropLibrary.getUncached(value); + InteropLibrary expectedLibrary = InteropLibrary.getUncached(other); + return valueLibrary.isIdentical(value, other, expectedLibrary); + } - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.node_patterns.DetailValue#executeDetailValue(com.oracle.truffle.api.frame.VirtualFrame, - * java.lang.Object) - */ - @Override - public boolean executeDetailValue(VirtualFrame frame, Object value) { - // Execute the expression - Object expected = this.expr.executeGeneric(frame); + @Fallback + public boolean onLKQLValues( + VirtualFrame frame, Object value, @Cached("getExpr(frame)") Object other) { + return ObjectUtils.equals(value, other); + } + + public Object getExpr(VirtualFrame frame) { + return this.expr.executeGeneric(frame); + } - // Verify the equality - if (LKQLTypeSystemGen.isLKQLValue(value) && LKQLTypeSystemGen.isLKQLValue(expected)) { - InteropLibrary valueLibrary = InteropLibrary.getUncached(value); - InteropLibrary expectedLibrary = InteropLibrary.getUncached(expected); - return valueLibrary.isIdentical(value, expected, expectedLibrary); - } else { - return ObjectUtils.equals(value, expected); + public LKQLValue getExprAsLKQLValue(VirtualFrame frame) { + var val = this.expr.executeGeneric(frame); + if (LKQLTypeSystemGen.isLKQLValue(val)) { + return LKQLTypeSystemGen.asLKQLValue(val); } + return null; } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailPattern.java index ec006de9f..14fd62781 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailPattern.java @@ -22,10 +22,7 @@ package com.adacore.lkql_jit.nodes.patterns.node_patterns; -import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -34,7 +31,7 @@ * * @author Hugo GUERRIER */ -public final class DetailPattern extends DetailValue { +public class DetailPattern extends DetailValue { // ----- Children ----- @@ -56,37 +53,13 @@ public DetailPattern(SourceLocation location, BasePattern pattern) { this.pattern = pattern; } - // ----- Execution methods ----- - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.node_patterns.DetailValue#executeDetailValue(com.oracle.truffle.api.frame.VirtualFrame, - * java.lang.Object) - */ @Override - public boolean executeDetailValue(VirtualFrame frame, Object value) { - // Check if the value is a string - if (LKQLTypeSystemGen.isString(value)) { - return this.pattern.executeString(frame, LKQLTypeSystemGen.asString(value)); - } - - // Verify that the value is a node - if (!LKQLTypeSystemGen.isAdaNode(value)) { - throw LKQLRuntimeException.wrongType( - LKQLTypesHelper.ADA_NODE, LKQLTypesHelper.fromJava(value), this); - } - - // Execute the pattern with the node - return this.pattern.executeNode(frame, LKQLTypeSystemGen.asAdaNode(value)); + public String toString(int indentLevel) { + return this.nodeRepresentation(indentLevel); } - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ @Override - public String toString(int indentLevel) { - return this.nodeRepresentation(indentLevel); + public boolean executeDetailValue(VirtualFrame frame, Object value) { + return this.pattern.executeValue(frame, value); } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailValue.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailValue.java index 212f279ac..66b3fe408 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailValue.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/DetailValue.java @@ -50,7 +50,7 @@ protected DetailValue(SourceLocation location) { * com.adacore.lkql_jit.nodes.LKQLNode#executeGeneric(com.oracle.truffle.api.frame.VirtualFrame) */ @Override - public Object executeGeneric(VirtualFrame frame) { + public final Object executeGeneric(VirtualFrame frame) { throw LKQLRuntimeException.shouldNotExecute(this); } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/ExtendedNodePattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/ExtendedNodePattern.java index 939e0bb94..a7702879a 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/ExtendedNodePattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/ExtendedNodePattern.java @@ -22,8 +22,10 @@ package com.adacore.lkql_jit.nodes.patterns.node_patterns; -import com.adacore.libadalang.Libadalang; +import com.adacore.lkql_jit.LKQLTypeSystemGen; +import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.patterns.ValuePattern; +import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; @@ -63,21 +65,26 @@ public ExtendedNodePattern( // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see com.adacore.lkql_jit.nodes.patterns.BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { + public boolean executeValue(VirtualFrame frame, Object value) { // Test the base pattern - if (this.basePattern.executeNode(frame, node)) { - // Verify all details - for (NodePatternDetail detail : this.details) { - if (!detail.executeDetail(frame, node)) return false; - } + if (this.basePattern.executeValue(frame, value)) { + if (LKQLTypeSystemGen.isAdaNode(value)) { + var node = LKQLTypeSystemGen.asAdaNode(value); + + // Verify all details + for (NodePatternDetail detail : this.details) { + if (!detail.executeDetail(frame, node)) return false; + } - // Return the success - return true; + // Return the success + return true; + } else { + throw LKQLRuntimeException.wrongType( + LKQLTypesHelper.ADA_NODE, LKQLTypesHelper.fromJava(value), this); + } } // Return the failure diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/NodeKindPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/NodeKindPattern.java index 800aebf41..6b183064b 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/NodeKindPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/node_patterns/NodeKindPattern.java @@ -59,13 +59,11 @@ public NodeKindPattern(SourceLocation location, String kindName) { // ----- Execution methods ----- /** - * @see - * com.adacore.lkql_jit.nodes.patterns.BasePattern#executeNode(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) + * @see com.adacore.lkql_jit.nodes.patterns.BasePattern#executeValue(VirtualFrame, Object) */ @Override - public boolean executeNode(VirtualFrame frame, Libadalang.AdaNode node) { - return this.nodeClazz.isInstance(node) && node != LKQLNull.INSTANCE; + public boolean executeValue(VirtualFrame frame, Object value) { + return this.nodeClazz.isInstance(value) && value != LKQLNull.INSTANCE; } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java index 6a3a53251..6787956ce 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java @@ -22,7 +22,7 @@ package com.adacore.lkql_jit.nodes.root_nodes; -import com.adacore.lkql_jit.built_ins.values.LKQLDepthNode; +import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; import com.adacore.lkql_jit.built_ins.values.LKQLUnit; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; @@ -37,7 +37,7 @@ * @author Hugo GUERRIER */ public final class SelectorRootNode - extends MemoizedRootNode { + extends MemoizedRootNode { // ----- Attributes ----- @@ -96,16 +96,16 @@ public Object execute(VirtualFrame frame) { this.initFrame(frame); // Get the node and set it into the frame - LKQLDepthNode node = (LKQLDepthNode) frame.getArguments()[1]; + LKQLDepthValue value = (LKQLDepthValue) frame.getArguments()[1]; // Try memoization if (this.isMemoized) { - if (this.isMemoized(node)) return this.getMemoized(node); + if (this.isMemoized(value)) return this.getMemoized(value); } if (this.thisSlot > -1 && this.depthSlot > -1) { - FrameUtils.writeLocal(frame, this.thisSlot, node); - FrameUtils.writeLocal(frame, this.depthSlot, ((Integer) node.getDepth()).longValue()); + FrameUtils.writeLocal(frame, this.thisSlot, value.value); + FrameUtils.writeLocal(frame, this.depthSlot, ((Integer) value.depth).longValue()); } // Prepare the result @@ -113,7 +113,7 @@ public Object execute(VirtualFrame frame) { // Try to match an arm, if there is none, set the result to unit for (SelectorArm arm : this.arms) { - res = arm.executeArm(frame, node); + res = arm.executeArm(frame, value); if (res != null) break; } if (res == null) { @@ -122,7 +122,7 @@ public Object execute(VirtualFrame frame) { // Do the memoization cache addition if (this.isMemoized) { - this.putMemoized(node, res); + this.putMemoized(value, res); } // Return the result diff --git a/lkql_jit/lkql_cli/src/main/java/com/adacore/lkql_jit/LKQLLauncher.java b/lkql_jit/lkql_cli/src/main/java/com/adacore/lkql_jit/LKQLLauncher.java index 8704f422a..8d7586f5e 100644 --- a/lkql_jit/lkql_cli/src/main/java/com/adacore/lkql_jit/LKQLLauncher.java +++ b/lkql_jit/lkql_cli/src/main/java/com/adacore/lkql_jit/LKQLLauncher.java @@ -232,6 +232,8 @@ protected int executeScript(Context.Builder contextBuilder) { // Ignore } catch (EndOfFileException e) { return 12; + } catch (Exception e) { + System.err.println(e.getMessage()); } } } diff --git a/testsuite/tests/interop/selector_list/Main.java b/testsuite/tests/interop/selector_list/Main.java deleted file mode 100644 index 89df22bfb..000000000 --- a/testsuite/tests/interop/selector_list/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -import org.graalvm.polyglot.Context; -import org.graalvm.polyglot.Value; - -public class Main { - private static final String LKQL_SOURCE = - """ - val nodes = children(units()[1].root) - """; - - private static void print(String messageName, Object value) { - System.out.println(" " + messageName + ": " + value); - } - - public static void main(String[] args) { - Context context = Context.newBuilder("lkql") - .option("lkql.projectFile", "default_project/default.gpr") - .build(); - Value executable = context.parse("lkql", LKQL_SOURCE); - - Value namespace = executable.execute(false); - Value nodes = namespace.getMember("nodes"); - System.out.println("=== Selector list interop messages:"); - print("toString()", nodes.toString()); - print("hasArrayElements()", nodes.hasArrayElements()); - print("getArraySize()", nodes.getArraySize()); - print("isBoolean()", nodes.isBoolean()); - print("asBoolean()", nodes.asBoolean()); - print("getArrayElement(0)", nodes.getArrayElement(0)); - print("getArrayElement(1)", nodes.getArrayElement(1)); - print("getArrayElement(2)", nodes.getArrayElement(2)); - print("hasIterator()", nodes.hasIterator()); - } -} diff --git a/testsuite/tests/interop/selector_list/test.out b/testsuite/tests/interop/selector_list/test.out deleted file mode 100644 index e9eeb3f00..000000000 --- a/testsuite/tests/interop/selector_list/test.out +++ /dev/null @@ -1,10 +0,0 @@ -=== Selector list interop messages: - toString(): [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] - hasArrayElements(): true - getArraySize(): 57 - isBoolean(): true - asBoolean(): true - getArrayElement(0): - getArrayElement(1): - getArrayElement(2): - hasIterator(): true diff --git a/testsuite/tests/interop/selector_list/test.yaml b/testsuite/tests/interop/selector_list/test.yaml deleted file mode 100644 index 33f2e79ec..000000000 --- a/testsuite/tests/interop/selector_list/test.yaml +++ /dev/null @@ -1 +0,0 @@ -driver: java \ No newline at end of file From 311b472933ceef39394fc8ee5f681898a61b5c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Wed, 10 Jan 2024 12:04:50 +0100 Subject: [PATCH 03/16] Remove useless intermediate class UnfilteredPattern --- lkql/language/parser.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lkql/language/parser.py b/lkql/language/parser.py index 8d3ae8658..1ed3ed953 100644 --- a/lkql/language/parser.py +++ b/lkql/language/parser.py @@ -405,14 +405,6 @@ def value_part(): return No(ValuePattern) -@abstract -class UnfilteredPattern(BasePattern): - """ - Pattern without a filtering predicate. - """ - pass - - class FilteredPattern(BasePattern): """ Pattern with a filtering predicate, of the form: @@ -422,7 +414,7 @@ class FilteredPattern(BasePattern): o@ObjectDecl when o.children.length == 3 """ - pattern = Field(type=UnfilteredPattern) + pattern = Field(type=BasePattern) predicate = Field(type=Expr) @langkit_property() @@ -435,7 +427,7 @@ def value_part(): @abstract -class ValuePattern(UnfilteredPattern): +class ValuePattern(BasePattern): """ Root node class for patterns that filter values. (As opposed to patterns that only bind values to a given name without @@ -451,7 +443,7 @@ def value_part(): return Self -class BindingPattern(UnfilteredPattern): +class BindingPattern(BasePattern): """ Pattern comprising a binding name and a value pattern. From e3deb82722271317caebca061200ef041897a75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Tue, 9 Jan 2024 16:12:26 +0100 Subject: [PATCH 04/16] Remove chained node patterns They're not used anywhere in any real world checks, and we plan to replace them by another feature at a later stage. Closes #206 --- lkql/build/railroad-diagrams/pattern.svg | 14 +- lkql/language/parser.py | 82 +----- .../passes/FramingPass.java | 39 --- .../passes/TranslationPass.java | 88 ------ .../lkql_jit/nodes/expressions/Query.java | 31 +- .../lkql_jit/nodes/patterns/SelectorCall.java | 40 --- .../chained_patterns/ChainedNodePattern.java | 141 ---------- .../chained_patterns/ChainedPatternLink.java | 132 --------- .../patterns/chained_patterns/FieldLink.java | 113 -------- .../chained_patterns/PropertyLink.java | 130 --------- .../chained_patterns/SelectorLink.java | 81 ------ .../chained_query_dotted_name/script.lkql | 4 - .../chained_query_dotted_name/test.out | 1 - .../chained_query_dotted_name/test.yaml | 2 - .../chained_query_field/script.lkql | 6 - .../interpreter/chained_query_field/test.out | 4 - .../interpreter/chained_query_field/test.yaml | 2 - .../tests/parser/chained_query_pattern/input | 2 - .../parser/chained_query_pattern/test.out | 83 ------ .../parser/chained_query_pattern/test.yaml | 2 - .../parser/fun_with_type_annotations/input | 12 +- .../parser/fun_with_type_annotations/test.out | 266 +++++++++--------- user_manual/source/language_reference.rst | 53 ---- 23 files changed, 156 insertions(+), 1172 deletions(-) delete mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java delete mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java delete mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/FieldLink.java delete mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/PropertyLink.java delete mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/SelectorLink.java delete mode 100644 testsuite/tests/interpreter/chained_query_dotted_name/script.lkql delete mode 100644 testsuite/tests/interpreter/chained_query_dotted_name/test.out delete mode 100644 testsuite/tests/interpreter/chained_query_dotted_name/test.yaml delete mode 100644 testsuite/tests/interpreter/chained_query_field/script.lkql delete mode 100644 testsuite/tests/interpreter/chained_query_field/test.out delete mode 100644 testsuite/tests/interpreter/chained_query_field/test.yaml delete mode 100644 testsuite/tests/parser/chained_query_pattern/input delete mode 100644 testsuite/tests/parser/chained_query_pattern/test.out delete mode 100644 testsuite/tests/parser/chained_query_pattern/test.yaml diff --git a/lkql/build/railroad-diagrams/pattern.svg b/lkql/build/railroad-diagrams/pattern.svg index 31a54aff1..84651c033 100644 --- a/lkql/build/railroad-diagrams/pattern.svg +++ b/lkql/build/railroad-diagrams/pattern.svg @@ -1,4 +1,4 @@ - + pattern - - -chained_node_pattern -'or' -pattern -chained_node_pattern \ No newline at end of file + + +filtered_pattern +'or' +pattern +filtered_pattern \ No newline at end of file diff --git a/lkql/language/parser.py b/lkql/language/parser.py index 1ed3ed953..1bf134618 100644 --- a/lkql/language/parser.py +++ b/lkql/language/parser.py @@ -1014,52 +1014,6 @@ class ExtendedNodePattern(NodePattern): details = Field(type=NodePatternDetail.list) -@abstract -class ChainedPatternLink(LkqlNode): - """ - Element of a chained pattern of the form: - ``(selector|field|property) pattern`` - """ - pattern = AbstractField(type=BasePattern) - - -class SelectorLink(ChainedPatternLink): - """ - Element of a chained pattern of the form: - ``quantifier selector_name pattern`` - """ - selector = Field(type=SelectorCall) - pattern = Field(type=BasePattern) - - -class FieldLink(ChainedPatternLink): - """ - Element of a chained pattern of the form: - ``field pattern`` - """ - field = Field(type=Identifier) - pattern = Field(type=BasePattern) - - -class PropertyLink(ChainedPatternLink): - """ - Element of a chained pattern of the form: - ``property(args) pattern`` - """ - property = Field(type=FunCall) - pattern = Field(type=BasePattern) - - -class ChainedNodePattern(ValuePattern): - """ - Node pattern of the form:: - - ``Kind1(details...) selector1 Kind2(details...) selector2 ... KindN`` - """ - first_pattern = Field(type=BasePattern) - chain = Field(type=ChainedPatternLink.list) - - class MatchArm(LkqlNode): """ Represents one case of a 'match'. @@ -1127,38 +1081,16 @@ class Tuple(Expr): import_clause=Import("import", G.id), query=Query( - Opt( - "from", - Or(G.expr, Unpack("*", G.expr)) - ), - Opt( - "through", - Or(G.expr) - ), - "select", c(), Or( - QueryKind.alt_first(L.Identifier(match_text="first")), - QueryKind.alt_all(), - ), G.pattern + Opt("from", Or(G.expr, Unpack("*", G.expr))), + Opt("through", Or(G.expr)), + "select", c(), + Or(QueryKind.alt_first(L.Identifier(match_text="first")), + QueryKind.alt_all()), + G.pattern ), pattern=Or( - OrPattern( - G.chained_node_pattern, - "or", - G.pattern - ), - G.chained_node_pattern - ), - - chained_node_pattern=Or( - ChainedNodePattern( - G.filtered_pattern, - List(Or( - SelectorLink(G.selector_call, "is", G.filtered_pattern), - FieldLink(".", G.id, "is", G.filtered_pattern), - PropertyLink(".", G.fun_call, "is", G.filtered_pattern) - )) - ), + OrPattern(G.filtered_pattern, "or", G.pattern), G.filtered_pattern ), diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java index 1e5434fd0..55bef7d77 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java @@ -445,21 +445,6 @@ public Void visit(Liblkqllang.NodePatternSelector nodePatternSelector) { return null; } - /** - * Create the frame description for a selector link. - * - * @param selectorLink The Langkit selector link node. - * @return Nothing. - */ - @Override - public Void visit(Liblkqllang.SelectorLink selectorLink) { - selectorLink.fSelector().accept(this); - this.scriptFramesBuilder.openVirtualFrame(selectorLink); - selectorLink.fPattern().accept(this); - this.scriptFramesBuilder.closeFrame(); - return null; - } - // --- Non frame-changing nodes @Override @@ -942,30 +927,6 @@ public Void visit(Liblkqllang.ExtendedNodePattern extendedNodePattern) { return null; } - @Override - public Void visit(Liblkqllang.ChainedPatternLinkList chainedPatternLinkList) { - traverseChildren(chainedPatternLinkList); - return null; - } - - @Override - public Void visit(Liblkqllang.FieldLink fieldLink) { - traverseChildren(fieldLink); - return null; - } - - @Override - public Void visit(Liblkqllang.PropertyLink propertyLink) { - traverseChildren(propertyLink); - return null; - } - - @Override - public Void visit(Liblkqllang.ChainedNodePattern chainedNodePattern) { - traverseChildren(chainedNodePattern); - return null; - } - @Override public Void visit(Liblkqllang.MatchArmList matchArmList) { traverseChildren(matchArmList); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java index 3ab4be566..edb95ae77 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java @@ -53,7 +53,6 @@ import com.adacore.lkql_jit.nodes.expressions.operators.*; import com.adacore.lkql_jit.nodes.expressions.value_read.*; import com.adacore.lkql_jit.nodes.patterns.*; -import com.adacore.lkql_jit.nodes.patterns.chained_patterns.*; import com.adacore.lkql_jit.nodes.patterns.node_patterns.*; import com.adacore.lkql_jit.utils.ClosureDescriptor; import com.adacore.lkql_jit.utils.Constants; @@ -1671,93 +1670,6 @@ public LKQLNode visit(Liblkqllang.ExtendedNodePattern extendedNodePattern) { loc(extendedNodePattern), nodePattern, details.toArray(new NodePatternDetail[0])); } - // --- Chained node patterns - - /** - * Visit a selector link node. - * - * @param selectorLink The selector link node from Langkit. - * @return The selector link node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.SelectorLink selectorLink) { - // Translate the selector link selector - final SelectorCall selectorCall = (SelectorCall) selectorLink.fSelector().accept(this); - - // Enter the selector link frame - this.scriptFrames.enterFrame(selectorLink); - - // Translate the selector link pattern - final BasePattern pattern = (BasePattern) selectorLink.fPattern().accept(this); - - // Exit the selector link frame - this.scriptFrames.exitFrame(); - - // Return the new selector link node - return new SelectorLink(loc(selectorLink), pattern, selectorCall); - } - - /** - * Visit a field link node. - * - * @param fieldLink The field link node from Langkit. - * @return The field link node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.FieldLink fieldLink) { - // Translate the field link fields - final BasePattern pattern = (BasePattern) fieldLink.fPattern().accept(this); - final String fieldName = fieldLink.fField().getText(); - - // Return the new field link node - return FieldLinkNodeGen.create(loc(fieldLink), pattern, fieldName); - } - - /** - * Visit a property link node. - * - * @param propertyLink The property link node from Langkit. - * @return The property link node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.PropertyLink propertyLink) { - // Translate the property link fields - final BasePattern pattern = (BasePattern) propertyLink.fPattern().accept(this); - final String propertyName = propertyLink.fProperty().fName().getText(); - final ArgList argList = (ArgList) propertyLink.fProperty().fArguments().accept(this); - - // Return the new field link node - return PropertyLinkNodeGen.create(loc(propertyLink), pattern, propertyName, argList); - } - - @Override - public LKQLNode visit(Liblkqllang.ChainedPatternLinkList chainedPatternLinkList) { - return null; - } - - /** - * Visit a chained node pattern node. - * - * @param chainedNodePattern The chained node pattern node from Langkit. - * @return The chained node pattern node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.ChainedNodePattern chainedNodePattern) { - // Translate the chained node pattern fields - final BasePattern nodePattern = - (BasePattern) chainedNodePattern.fFirstPattern().accept(this); - - // Get the chained pattern link list - final List chain = new ArrayList<>(); - for (Liblkqllang.LkqlNode node : chainedNodePattern.fChain().children()) { - chain.add((ChainedPatternLink) node.accept(this)); - } - - // Return the new chained node pattern node - return new ChainedNodePattern( - loc(chainedNodePattern), nodePattern, chain.toArray(new ChainedPatternLink[0])); - } - // --- Pattern matching /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java index 90ae61132..86930bb43 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Query.java @@ -31,7 +31,6 @@ import com.adacore.lkql_jit.built_ins.values.lists.LKQLList; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.nodes.patterns.chained_patterns.ChainedNodePattern; import com.adacore.lkql_jit.utils.Iterator; import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.adacore.lkql_jit.utils.source_location.SourceLocation; @@ -206,19 +205,8 @@ private List exploreAll(VirtualFrame frame, Iterator nodeIte // Get the current node Libadalang.AdaNode adaNode = (Libadalang.AdaNode) nodeIterator.next(); - // If the pattern is a chained one - if (this.pattern instanceof ChainedNodePattern chainedNodePattern) { - Libadalang.AdaNode[] res = chainedNodePattern.executeChained(frame, adaNode); - if (res != null) { - for (Libadalang.AdaNode resNode : res) resList.add(resNode); - } - } - - // Else, the pattern is a basic one - else { - if (this.pattern.executeValue(frame, adaNode)) { - resList.add(adaNode); - } + if (this.pattern.executeValue(frame, adaNode)) { + resList.add(adaNode); } } @@ -239,19 +227,8 @@ private Libadalang.AdaNode exploreFirst(VirtualFrame frame, Iterator nodeIterato // Get the current node Libadalang.AdaNode adaNode = (Libadalang.AdaNode) nodeIterator.next(); - // If the pattern is a chained one - if (this.pattern instanceof ChainedNodePattern chainedNodePattern) { - Libadalang.AdaNode[] res = chainedNodePattern.executeChained(frame, adaNode); - if (res != null && res.length > 0) { - return res[0]; - } - } - - // Else, the pattern is a basic one - else { - if (this.pattern.executeValue(frame, adaNode)) { - return adaNode; - } + if (this.pattern.executeValue(frame, adaNode)) { + return adaNode; } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java index 3cc0f6cf7..d1ff31ded 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/SelectorCall.java @@ -136,46 +136,6 @@ public boolean executeVerification( return isValid; } - /** - * Execute the filtering logic on the selector call with the given pattern and return the result - * list value. TODO: Move this method and logic in the SelectorLink node. - * - * @param frame The frame to execute in. - * @param node The node to execute the selector on. - * @param pattern The pattern to perform the filtering logic. - * @return The list of the validating nodes. - */ - public LKQLList executeFiltering( - VirtualFrame frame, Libadalang.AdaNode node, BasePattern pattern) { - // Get the selector list - LKQLSelectorList selectorListValue = this.getSelectorList(frame, node); - - // Prepare the result - LKQLList res; - - // If the quantifier is all, verify it before returning anything - if (this.quantifier == Quantifier.ALL) { - if (this.isAll(frame, selectorListValue, pattern)) { - res = this.getFilteredList(frame, selectorListValue, pattern); - } else { - res = new LKQLList(new Libadalang.AdaNode[0]); - } - } - - // Else, just get the filtered list - else { - res = this.getFilteredList(frame, selectorListValue, pattern); - } - - // Do the bindings - if (this.bindingSlot > -1) { - this.doBinding(frame, res); - } - - // Return the result - return res; - } - // ----- Class methods ----- /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java deleted file mode 100644 index d6cf4563c..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedNodePattern.java +++ /dev/null @@ -1,141 +0,0 @@ -/*---------------------------------------------------------------------------- --- L K Q L J I T -- --- -- --- Copyright (C) 2022-2023, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- -- -----------------------------------------------------------------------------*/ - -package com.adacore.lkql_jit.nodes.patterns.chained_patterns; - -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.nodes.patterns.ValuePattern; -import com.adacore.lkql_jit.utils.functions.ListUtils; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.frame.VirtualFrame; -import java.util.ArrayList; -import java.util.List; - -/** - * This node represents a chained node pattern in the LKQL language. - * - * @author Hugo GUERRIER - */ -public final class ChainedNodePattern extends ValuePattern { - - // ----- Children ----- - - /** The node pattern start of the chain. */ - @Child - @SuppressWarnings("FieldMayBeFinal") - private BasePattern nodePattern; - - /** The chain for the node pattern. */ - @Children private final ChainedPatternLink[] chain; - - // ----- Constructors ----- - - /** - * Create a new chained node pattern with parameters. - * - * @param location The location of the node in the source. - * @param nodePattern The node pattern. - * @param chain The chain for the node pattern. - */ - public ChainedNodePattern( - SourceLocation location, BasePattern nodePattern, ChainedPatternLink[] chain) { - super(location); - this.nodePattern = nodePattern; - this.chain = chain; - } - - // ----- Execution methods ----- - - /** - * @see BasePattern#executeValue(VirtualFrame, Object) - */ - @Override - public boolean executeValue(VirtualFrame frame, Object value) { - throw LKQLRuntimeException.wrongPatternType("ChainedNodePattern", this); - } - - /** - * Get the result node from the chained pattern. - * - * @param frame The frame to execute in. - * @param node The node to verify. - * @return The result of the chained pattern. - */ - public Libadalang.AdaNode[] executeChained(VirtualFrame frame, Libadalang.AdaNode node) { - if (this.nodePattern.executeValue(frame, node)) { - return this.executeLink(frame, 0, node); - } else { - return new Libadalang.AdaNode[0]; - } - } - - // ----- Class methods ----- - - /** - * Execute the link of the chain at the given index with the given node. - * - * @param frame The frame to execute in. - * @param index The index of the link to execute. - * @param node The node to execute the link on. - * @return The array of the link execution result. - */ - private Libadalang.AdaNode[] executeLink( - VirtualFrame frame, int index, Libadalang.AdaNode node) { - // Get the result of the link execution - Libadalang.AdaNode[] linkRes = this.chain[index].executeLink(frame, node); - - // If the link is the last one return the result - if (index >= this.chain.length - 1) { - return linkRes; - } - - // Else, execute the next link on the results of the current link - else { - // Prepare the result list - List resList = new ArrayList<>(); - - // Add to the result with the already containing verification - for (Libadalang.AdaNode linkNode : linkRes) { - for (Libadalang.AdaNode toAdd : this.executeLink(frame, index + 1, linkNode)) { - if (!ListUtils.contains(resList, toAdd)) { - resList.add(toAdd); - } - } - } - - // Return the result - return resList.toArray(new Libadalang.AdaNode[0]); - } - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return this.nodeRepresentation(indentLevel); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java deleted file mode 100644 index 4575158db..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/ChainedPatternLink.java +++ /dev/null @@ -1,132 +0,0 @@ -/*---------------------------------------------------------------------------- --- L K Q L J I T -- --- -- --- Copyright (C) 2022-2023, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- -- -----------------------------------------------------------------------------*/ - -package com.adacore.lkql_jit.nodes.patterns.chained_patterns; - -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.built_ins.values.lists.LKQLList; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.nodes.LKQLNode; -import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.utils.LKQLTypesHelper; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.UnexpectedResultException; -import java.util.ArrayList; -import java.util.List; - -/** - * This node is the base of all chained pattern links in LKQL language. - * - * @author Hugo GUERRIER - */ -public abstract class ChainedPatternLink extends LKQLNode { - - // ----- Children ----- - - /** The pattern to match in the link. */ - @Child - @SuppressWarnings("FieldMayBeFinal") - protected BasePattern pattern; - - // ----- Constructors ----- - - /** - * Create a new chained pattern link. - * - * @param location The location of the node in the source. - * @param pattern The pattern to match. - */ - protected ChainedPatternLink(SourceLocation location, BasePattern pattern) { - super(location); - this.pattern = pattern; - } - - // ----- Execution methods ----- - - /** - * @see - * com.adacore.lkql_jit.nodes.LKQLNode#executeGeneric(com.oracle.truffle.api.frame.VirtualFrame) - */ - @Override - public final Object executeGeneric(VirtualFrame frame) { - throw LKQLRuntimeException.shouldNotExecute(this); - } - - /** - * Execute the link with a node and return the list of the matched node. - * - * @param frame The frame to execute the link in. - * @param node The input node in the chain. - * @return The result of the chain link execution. - */ - public abstract Libadalang.AdaNode[] executeLink(VirtualFrame frame, Libadalang.AdaNode node); - - // ----- Class methods ----- - - /** - * Do the pattern filtering logic on the given result object. - * - * @param frame The frame to execute the pattern in. - * @param resultObject The result object to filter and add in the result. - * @return The result of the filtering. - */ - protected Libadalang.AdaNode[] doPatternFiltering(VirtualFrame frame, Object resultObject) { - // Prepare the result list - List resList = new ArrayList<>(); - - // If the result object is a node - if (LKQLTypeSystemGen.isAdaNode(resultObject)) { - if (this.pattern.executeValue(frame, LKQLTypeSystemGen.asAdaNode(resultObject))) { - resList.add(LKQLTypeSystemGen.asAdaNode(resultObject)); - } - } - - // If the result object is a list of node - else if (LKQLTypeSystemGen.isLKQLList(resultObject)) { - LKQLList listValue = LKQLTypeSystemGen.asLKQLList(resultObject); - for (int i = 0; i < listValue.size(); i++) { - try { - Libadalang.AdaNode toVerify = LKQLTypeSystemGen.expectAdaNode(listValue.get(i)); - if (this.pattern.executeValue(frame, toVerify)) { - resList.add(toVerify); - } - } catch (UnexpectedResultException e) { - throw LKQLRuntimeException.wrongType( - LKQLTypesHelper.ADA_NODE, - LKQLTypesHelper.fromJava(e.getResult()), - this); - } - } - } - - // Else, throw a type exception - else { - throw LKQLRuntimeException.wrongType( - LKQLTypesHelper.LKQL_LIST, LKQLTypesHelper.fromJava(resultObject), this); - } - - // Return the result as an array of node - return resList.toArray(new Libadalang.AdaNode[0]); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/FieldLink.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/FieldLink.java deleted file mode 100644 index 81b8d5ed4..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/FieldLink.java +++ /dev/null @@ -1,113 +0,0 @@ -/*---------------------------------------------------------------------------- --- L K Q L J I T -- --- -- --- Copyright (C) 2022-2023, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- -- -----------------------------------------------------------------------------*/ - -package com.adacore.lkql_jit.nodes.patterns.chained_patterns; - -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.built_ins.values.LKQLProperty; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; - -/** - * This node represents a field link in a chained pattern in the LKQL language. - * - * @author Hugo GUERRIER - */ -public abstract class FieldLink extends ChainedPatternLink { - - // ----- Attributes ----- - - /** The name of the field to query. */ - protected final String fieldName; - - // ----- Constructors ----- - - /** - * Create a new field link node. - * - * @param location The location of the node in the source. - * @param pattern The pattern to verify. - * @param fieldName The name of the field to query. - */ - protected FieldLink(SourceLocation location, BasePattern pattern, String fieldName) { - super(location, pattern); - this.fieldName = fieldName; - } - - // ----- Execution methods ----- - - /** - * Execute the field link with the cached strategy. - * - * @param frame The frame to execute the link in. - * @param node The node get the field from. - * @param property The cached property reference. - * @return The result of the link. - */ - @Specialization(guards = {"node == property.getNode()", "property.getDescription() != null"}) - protected Libadalang.AdaNode[] fieldCached( - VirtualFrame frame, - @SuppressWarnings("unused") Libadalang.AdaNode node, - @Cached("create(fieldName, node)") LKQLProperty property) { - // Get the value of the field - Object value = property.executeAsField(this); - - // Do the pattern filtering - return this.doPatternFiltering(frame, value); - } - - /** - * Execute the field link with the un-cached strategy. - * - * @param frame The frame to execute the link in. - * @param node The node get the field from. - * @return The result of the link. - */ - @Specialization(replaces = "fieldCached") - protected Libadalang.AdaNode[] fieldUnached(VirtualFrame frame, Libadalang.AdaNode node) { - // Get the field method - LKQLProperty property = new LKQLProperty(this.fieldName, node); - - // Verify if the field method is null - if (property.getDescription() == null) { - throw LKQLRuntimeException.noSuchField(this); - } - - // Execute the field detail - return this.fieldCached(frame, node, property); - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return this.nodeRepresentation( - indentLevel, new String[] {"fieldName"}, new Object[] {this.fieldName}); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/PropertyLink.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/PropertyLink.java deleted file mode 100644 index 34be6a0cb..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/PropertyLink.java +++ /dev/null @@ -1,130 +0,0 @@ -/*---------------------------------------------------------------------------- --- L K Q L J I T -- --- -- --- Copyright (C) 2022-2023, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- -- -----------------------------------------------------------------------------*/ - -package com.adacore.lkql_jit.nodes.patterns.chained_patterns; - -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.built_ins.values.LKQLProperty; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.nodes.arguments.ArgList; -import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; - -/** - * This node represents a property link in a chained pattern in the LKQL language. - * - * @author Hugo GUERRIER - */ -public abstract class PropertyLink extends ChainedPatternLink { - - // ----- Attributes ----- - - /** The name of the property to call. */ - protected final String propertyName; - - // ----- Children ----- - - /** The list of the argument for the property call. */ - @Child - @SuppressWarnings("FieldMayBeFinal") - protected ArgList argList; - - // ----- Constructors ----- - - /** - * Create a new property link node. - * - * @param location The token location in the source. - * @param pattern The pattern to verify. - * @param propertyName The name of the property to call. - * @param argList The argument list. - */ - public PropertyLink( - SourceLocation location, BasePattern pattern, String propertyName, ArgList argList) { - super(location, pattern); - this.propertyName = propertyName; - this.argList = argList; - } - - // ----- Execution methods ----- - - /** - * Execute the property link with the cached property. - * - * @param frame The frame to execute the link in. - * @param node The node get the property from. - * @param property The cached property reference. - * @return The result of the link. - */ - @Specialization(guards = {"node == property.getNode()", "property.getDescription() != null"}) - protected Libadalang.AdaNode[] propertyCached( - VirtualFrame frame, - @SuppressWarnings("unused") Libadalang.AdaNode node, - @Cached("create(propertyName, node)") LKQLProperty property) { - // Evaluate the arguments - Object[] arguments = new Object[this.argList.getArgs().length]; - for (int i = 0; i < arguments.length; i++) { - arguments[i] = this.argList.getArgs()[i].getArgExpr().executeGeneric(frame); - } - - // Get the property result - Object value = property.executeAsProperty(this, this.argList, arguments); - - // Do the filtering - return this.doPatternFiltering(frame, value); - } - - /** - * Execute the property link with the un-cached path. - * - * @param frame The frame to execute the link in. - * @param node The node get the property from. - * @return The result of the link. - */ - @Specialization(replaces = "propertyCached") - protected Libadalang.AdaNode[] propertyUncached(VirtualFrame frame, Libadalang.AdaNode node) { - // Get the property methods - LKQLProperty property = new LKQLProperty(this.propertyName, node); - - // Test if the property is valid - if (property.getDescription() == null) { - throw LKQLRuntimeException.noSuchField(this); - } - - // Return the result - return this.propertyCached(frame, node, property); - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return this.nodeRepresentation( - indentLevel, new String[] {"propertyName"}, new Object[] {this.propertyName}); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/SelectorLink.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/SelectorLink.java deleted file mode 100644 index f3d2a4f02..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/chained_patterns/SelectorLink.java +++ /dev/null @@ -1,81 +0,0 @@ -/*---------------------------------------------------------------------------- --- L K Q L J I T -- --- -- --- Copyright (C) 2022-2023, AdaCore -- --- -- --- This library is free software; you can redistribute it and/or modify it -- --- under terms of the GNU General Public License as published by the Free -- --- Software Foundation; either version 3, or (at your option) any later -- --- version. This library is distributed in the hope that it will be useful, -- --- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- --- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- -- -----------------------------------------------------------------------------*/ - -package com.adacore.lkql_jit.nodes.patterns.chained_patterns; - -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.nodes.patterns.SelectorCall; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.frame.VirtualFrame; - -/** - * This node represents a selector in a chained pattern. - * - * @author Hugo GUERRIER - */ -public final class SelectorLink extends ChainedPatternLink { - - // ----- Children ----- - - /** The selector call to perform during link execution. */ - @Child - @SuppressWarnings("FieldMayBeFinal") - private SelectorCall selectorCall; - - // ----- Constructors ----- - - /** - * Create a new selector link node. - * - * @param location The location of the node in the source. - * @param pattern The pattern to verify. - * @param selectorCall The selector call. - */ - public SelectorLink(SourceLocation location, BasePattern pattern, SelectorCall selectorCall) { - super(location, pattern); - this.selectorCall = selectorCall; - } - - // ----- Execution methods ----- - - /** - * @see - * com.adacore.lkql_jit.nodes.patterns.chained_patterns.ChainedPatternLink#executeLink(com.oracle.truffle.api.frame.VirtualFrame, - * com.adacore.libadalang.Libadalang.AdaNode) - */ - @Override - public Libadalang.AdaNode[] executeLink(VirtualFrame frame, Libadalang.AdaNode node) { - return (Libadalang.AdaNode[]) - this.selectorCall.executeFiltering(frame, node, this.pattern).getContent(); - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return this.nodeRepresentation(indentLevel); - } -} diff --git a/testsuite/tests/interpreter/chained_query_dotted_name/script.lkql b/testsuite/tests/interpreter/chained_query_dotted_name/script.lkql deleted file mode 100644 index f9002201f..000000000 --- a/testsuite/tests/interpreter/chained_query_dotted_name/script.lkql +++ /dev/null @@ -1,4 +0,0 @@ -val inDottedInWith = - select a @ AspectSpec any children is DottedName - any children is Identifier -print(inDottedInWith) \ No newline at end of file diff --git a/testsuite/tests/interpreter/chained_query_dotted_name/test.out b/testsuite/tests/interpreter/chained_query_dotted_name/test.out deleted file mode 100644 index ddb2b340c..000000000 --- a/testsuite/tests/interpreter/chained_query_dotted_name/test.out +++ /dev/null @@ -1 +0,0 @@ -[, , ] diff --git a/testsuite/tests/interpreter/chained_query_dotted_name/test.yaml b/testsuite/tests/interpreter/chained_query_dotted_name/test.yaml deleted file mode 100644 index 0c46d8ed4..000000000 --- a/testsuite/tests/interpreter/chained_query_dotted_name/test.yaml +++ /dev/null @@ -1,2 +0,0 @@ -driver: 'interpreter' -project: 'aspect_decls/aspect_decls.gpr' diff --git a/testsuite/tests/interpreter/chained_query_field/script.lkql b/testsuite/tests/interpreter/chained_query_field/script.lkql deleted file mode 100644 index 438958f25..000000000 --- a/testsuite/tests/interpreter/chained_query_field/script.lkql +++ /dev/null @@ -1,6 +0,0 @@ -val inDottedInWith = - select t @ TypeDecl.children is d @ DefiningName when { - val x = print(t); - val y = print(d); - true - } diff --git a/testsuite/tests/interpreter/chained_query_field/test.out b/testsuite/tests/interpreter/chained_query_field/test.out deleted file mode 100644 index 0ba011217..000000000 --- a/testsuite/tests/interpreter/chained_query_field/test.out +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/testsuite/tests/interpreter/chained_query_field/test.yaml b/testsuite/tests/interpreter/chained_query_field/test.yaml deleted file mode 100644 index e787a4fa0..000000000 --- a/testsuite/tests/interpreter/chained_query_field/test.yaml +++ /dev/null @@ -1,2 +0,0 @@ -driver: 'interpreter' -project: 'access_decls/access_decls.gpr' diff --git a/testsuite/tests/parser/chained_query_pattern/input b/testsuite/tests/parser/chained_query_pattern/input deleted file mode 100644 index 6c366fd3b..000000000 --- a/testsuite/tests/parser/chained_query_pattern/input +++ /dev/null @@ -1,2 +0,0 @@ -select k @ KindOne.property() is KindTwo all sel is l @ KindThree.field is KindFour - when k.prop() and l.prop() diff --git a/testsuite/tests/parser/chained_query_pattern/test.out b/testsuite/tests/parser/chained_query_pattern/test.out deleted file mode 100644 index e1e7da8cb..000000000 --- a/testsuite/tests/parser/chained_query_pattern/test.out +++ /dev/null @@ -1,83 +0,0 @@ -Query -|f_from_expr: -|f_through_expr: -|f_query_kind: -| QueryKindAll -|f_pattern: -| ChainedNodePattern -| |f_first_pattern: -| | BindingPattern -| | |f_binding: -| | | Identifier: k -| | |f_value_pattern: -| | | NodeKindPattern -| | | |f_kind_name: -| | | | Identifier: KindOne -| |f_chain: -| | ChainedPatternLinkList -| | | PropertyLink -| | | |f_property: -| | | | FunCall -| | | | |f_name: -| | | | | Identifier: property -| | | | |f_has_safe: -| | | | | SafeAbsent -| | | | |f_arguments: -| | | | | ArgList: -| | | |f_pattern: -| | | | NodeKindPattern -| | | | |f_kind_name: -| | | | | Identifier: KindTwo -| | | SelectorLink -| | | |f_selector: -| | | | SelectorCall -| | | | |f_quantifier: -| | | | | Identifier: all -| | | | |f_binding: -| | | | |f_selector_call: -| | | | | Identifier: sel -| | | |f_pattern: -| | | | BindingPattern -| | | | |f_binding: -| | | | | Identifier: l -| | | | |f_value_pattern: -| | | | | NodeKindPattern -| | | | | |f_kind_name: -| | | | | | Identifier: KindThree -| | | FieldLink -| | | |f_field: -| | | | Identifier: field -| | | |f_pattern: -| | | | FilteredPattern -| | | | |f_pattern: -| | | | | NodeKindPattern -| | | | | |f_kind_name: -| | | | | | Identifier: KindFour -| | | | |f_predicate: -| | | | | BinOp -| | | | | |f_left: -| | | | | | FunCall -| | | | | | |f_name: -| | | | | | | DotAccess -| | | | | | | |f_receiver: -| | | | | | | | Identifier: k -| | | | | | | |f_member: -| | | | | | | | Identifier: prop -| | | | | | |f_has_safe: -| | | | | | | SafeAbsent -| | | | | | |f_arguments: -| | | | | | | ArgList: -| | | | | |f_op: -| | | | | | OpAnd -| | | | | |f_right: -| | | | | | FunCall -| | | | | | |f_name: -| | | | | | | DotAccess -| | | | | | | |f_receiver: -| | | | | | | | Identifier: l -| | | | | | | |f_member: -| | | | | | | | Identifier: prop -| | | | | | |f_has_safe: -| | | | | | | SafeAbsent -| | | | | | |f_arguments: -| | | | | | | ArgList: diff --git a/testsuite/tests/parser/chained_query_pattern/test.yaml b/testsuite/tests/parser/chained_query_pattern/test.yaml deleted file mode 100644 index 563a6a37f..000000000 --- a/testsuite/tests/parser/chained_query_pattern/test.yaml +++ /dev/null @@ -1,2 +0,0 @@ -driver: parser -rule: expr diff --git a/testsuite/tests/parser/fun_with_type_annotations/input b/testsuite/tests/parser/fun_with_type_annotations/input index cb012e575..545776006 100644 --- a/testsuite/tests/parser/fun_with_type_annotations/input +++ b/testsuite/tests/parser/fun_with_type_annotations/input @@ -2,10 +2,10 @@ fun too_many_dependencies(max_deps : int) = select CompilationUnit( - any c @ children is Identifier(any parent(depth=2) is WithClause) + any c @ children is Identifier(any parent(depth=2) is WithClause), + f_body is l @ LibraryItem when { + val semanticParent = l.f_item?.p_semantic_parent(); + val deps = [x for x in c if x.p_referenced_decl() != semanticParent]; + deps.length > max_deps + } ) - .f_body is l @ LibraryItem when { - val semanticParent = l.f_item?.p_semantic_parent(); - val deps = [x for x in c if x.p_referenced_decl() != semanticParent]; - deps.length > max_deps - } diff --git a/testsuite/tests/parser/fun_with_type_annotations/test.out b/testsuite/tests/parser/fun_with_type_annotations/test.out index 05fe6f8ea..133c0a084 100644 --- a/testsuite/tests/parser/fun_with_type_annotations/test.out +++ b/testsuite/tests/parser/fun_with_type_annotations/test.out @@ -26,142 +26,140 @@ FunDecl | | |f_query_kind: | | | QueryKindAll | | |f_pattern: -| | | ChainedNodePattern -| | | |f_first_pattern: -| | | | ExtendedNodePattern -| | | | |f_node_pattern: -| | | | | NodeKindPattern -| | | | | |f_kind_name: -| | | | | | Identifier: CompilationUnit -| | | | |f_details: -| | | | | NodePatternDetailList -| | | | | | NodePatternSelector -| | | | | | |f_call: -| | | | | | | SelectorCall -| | | | | | | |f_quantifier: -| | | | | | | | Identifier: any -| | | | | | | |f_binding: -| | | | | | | | Identifier: c -| | | | | | | |f_selector_call: -| | | | | | | | Identifier: children -| | | | | | |f_pattern: -| | | | | | | ExtendedNodePattern -| | | | | | | |f_node_pattern: -| | | | | | | | NodeKindPattern -| | | | | | | | |f_kind_name: -| | | | | | | | | Identifier: Identifier -| | | | | | | |f_details: -| | | | | | | | NodePatternDetailList -| | | | | | | | | NodePatternSelector -| | | | | | | | | |f_call: -| | | | | | | | | | SelectorCall -| | | | | | | | | | |f_quantifier: -| | | | | | | | | | | Identifier: any -| | | | | | | | | | |f_binding: -| | | | | | | | | | |f_selector_call: -| | | | | | | | | | | FunCall -| | | | | | | | | | | |f_name: -| | | | | | | | | | | | Identifier: parent -| | | | | | | | | | | |f_has_safe: -| | | | | | | | | | | | SafeAbsent -| | | | | | | | | | | |f_arguments: -| | | | | | | | | | | | ArgList -| | | | | | | | | | | | | NamedArg -| | | | | | | | | | | | | |f_arg_name: -| | | | | | | | | | | | | | Identifier: depth -| | | | | | | | | | | | | |f_value_expr: -| | | | | | | | | | | | | | IntegerLiteral: 2 -| | | | | | | | | |f_pattern: -| | | | | | | | | | NodeKindPattern -| | | | | | | | | | |f_kind_name: -| | | | | | | | | | | Identifier: WithClause -| | | |f_chain: -| | | | ChainedPatternLinkList -| | | | | FieldLink -| | | | | |f_field: -| | | | | | Identifier: f_body +| | | ExtendedNodePattern +| | | |f_node_pattern: +| | | | NodeKindPattern +| | | | |f_kind_name: +| | | | | Identifier: CompilationUnit +| | | |f_details: +| | | | NodePatternDetailList +| | | | | NodePatternSelector +| | | | | |f_call: +| | | | | | SelectorCall +| | | | | | |f_quantifier: +| | | | | | | Identifier: any +| | | | | | |f_binding: +| | | | | | | Identifier: c +| | | | | | |f_selector_call: +| | | | | | | Identifier: children | | | | | |f_pattern: -| | | | | | FilteredPattern -| | | | | | |f_pattern: -| | | | | | | BindingPattern -| | | | | | | |f_binding: -| | | | | | | | Identifier: l -| | | | | | | |f_value_pattern: -| | | | | | | | NodeKindPattern -| | | | | | | | |f_kind_name: -| | | | | | | | | Identifier: LibraryItem -| | | | | | |f_predicate: -| | | | | | | BlockExpr -| | | | | | | |f_body: -| | | | | | | | BlockBodyList -| | | | | | | | | BlockBodyDecl -| | | | | | | | | |f_decl: -| | | | | | | | | | ValDecl -| | | | | | | | | | |f_annotation: -| | | | | | | | | | |f_doc_node: -| | | | | | | | | | |f_identifier: -| | | | | | | | | | | Identifier: semanticParent -| | | | | | | | | | |f_value: -| | | | | | | | | | | FunCall -| | | | | | | | | | | |f_name: -| | | | | | | | | | | | SafeAccess -| | | | | | | | | | | | |f_receiver: -| | | | | | | | | | | | | DotAccess +| | | | | | ExtendedNodePattern +| | | | | | |f_node_pattern: +| | | | | | | NodeKindPattern +| | | | | | | |f_kind_name: +| | | | | | | | Identifier: Identifier +| | | | | | |f_details: +| | | | | | | NodePatternDetailList +| | | | | | | | NodePatternSelector +| | | | | | | | |f_call: +| | | | | | | | | SelectorCall +| | | | | | | | | |f_quantifier: +| | | | | | | | | | Identifier: any +| | | | | | | | | |f_binding: +| | | | | | | | | |f_selector_call: +| | | | | | | | | | FunCall +| | | | | | | | | | |f_name: +| | | | | | | | | | | Identifier: parent +| | | | | | | | | | |f_has_safe: +| | | | | | | | | | | SafeAbsent +| | | | | | | | | | |f_arguments: +| | | | | | | | | | | ArgList +| | | | | | | | | | | | NamedArg +| | | | | | | | | | | | |f_arg_name: +| | | | | | | | | | | | | Identifier: depth +| | | | | | | | | | | | |f_value_expr: +| | | | | | | | | | | | | IntegerLiteral: 2 +| | | | | | | | |f_pattern: +| | | | | | | | | NodeKindPattern +| | | | | | | | | |f_kind_name: +| | | | | | | | | | Identifier: WithClause +| | | | | NodePatternField +| | | | | |f_identifier: +| | | | | | Identifier: f_body +| | | | | |f_expected_value: +| | | | | | DetailPattern +| | | | | | |f_pattern_value: +| | | | | | | FilteredPattern +| | | | | | | |f_pattern: +| | | | | | | | BindingPattern +| | | | | | | | |f_binding: +| | | | | | | | | Identifier: l +| | | | | | | | |f_value_pattern: +| | | | | | | | | NodeKindPattern +| | | | | | | | | |f_kind_name: +| | | | | | | | | | Identifier: LibraryItem +| | | | | | | |f_predicate: +| | | | | | | | BlockExpr +| | | | | | | | |f_body: +| | | | | | | | | BlockBodyList +| | | | | | | | | | BlockBodyDecl +| | | | | | | | | | |f_decl: +| | | | | | | | | | | ValDecl +| | | | | | | | | | | |f_annotation: +| | | | | | | | | | | |f_doc_node: +| | | | | | | | | | | |f_identifier: +| | | | | | | | | | | | Identifier: semanticParent +| | | | | | | | | | | |f_value: +| | | | | | | | | | | | FunCall +| | | | | | | | | | | | |f_name: +| | | | | | | | | | | | | SafeAccess | | | | | | | | | | | | | |f_receiver: -| | | | | | | | | | | | | | Identifier: l -| | | | | | | | | | | | | |f_member: -| | | | | | | | | | | | | | Identifier: f_item -| | | | | | | | | | | | |f_member: -| | | | | | | | | | | | | Identifier: p_semantic_parent -| | | | | | | | | | | |f_has_safe: -| | | | | | | | | | | | SafeAbsent -| | | | | | | | | | | |f_arguments: -| | | | | | | | | | | | ArgList: -| | | | | | | | | BlockBodyDecl -| | | | | | | | | |f_decl: -| | | | | | | | | | ValDecl -| | | | | | | | | | |f_annotation: -| | | | | | | | | | |f_doc_node: -| | | | | | | | | | |f_identifier: -| | | | | | | | | | | Identifier: deps -| | | | | | | | | | |f_value: -| | | | | | | | | | | ListComprehension -| | | | | | | | | | | |f_expr: -| | | | | | | | | | | | Identifier: x -| | | | | | | | | | | |f_generators: -| | | | | | | | | | | | ListCompAssocList -| | | | | | | | | | | | | ListCompAssoc -| | | | | | | | | | | | | |f_binding_name: -| | | | | | | | | | | | | | Identifier: x -| | | | | | | | | | | | | |f_coll_expr: -| | | | | | | | | | | | | | Identifier: c -| | | | | | | | | | | |f_guard: -| | | | | | | | | | | | RelBinOp -| | | | | | | | | | | | |f_left: -| | | | | | | | | | | | | FunCall -| | | | | | | | | | | | | |f_name: | | | | | | | | | | | | | | DotAccess | | | | | | | | | | | | | | |f_receiver: -| | | | | | | | | | | | | | | Identifier: x +| | | | | | | | | | | | | | | Identifier: l | | | | | | | | | | | | | | |f_member: -| | | | | | | | | | | | | | | Identifier: p_referenced_decl -| | | | | | | | | | | | | |f_has_safe: -| | | | | | | | | | | | | | SafeAbsent -| | | | | | | | | | | | | |f_arguments: -| | | | | | | | | | | | | | ArgList: -| | | | | | | | | | | | |f_op: -| | | | | | | | | | | | | OpNeq -| | | | | | | | | | | | |f_right: -| | | | | | | | | | | | | Identifier: semanticParent -| | | | | | | |f_expr: -| | | | | | | | RelBinOp -| | | | | | | | |f_left: -| | | | | | | | | DotAccess -| | | | | | | | | |f_receiver: -| | | | | | | | | | Identifier: deps -| | | | | | | | | |f_member: -| | | | | | | | | | Identifier: length -| | | | | | | | |f_op: -| | | | | | | | | OpGt -| | | | | | | | |f_right: -| | | | | | | | | Identifier: max_deps +| | | | | | | | | | | | | | | Identifier: f_item +| | | | | | | | | | | | | |f_member: +| | | | | | | | | | | | | | Identifier: p_semantic_parent +| | | | | | | | | | | | |f_has_safe: +| | | | | | | | | | | | | SafeAbsent +| | | | | | | | | | | | |f_arguments: +| | | | | | | | | | | | | ArgList: +| | | | | | | | | | BlockBodyDecl +| | | | | | | | | | |f_decl: +| | | | | | | | | | | ValDecl +| | | | | | | | | | | |f_annotation: +| | | | | | | | | | | |f_doc_node: +| | | | | | | | | | | |f_identifier: +| | | | | | | | | | | | Identifier: deps +| | | | | | | | | | | |f_value: +| | | | | | | | | | | | ListComprehension +| | | | | | | | | | | | |f_expr: +| | | | | | | | | | | | | Identifier: x +| | | | | | | | | | | | |f_generators: +| | | | | | | | | | | | | ListCompAssocList +| | | | | | | | | | | | | | ListCompAssoc +| | | | | | | | | | | | | | |f_binding_name: +| | | | | | | | | | | | | | | Identifier: x +| | | | | | | | | | | | | | |f_coll_expr: +| | | | | | | | | | | | | | | Identifier: c +| | | | | | | | | | | | |f_guard: +| | | | | | | | | | | | | RelBinOp +| | | | | | | | | | | | | |f_left: +| | | | | | | | | | | | | | FunCall +| | | | | | | | | | | | | | |f_name: +| | | | | | | | | | | | | | | DotAccess +| | | | | | | | | | | | | | | |f_receiver: +| | | | | | | | | | | | | | | | Identifier: x +| | | | | | | | | | | | | | | |f_member: +| | | | | | | | | | | | | | | | Identifier: p_referenced_decl +| | | | | | | | | | | | | | |f_has_safe: +| | | | | | | | | | | | | | | SafeAbsent +| | | | | | | | | | | | | | |f_arguments: +| | | | | | | | | | | | | | | ArgList: +| | | | | | | | | | | | | |f_op: +| | | | | | | | | | | | | | OpNeq +| | | | | | | | | | | | | |f_right: +| | | | | | | | | | | | | | Identifier: semanticParent +| | | | | | | | |f_expr: +| | | | | | | | | RelBinOp +| | | | | | | | | |f_left: +| | | | | | | | | | DotAccess +| | | | | | | | | | |f_receiver: +| | | | | | | | | | | Identifier: deps +| | | | | | | | | | |f_member: +| | | | | | | | | | | Identifier: length +| | | | | | | | | |f_op: +| | | | | | | | | | OpGt +| | | | | | | | | |f_right: +| | | | | | | | | | Identifier: max_deps diff --git a/user_manual/source/language_reference.rst b/user_manual/source/language_reference.rst index 0226a5ca0..0370a7153 100644 --- a/user_manual/source/language_reference.rst +++ b/user_manual/source/language_reference.rst @@ -797,7 +797,6 @@ keyword. Pattern ------- -.. lkql_doc_class:: UnfilteredPattern .. lkql_doc_class:: ValuePattern .. raw:: html @@ -927,58 +926,6 @@ this is denoted by the parentheses after the property name. select BaseId(p_referenced_decl() is ObjectDecl) -Chained Sub Patterns -^^^^^^^^^^^^^^^^^^^^ - -.. lkql_doc_class:: ChainedPatternLink -.. lkql_doc_class:: SelectorCall - -Chained sub patterns are roughly similar to nested sub patterns, and come in -similar flavours. The big difference between the two kind of patterns, is which -nodes are yielded when the pattern is used in a query. Chained patterns will -yield the sub-nodes, rather than just filtering and returning the top level -node. - -You have the three different kind of chained patterns, corresponding to the -nested ones. - -Selector Chain -"""""""""""""" - -A selector chain is a sub-pattern that allows you to recursively yield a -sub-query via a selector call: - -.. code-block:: lkql - - select Body any children is ForLoopStmt - -The quantifier part (``any``) can be either ``any`` or ``all``, which will -alter how the sub-pattern matches: - -Field Chain -""""""""""" - -A field chain is a sub-pattern that allows you to yield a specific field in the -parent object, given that it satisfies a pattern. - -.. code-block:: lkql - - select ObjectDecl.f_default_expr is IntLiteral - -This will yield the default exprssions for object decls, given that those -default expressions are int literals. - -Property Chain -"""""""""""""" - -A property chain is very similar to a field chain, except that a property of -the node is called, instead of a field accessed. Syntactically, this is denoted -by the parentheses after the property name. - -.. code-block:: lkql - - select BaseId.p_referenced_decl() is ObjectDecl - Filtered Patterns and Binding Patterns ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From e1e2b24ab7be01e18693fc4fcc0658ec0a683121 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Wed, 10 Jan 2024 12:24:45 +0100 Subject: [PATCH 05/16] Remove useless properties on patterns --- lkql/language/parser.py | 45 ++--------------------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) diff --git a/lkql/language/parser.py b/lkql/language/parser.py index 1bf134618..26ef0b14f 100644 --- a/lkql/language/parser.py +++ b/lkql/language/parser.py @@ -380,29 +380,7 @@ class BasePattern(LkqlNode): """ Root node class for patterns. """ - - @langkit_property(return_type=T.Identifier, public=True, - kind=AbstractKind.abstract) - def binding_name(): - """ - Return the pattern's binding name. - Return an empty String if the pattern doesn't contain a binding name. - """ - pass - - @langkit_property(return_type=T.Bool, public=True) - def has_binding(): - """ - Return whether the node pattern contains a binding name. - """ - return dsl_expr.Not(Self.binding_name.is_null) - - @langkit_property(return_type=T.ValuePattern, public=True) - def value_part(): - """ - Return the value pattern contained in the pattern , if any. - """ - return No(ValuePattern) + pass class FilteredPattern(BasePattern): @@ -417,14 +395,6 @@ class FilteredPattern(BasePattern): pattern = Field(type=BasePattern) predicate = Field(type=Expr) - @langkit_property() - def binding_name(): - return Self.pattern.binding_name - - @langkit_property() - def value_part(): - return Self.pattern.value_part() - @abstract class ValuePattern(BasePattern): @@ -433,14 +403,7 @@ class ValuePattern(BasePattern): (As opposed to patterns that only bind values to a given name without doing any kind of filtering) """ - - @langkit_property() - def binding_name(): - return dsl_expr.No(T.Identifier) - - @langkit_property() - def value_part(): - return Self + pass class BindingPattern(BasePattern): @@ -455,10 +418,6 @@ class BindingPattern(BasePattern): binding = Field(type=Identifier) value_pattern = Field(type=ValuePattern) - @langkit_property() - def binding_name(): - return Self.binding - class IsClause(Expr): """ From fc02cd6959c1aa6edc379b9611c5fdb9da8b195e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20AMIARD?= Date: Wed, 10 Jan 2024 12:45:14 +0100 Subject: [PATCH 06/16] Implement bool patterns --- .../build/railroad-diagrams/value_pattern.svg | 14 +++-- lkql/language/parser.py | 10 ++++ .../passes/FramingPass.java | 10 ++++ .../passes/TranslationPass.java | 10 ++++ .../lkql_jit/nodes/patterns/BoolPattern.java | 55 +++++++++++++++++++ .../interpreter/bool_pattern/script.lkql | 9 +++ .../tests/interpreter/bool_pattern/test.out | 3 + .../tests/interpreter/bool_pattern/test.yaml | 2 + 8 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BoolPattern.java create mode 100644 testsuite/tests/interpreter/bool_pattern/script.lkql create mode 100644 testsuite/tests/interpreter/bool_pattern/test.out create mode 100644 testsuite/tests/interpreter/bool_pattern/test.yaml diff --git a/lkql/build/railroad-diagrams/value_pattern.svg b/lkql/build/railroad-diagrams/value_pattern.svg index 12ea894a2..b355b7426 100644 --- a/lkql/build/railroad-diagrams/value_pattern.svg +++ b/lkql/build/railroad-diagrams/value_pattern.svg @@ -1,4 +1,4 @@ - + +bool_pattern + + +'true' + +'false' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/integer_pattern.svg b/lkql/build/railroad-diagrams/integer_pattern.svg new file mode 100644 index 000000000..ac7b0084a --- /dev/null +++ b/lkql/build/railroad-diagrams/integer_pattern.svg @@ -0,0 +1,37 @@ + + + +integer_pattern + +Integer \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/list_pattern.svg b/lkql/build/railroad-diagrams/list_pattern.svg new file mode 100644 index 000000000..39f416053 --- /dev/null +++ b/lkql/build/railroad-diagrams/list_pattern.svg @@ -0,0 +1,43 @@ + + + +list_pattern + +'[' + + +binding_pattern +splat_pattern +',' +']' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/object_pattern.svg b/lkql/build/railroad-diagrams/object_pattern.svg new file mode 100644 index 000000000..20250476b --- /dev/null +++ b/lkql/build/railroad-diagrams/object_pattern.svg @@ -0,0 +1,43 @@ + + + +object_pattern + +'{' + + +object_pattern_assoc +splat_pattern +',' +'}' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/object_pattern_assoc.svg b/lkql/build/railroad-diagrams/object_pattern_assoc.svg new file mode 100644 index 000000000..18b45e477 --- /dev/null +++ b/lkql/build/railroad-diagrams/object_pattern_assoc.svg @@ -0,0 +1,39 @@ + + + +object_pattern_assoc + +id +':' +pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/regex_pattern.svg b/lkql/build/railroad-diagrams/regex_pattern.svg new file mode 100644 index 000000000..badab289a --- /dev/null +++ b/lkql/build/railroad-diagrams/regex_pattern.svg @@ -0,0 +1,37 @@ + + + +regex_pattern + +String \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/splat_pattern.svg b/lkql/build/railroad-diagrams/splat_pattern.svg new file mode 100644 index 000000000..10e8bb04e --- /dev/null +++ b/lkql/build/railroad-diagrams/splat_pattern.svg @@ -0,0 +1,42 @@ + + + +splat_pattern + + + + +id +'@' +'...' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/tuple_pattern.svg b/lkql/build/railroad-diagrams/tuple_pattern.svg new file mode 100644 index 000000000..5a5183f9f --- /dev/null +++ b/lkql/build/railroad-diagrams/tuple_pattern.svg @@ -0,0 +1,41 @@ + + + +tuple_pattern + +'(' + +binding_pattern +',' +')' \ No newline at end of file