diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IAbsOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAbsOperandNode.java index 52f70a033..f6979b0b8 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IAbsOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAbsOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface IAbsOperandNode extends IOperandNode -{ - IOperandNode parameter(); // TODO: (type-check) -} +public interface IAbsOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IAtnOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAtnOperandNode.java new file mode 100644 index 000000000..edd6a4f41 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAtnOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface IAtnOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IAverOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAverOperandNode.java new file mode 100644 index 000000000..b7306b30f --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IAverOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface IAverOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ICosOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ICosOperandNode.java new file mode 100644 index 000000000..61ced9f44 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ICosOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface ICosOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ICountOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ICountOperandNode.java index 9f4665951..f05da0f49 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/ICountOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ICountOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface ICountOperandNode extends IOperandNode -{ - IVariableReferenceNode variable(); -} +public interface ICountOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IDataType.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IDataType.java index 15cde33d4..c21abf148 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IDataType.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IDataType.java @@ -16,6 +16,16 @@ public interface IDataType boolean hasDynamicLength(); + default boolean isNumericFamily() + { + return format() == NUMERIC || format() == PACKED || format() == FLOAT || format() == INTEGER; + } + + default boolean isAlphaNumericFamily() + { + return format() == ALPHANUMERIC || format() == UNICODE || format() == BINARY; + } + /** * Determines if this type fits into the given type. Implicit conversion is taken into account.
* This does not compare by byte size diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IExpOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IExpOperandNode.java new file mode 100644 index 000000000..819ec1506 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IExpOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface IExpOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IFracOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IFracOperandNode.java index 9c154ba88..825aca735 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IFracOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IFracOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface IFracOperandNode extends IOperandNode -{ - IOperandNode parameter(); // TODO: (type-check) -} +public interface IFracOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IIntOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IIntOperandNode.java index 538993b8a..4986436fc 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IIntOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IIntOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface IIntOperandNode extends IOperandNode -{ - IVariableReferenceNode variable(); // TODO: (type-check) -} +public interface IIntOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ILogOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ILogOperandNode.java index a27491c03..69d249a41 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/ILogOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ILogOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface ILogOperandNode extends IOperandNode -{ - IOperandNode parameter(); -} +public interface ILogOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IMathFunctionOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMathFunctionOperandNode.java new file mode 100644 index 000000000..a9e01ef7a --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMathFunctionOperandNode.java @@ -0,0 +1,6 @@ +package org.amshove.natparse.natural; + +public interface IMathFunctionOperandNode extends IOperandNode +{ + IOperandNode parameter(); +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IMaxOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMaxOperandNode.java new file mode 100644 index 000000000..cc8e0842d --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMaxOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface IMaxOperandNode extends IProcessingLoopFunctionNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IMinOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMinOperandNode.java new file mode 100644 index 000000000..ca9a71e44 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IMinOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface IMinOperandNode extends IProcessingLoopFunctionNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IOldOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IOldOperandNode.java index aa16ebf99..e59ec796e 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IOldOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IOldOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface IOldOperandNode extends IOperandNode -{ - IOperandNode operand(); -} +public interface IOldOperandNode extends IProcessingLoopFunctionNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IPosNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IPosOperandNode.java similarity index 60% rename from libs/natparse/src/main/java/org/amshove/natparse/natural/IPosNode.java rename to libs/natparse/src/main/java/org/amshove/natparse/natural/IPosOperandNode.java index 2a718c874..ac453acbf 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IPosNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IPosOperandNode.java @@ -1,6 +1,6 @@ package org.amshove.natparse.natural; -public interface IPosNode extends IOperandNode +public interface IPosOperandNode extends IOperandNode { IVariableReferenceNode positionOf(); } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IProcessingLoopFunctionNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IProcessingLoopFunctionNode.java new file mode 100644 index 000000000..4c02c080f --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IProcessingLoopFunctionNode.java @@ -0,0 +1,6 @@ +package org.amshove.natparse.natural; + +public interface IProcessingLoopFunctionNode extends IOperandNode +{ + IOperandNode parameter(); +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISignOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISignOperandNode.java index 04142b771..f479b033b 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISignOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISignOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; public interface ISignOperandNode extends IOperandNode -{ - IOperandNode parameter(); // TODO: (type-check) -} +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISinOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISinOperandNode.java new file mode 100644 index 000000000..69aa9030a --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISinOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface ISinOperandNode extends IOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISortKeyOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISortKeyOperandNode.java new file mode 100644 index 000000000..89ae2b81e --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISortKeyOperandNode.java @@ -0,0 +1,6 @@ +package org.amshove.natparse.natural; + +public interface ISortKeyOperandNode extends IOperandNode +{ + IVariableReferenceNode variable(); +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISqrtOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISqrtOperandNode.java new file mode 100644 index 000000000..7599fd4a0 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISqrtOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface ISqrtOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISumOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISumOperandNode.java index 5768380b8..a193c8981 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/ISumOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ISumOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface ISumOperandNode extends IOperandNode -{ - IVariableReferenceNode variable(); // TODO (type-check) -} +public interface ISumOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ITanOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ITanOperandNode.java new file mode 100644 index 000000000..00567f1cf --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ITanOperandNode.java @@ -0,0 +1,4 @@ +package org.amshove.natparse.natural; + +public interface ITanOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/ITotalOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/ITotalOperandNode.java index ef39bd9b3..67bfa1c99 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/ITotalOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/ITotalOperandNode.java @@ -1,6 +1,4 @@ package org.amshove.natparse.natural; -public interface ITotalOperandNode extends IOperandNode -{ - IVariableReferenceNode variable(); -} +public interface ITotalOperandNode extends IMathFunctionOperandNode +{} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/natural/IValOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/natural/IValOperandNode.java index ea1bd02e9..a7d786fb8 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/natural/IValOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/natural/IValOperandNode.java @@ -2,5 +2,5 @@ public interface IValOperandNode extends IOperandNode { - IOperandNode operand(); // TODO (type-check) + IOperandNode parameter(); } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbsOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbsOperandNode.java index e5c49d1bf..f788b39a9 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbsOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbsOperandNode.java @@ -1,9 +1,9 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.IAbsOperandNode; +import org.amshove.natparse.natural.IMathFunctionOperandNode; import org.amshove.natparse.natural.IOperandNode; -class AbsOperandNode extends BaseSyntaxNode implements IAbsOperandNode +class AbsOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { private IOperandNode parameter; diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbstractParser.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbstractParser.java index 0b200efe1..1577abaec 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbstractParser.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AbstractParser.java @@ -516,53 +516,53 @@ protected IOperandNode consumeOperandNode(BaseSyntaxNode node) throws ParseError } if (peekKind(1, SyntaxKind.LPAREN)) { - if (peek().kind() == SyntaxKind.VAL) + switch (peek().kind()) { - return valOperand(node); - } - if (peek().kind() == SyntaxKind.INT) - { - return intOperand(node); - } - if (peek().kind() == SyntaxKind.SUM) - { - return sumOperand(node); - } - if (peek().kind() == SyntaxKind.TOTAL) - { - return totalOperand(node); - } - if (peek().kind() == SyntaxKind.COUNT) - { - return countOperand(node); - } - if (peek().kind() == SyntaxKind.LOG) - { - return logOperand(node); - } - if (peek().kind() == SyntaxKind.OLD) - { - return oldOperand(node); - } - if (peek().kind() == SyntaxKind.ABS) - { - return absOperand(node); - } - if (peek().kind() == SyntaxKind.SGN) - { - return sgnOperand(node); - } - if (peek().kind() == SyntaxKind.POS) - { - return posOperand(node); - } - if (peek().kind() == SyntaxKind.FRAC) - { - return fracOperand(node); - } - if (peek().kind() == SyntaxKind.RET) - { - return retOperand(node); + case ABS: + return absOperand(node); + case ATN: + return atnOperand(node); + case AVER, NAVER: + return averOperand(node); + case COS: + return cosOperand(node); + case COUNT, NCOUNT: + return countOperand(node); + case EXP: + return expOperand(node); + case FRAC: + return fracOperand(node); + case INT: + return intOperand(node); + case LOG: + return logOperand(node); + case MAX: + return maxOperand(node); + case MIN, NMIN: + return minOperand(node); + case OLD: + return oldOperand(node); + case POS: + return posOperand(node); + case RET: + return retOperand(node); + case SGN: + return sgnOperand(node); + case SIN: + return sinOperand(node); + case SORTKEY: + return sortKeyOperand(node); + case SQRT: + return sqrtOperand(node); + case SUM: + return sumOperand(node); + case TAN: + return tanOperand(node); + case TOTAL: + return totalOperand(node); + case VAL: + return valOperand(node); + default: } } if (peek().kind() == SyntaxKind.LABEL_IDENTIFIER) @@ -587,72 +587,94 @@ private IOperandNode prefixUnary(BaseSyntaxNode node) throws ParseError return unary; } - private IOperandNode posOperand(BaseSyntaxNode node) throws ParseError - { - var posNode = new PosNode(); - node.addNode(posNode); - consumeMandatory(posNode, SyntaxKind.POS); - consumeMandatory(posNode, SyntaxKind.LPAREN); - posNode.setPositionOf(consumeVariableReferenceNode(posNode)); - consumeMandatory(posNode, SyntaxKind.RPAREN); - return posNode; - } - - private IOperandNode valOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode absOperand(BaseSyntaxNode node) throws ParseError { - var valOperand = new ValOperandNode(); - node.addNode(valOperand); - consumeMandatory(valOperand, SyntaxKind.VAL); - consumeMandatory(valOperand, SyntaxKind.LPAREN); - valOperand.setVariable(consumeOperandNode(valOperand)); - consumeMandatory(valOperand, SyntaxKind.RPAREN); - return valOperand; + var absOperand = new AbsOperandNode(); + node.addNode(absOperand); + consumeMandatory(absOperand, SyntaxKind.ABS); + consumeMandatory(absOperand, SyntaxKind.LPAREN); + absOperand.setParameter(consumeOperandNode(absOperand)); + consumeMandatory(absOperand, SyntaxKind.RPAREN); + return absOperand; } - private IOperandNode intOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode atnOperand(BaseSyntaxNode node) throws ParseError { - var intOperand = new IntOperandNode(); - node.addNode(intOperand); - consumeMandatory(intOperand, SyntaxKind.INT); - consumeMandatory(intOperand, SyntaxKind.LPAREN); - intOperand.setVariable(consumeVariableReferenceNode(intOperand)); - consumeMandatory(intOperand, SyntaxKind.RPAREN); - return intOperand; + var atnOperand = new AtnOperandNode(); + node.addNode(atnOperand); + consumeMandatory(atnOperand, SyntaxKind.ATN); + consumeMandatory(atnOperand, SyntaxKind.LPAREN); + atnOperand.setParameter(consumeOperandNode(atnOperand)); + consumeMandatory(atnOperand, SyntaxKind.RPAREN); + return atnOperand; } - private IOperandNode sumOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode averOperand(BaseSyntaxNode node) throws ParseError { - var sumOperand = new SumOperandNode(); - node.addNode(sumOperand); - consumeMandatory(sumOperand, SyntaxKind.SUM); - consumeMandatory(sumOperand, SyntaxKind.LPAREN); - sumOperand.setVariable(consumeVariableReferenceNode(sumOperand)); - consumeMandatory(sumOperand, SyntaxKind.RPAREN); - return sumOperand; + var averOperand = new AverOperandNode(); + node.addNode(averOperand); + consumeAnyMandatory(averOperand, List.of(SyntaxKind.AVER, SyntaxKind.NAVER)); + consumeMandatory(averOperand, SyntaxKind.LPAREN); + averOperand.setParameter(consumeVariableReferenceNode(averOperand)); + consumeMandatory(averOperand, SyntaxKind.RPAREN); + return averOperand; } - private IOperandNode totalOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode cosOperand(BaseSyntaxNode node) throws ParseError { - var totalOperand = new TotalOperandNode(); - node.addNode(totalOperand); - consumeMandatory(totalOperand, SyntaxKind.TOTAL); - consumeMandatory(totalOperand, SyntaxKind.LPAREN); - totalOperand.setVariable(consumeVariableReferenceNode(totalOperand)); - consumeMandatory(totalOperand, SyntaxKind.RPAREN); - return totalOperand; + var cosOperand = new CosOperandNode(); + node.addNode(cosOperand); + consumeMandatory(cosOperand, SyntaxKind.COS); + consumeMandatory(cosOperand, SyntaxKind.LPAREN); + cosOperand.setParameter(consumeOperandNode(cosOperand)); + consumeMandatory(cosOperand, SyntaxKind.RPAREN); + return cosOperand; } private IOperandNode countOperand(BaseSyntaxNode node) throws ParseError { var countOperand = new CountOperandNode(); node.addNode(countOperand); - consumeMandatory(countOperand, SyntaxKind.COUNT); + consumeAnyMandatory(countOperand, List.of(SyntaxKind.COUNT, SyntaxKind.NCOUNT)); consumeMandatory(countOperand, SyntaxKind.LPAREN); - countOperand.setVariable(consumeVariableReferenceNode(countOperand)); + countOperand.setParameter(consumeOperandNode(countOperand)); consumeMandatory(countOperand, SyntaxKind.RPAREN); return countOperand; } + private IOperandNode expOperand(BaseSyntaxNode node) throws ParseError + { + var expOperand = new ExpOperandNode(); + node.addNode(expOperand); + consumeMandatory(expOperand, SyntaxKind.EXP); + consumeMandatory(expOperand, SyntaxKind.LPAREN); + expOperand.setParameter(consumeOperandNode(expOperand)); + consumeMandatory(expOperand, SyntaxKind.RPAREN); + return expOperand; + } + + private IOperandNode fracOperand(BaseSyntaxNode node) throws ParseError + { + var fracOperand = new FracOperandNode(); + node.addNode(fracOperand); + consumeMandatory(fracOperand, SyntaxKind.FRAC); + consumeMandatory(fracOperand, SyntaxKind.LPAREN); + fracOperand.setParameter(consumeOperandNode(fracOperand)); + consumeMandatory(fracOperand, SyntaxKind.RPAREN); + return fracOperand; + } + + private IOperandNode intOperand(BaseSyntaxNode node) throws ParseError + { + var intOperand = new IntOperandNode(); + node.addNode(intOperand); + consumeMandatory(intOperand, SyntaxKind.INT); + consumeMandatory(intOperand, SyntaxKind.LPAREN); + intOperand.setParameter(consumeVariableReferenceNode(intOperand)); + consumeMandatory(intOperand, SyntaxKind.RPAREN); + return intOperand; + } + private IOperandNode logOperand(BaseSyntaxNode node) throws ParseError { var logOperand = new LogOperandNode(); @@ -664,26 +686,59 @@ private IOperandNode logOperand(BaseSyntaxNode node) throws ParseError return logOperand; } + private IOperandNode maxOperand(BaseSyntaxNode node) throws ParseError + { + var maxOperand = new MaxOperandNode(); + node.addNode(maxOperand); + consumeMandatory(maxOperand, SyntaxKind.MAX); + consumeMandatory(maxOperand, SyntaxKind.LPAREN); + maxOperand.setParameter(consumeOperandNode(maxOperand)); + consumeMandatory(maxOperand, SyntaxKind.RPAREN); + return maxOperand; + } + + private IOperandNode minOperand(BaseSyntaxNode node) throws ParseError + { + var minOperand = new MinOperandNode(); + node.addNode(minOperand); + consumeAnyMandatory(minOperand, List.of(SyntaxKind.MIN, SyntaxKind.NMIN)); + consumeMandatory(minOperand, SyntaxKind.LPAREN); + minOperand.setParameter(consumeOperandNode(minOperand)); + consumeMandatory(minOperand, SyntaxKind.RPAREN); + return minOperand; + } + private IOperandNode oldOperand(BaseSyntaxNode node) throws ParseError { var oldOperand = new OldOperandNode(); node.addNode(oldOperand); consumeMandatory(oldOperand, SyntaxKind.OLD); consumeMandatory(oldOperand, SyntaxKind.LPAREN); - oldOperand.setOperand(consumeOperandNode(oldOperand)); + oldOperand.setParameter(consumeOperandNode(oldOperand)); consumeMandatory(oldOperand, SyntaxKind.RPAREN); return oldOperand; } - private IOperandNode absOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode posOperand(BaseSyntaxNode node) throws ParseError { - var absOperand = new AbsOperandNode(); - node.addNode(absOperand); - consumeMandatory(absOperand, SyntaxKind.ABS); - consumeMandatory(absOperand, SyntaxKind.LPAREN); - absOperand.setParameter(consumeOperandNode(absOperand)); - consumeMandatory(absOperand, SyntaxKind.RPAREN); - return absOperand; + var posOperand = new PosOperandNode(); + node.addNode(posOperand); + consumeMandatory(posOperand, SyntaxKind.POS); + consumeMandatory(posOperand, SyntaxKind.LPAREN); + posOperand.setPositionOf(consumeVariableReferenceNode(posOperand)); + consumeMandatory(posOperand, SyntaxKind.RPAREN); + return posOperand; + } + + private IOperandNode retOperand(BaseSyntaxNode node) throws ParseError + { + var retOperand = new RetOperandNode(); + node.addNode(retOperand); + consumeMandatory(retOperand, SyntaxKind.RET); + consumeMandatory(retOperand, SyntaxKind.LPAREN); + retOperand.setParameter(consumeLiteralNode(retOperand)); + consumeMandatory(retOperand, SyntaxKind.RPAREN); + return retOperand; } private IOperandNode sgnOperand(BaseSyntaxNode node) throws ParseError @@ -697,26 +752,81 @@ private IOperandNode sgnOperand(BaseSyntaxNode node) throws ParseError return sgnOperand; } - private IOperandNode fracOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode sinOperand(BaseSyntaxNode node) throws ParseError { - var fracOperand = new FracOperandNode(); - node.addNode(fracOperand); - consumeMandatory(fracOperand, SyntaxKind.FRAC); - consumeMandatory(fracOperand, SyntaxKind.LPAREN); - fracOperand.setParameter(consumeOperandNode(fracOperand)); - consumeMandatory(fracOperand, SyntaxKind.RPAREN); - return fracOperand; + var sinOperand = new SinOperandNode(); + node.addNode(sinOperand); + consumeMandatory(sinOperand, SyntaxKind.SIN); + consumeMandatory(sinOperand, SyntaxKind.LPAREN); + sinOperand.setParameter(consumeOperandNode(sinOperand)); + consumeMandatory(sinOperand, SyntaxKind.RPAREN); + return sinOperand; } - private IOperandNode retOperand(BaseSyntaxNode node) throws ParseError + private IOperandNode sortKeyOperand(BaseSyntaxNode node) throws ParseError { - var retOperand = new RetOperandNode(); - node.addNode(retOperand); - consumeMandatory(retOperand, SyntaxKind.RET); - consumeMandatory(retOperand, SyntaxKind.LPAREN); - retOperand.setParameter(consumeLiteralNode(retOperand)); - consumeMandatory(retOperand, SyntaxKind.RPAREN); - return retOperand; + var sortkeyOperand = new SortKeyOperandNode(); + node.addNode(sortkeyOperand); + consumeMandatory(sortkeyOperand, SyntaxKind.SORTKEY); + consumeMandatory(sortkeyOperand, SyntaxKind.LPAREN); + sortkeyOperand.setVariable(consumeVariableReferenceNode(sortkeyOperand)); + consumeMandatory(sortkeyOperand, SyntaxKind.RPAREN); + return sortkeyOperand; + } + + private IOperandNode sqrtOperand(BaseSyntaxNode node) throws ParseError + { + var sqrtOperand = new SqrtOperandNode(); + node.addNode(sqrtOperand); + consumeMandatory(sqrtOperand, SyntaxKind.SQRT); + consumeMandatory(sqrtOperand, SyntaxKind.LPAREN); + sqrtOperand.setParameter(consumeOperandNode(sqrtOperand)); + consumeMandatory(sqrtOperand, SyntaxKind.RPAREN); + return sqrtOperand; + } + + private IOperandNode tanOperand(BaseSyntaxNode node) throws ParseError + { + var tanOperand = new TanOperandNode(); + node.addNode(tanOperand); + consumeMandatory(tanOperand, SyntaxKind.TAN); + consumeMandatory(tanOperand, SyntaxKind.LPAREN); + tanOperand.setParameter(consumeOperandNode(tanOperand)); + consumeMandatory(tanOperand, SyntaxKind.RPAREN); + return tanOperand; + } + + private IOperandNode sumOperand(BaseSyntaxNode node) throws ParseError + { + var sumOperand = new SumOperandNode(); + node.addNode(sumOperand); + consumeMandatory(sumOperand, SyntaxKind.SUM); + consumeMandatory(sumOperand, SyntaxKind.LPAREN); + sumOperand.setParameter(consumeVariableReferenceNode(sumOperand)); + consumeMandatory(sumOperand, SyntaxKind.RPAREN); + return sumOperand; + } + + private IOperandNode totalOperand(BaseSyntaxNode node) throws ParseError + { + var totalOperand = new TotalOperandNode(); + node.addNode(totalOperand); + consumeMandatory(totalOperand, SyntaxKind.TOTAL); + consumeMandatory(totalOperand, SyntaxKind.LPAREN); + totalOperand.setParameter(consumeVariableReferenceNode(totalOperand)); + consumeMandatory(totalOperand, SyntaxKind.RPAREN); + return totalOperand; + } + + private IOperandNode valOperand(BaseSyntaxNode node) throws ParseError + { + var valOperand = new ValOperandNode(); + node.addNode(valOperand); + consumeMandatory(valOperand, SyntaxKind.VAL); + consumeMandatory(valOperand, SyntaxKind.LPAREN); + valOperand.setParameter(consumeOperandNode(valOperand)); + consumeMandatory(valOperand, SyntaxKind.RPAREN); + return valOperand; } private IOperandNode consumeLabelIdentifier(BaseSyntaxNode node) throws ParseError diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AtnOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AtnOperandNode.java new file mode 100644 index 000000000..46ccd1c7f --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AtnOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class AtnOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/AverOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AverOperandNode.java new file mode 100644 index 000000000..0650fbbda --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/AverOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class AverOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/CosOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/CosOperandNode.java new file mode 100644 index 000000000..5e52eafc2 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/CosOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class CosOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/CountOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/CountOperandNode.java index b6f0d9b47..d134b1649 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/CountOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/CountOperandNode.java @@ -1,20 +1,20 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.ICountOperandNode; -import org.amshove.natparse.natural.IVariableReferenceNode; +import org.amshove.natparse.natural.IOperandNode; +import org.amshove.natparse.natural.IProcessingLoopFunctionNode; -class CountOperandNode extends BaseSyntaxNode implements ICountOperandNode +class CountOperandNode extends BaseSyntaxNode implements IProcessingLoopFunctionNode { - private IVariableReferenceNode variable; + private IOperandNode parameter; @Override - public IVariableReferenceNode variable() + public IOperandNode parameter() { - return variable; + return parameter; } - void setVariable(IVariableReferenceNode variable) + void setParameter(IOperandNode parameter) { - this.variable = variable; + this.parameter = parameter; } } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/ExpOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/ExpOperandNode.java new file mode 100644 index 000000000..059294381 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/ExpOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class ExpOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/FracOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/FracOperandNode.java index 748ee48d5..e435bd6e2 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/FracOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/FracOperandNode.java @@ -1,9 +1,9 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.IFracOperandNode; +import org.amshove.natparse.natural.IMathFunctionOperandNode; import org.amshove.natparse.natural.IOperandNode; -class FracOperandNode extends BaseSyntaxNode implements IFracOperandNode +class FracOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { private IOperandNode parameter; diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/IntOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/IntOperandNode.java index 84e2c36dd..abdb9c413 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/IntOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/IntOperandNode.java @@ -1,20 +1,20 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.IIntOperandNode; -import org.amshove.natparse.natural.IVariableReferenceNode; +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; -class IntOperandNode extends BaseSyntaxNode implements IIntOperandNode +class IntOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { - private IVariableReferenceNode variable; + private IOperandNode parameter; @Override - public IVariableReferenceNode variable() + public IOperandNode parameter() { - return variable; + return parameter; } - void setVariable(IVariableReferenceNode variable) + void setParameter(IOperandNode parameter) { - this.variable = variable; + this.parameter = parameter; } } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/MathFunctionOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MathFunctionOperandNode.java new file mode 100644 index 000000000..b6095370c --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MathFunctionOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class MathFunctionOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/MaxOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MaxOperandNode.java new file mode 100644 index 000000000..f961758ab --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MaxOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IOperandNode; +import org.amshove.natparse.natural.IProcessingLoopFunctionNode; + +class MaxOperandNode extends BaseSyntaxNode implements IProcessingLoopFunctionNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/MinOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MinOperandNode.java new file mode 100644 index 000000000..85672e45a --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/MinOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IOperandNode; +import org.amshove.natparse.natural.IProcessingLoopFunctionNode; + +class MinOperandNode extends BaseSyntaxNode implements IProcessingLoopFunctionNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/NaturalParser.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/NaturalParser.java index 2eca9011a..9f0a2e3a3 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/NaturalParser.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/NaturalParser.java @@ -161,7 +161,7 @@ private IStatementListNode parseBody(TokenList tokens, IModuleProvider modulePro } } - if (naturalModule.body() != null) + if (naturalModule.body() != null && naturalModule.file().getFiletype() != NaturalFileType.COPYCODE) { var typer = new TypeChecker(); for (var diagnostic : typer.check(naturalModule.body())) diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/OldOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/OldOperandNode.java index 72e231054..b66c2ecf2 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/OldOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/OldOperandNode.java @@ -1,20 +1,20 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.IOldOperandNode; import org.amshove.natparse.natural.IOperandNode; +import org.amshove.natparse.natural.IProcessingLoopFunctionNode; -class OldOperandNode extends BaseSyntaxNode implements IOldOperandNode +class OldOperandNode extends BaseSyntaxNode implements IProcessingLoopFunctionNode { - private IOperandNode operand; + private IOperandNode parameter; @Override - public IOperandNode operand() + public IOperandNode parameter() { - return operand; + return parameter; } - void setOperand(IOperandNode operand) + void setParameter(IOperandNode parameter) { - this.operand = operand; + this.parameter = parameter; } } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/PosNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/PosOperandNode.java similarity index 72% rename from libs/natparse/src/main/java/org/amshove/natparse/parsing/PosNode.java rename to libs/natparse/src/main/java/org/amshove/natparse/parsing/PosOperandNode.java index d8edaa583..1e22c6af7 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/PosNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/PosOperandNode.java @@ -1,9 +1,9 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.IPosNode; +import org.amshove.natparse.natural.IPosOperandNode; import org.amshove.natparse.natural.IVariableReferenceNode; -class PosNode extends BaseSyntaxNode implements IPosNode +class PosOperandNode extends BaseSyntaxNode implements IPosOperandNode { private IVariableReferenceNode positionOf; diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SignOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SignOperandNode.java index 15673923b..6e9ed01f2 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SignOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SignOperandNode.java @@ -1,9 +1,9 @@ package org.amshove.natparse.parsing; +import org.amshove.natparse.natural.IMathFunctionOperandNode; import org.amshove.natparse.natural.IOperandNode; -import org.amshove.natparse.natural.ISignOperandNode; -class SignOperandNode extends BaseSyntaxNode implements ISignOperandNode +class SignOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { private IOperandNode parameter; diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SinOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SinOperandNode.java new file mode 100644 index 000000000..7b820dc22 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SinOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class SinOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SortKeyOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SortKeyOperandNode.java new file mode 100644 index 000000000..ec851a907 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SortKeyOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.ISortKeyOperandNode; +import org.amshove.natparse.natural.IVariableReferenceNode; + +class SortKeyOperandNode extends BaseSyntaxNode implements ISortKeyOperandNode +{ + private IVariableReferenceNode variable; + + @Override + public IVariableReferenceNode variable() + { + return variable; + } + + void setVariable(IVariableReferenceNode variable) + { + this.variable = variable; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SqrtOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SqrtOperandNode.java new file mode 100644 index 000000000..fdfa9f234 --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SqrtOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class SqrtOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SumOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SumOperandNode.java index 2f91979b4..a67b3d13c 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/SumOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/SumOperandNode.java @@ -1,20 +1,20 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.ISumOperandNode; -import org.amshove.natparse.natural.IVariableReferenceNode; +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; -class SumOperandNode extends BaseSyntaxNode implements ISumOperandNode +class SumOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { - private IVariableReferenceNode variable; + private IOperandNode parameter; @Override - public IVariableReferenceNode variable() + public IOperandNode parameter() { - return variable; + return parameter; } - void setVariable(IVariableReferenceNode variable) + void setParameter(IOperandNode parameter) { - this.variable = variable; + this.parameter = parameter; } } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/TanOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TanOperandNode.java new file mode 100644 index 000000000..7eb90aded --- /dev/null +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TanOperandNode.java @@ -0,0 +1,20 @@ +package org.amshove.natparse.parsing; + +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; + +class TanOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode +{ + private IOperandNode parameter; + + @Override + public IOperandNode parameter() + { + return parameter; + } + + void setParameter(IOperandNode parameter) + { + this.parameter = parameter; + } +} diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/TotalOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TotalOperandNode.java index b7a6ee161..66ac8ae03 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/TotalOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TotalOperandNode.java @@ -1,20 +1,20 @@ package org.amshove.natparse.parsing; -import org.amshove.natparse.natural.ITotalOperandNode; -import org.amshove.natparse.natural.IVariableReferenceNode; +import org.amshove.natparse.natural.IMathFunctionOperandNode; +import org.amshove.natparse.natural.IOperandNode; -class TotalOperandNode extends BaseSyntaxNode implements ITotalOperandNode +class TotalOperandNode extends BaseSyntaxNode implements IMathFunctionOperandNode { - private IVariableReferenceNode variable; + private IOperandNode parameter; @Override - public IVariableReferenceNode variable() + public IOperandNode parameter() { - return variable; + return parameter; } - void setVariable(IVariableReferenceNode variable) + void setParameter(IOperandNode parameter) { - this.variable = variable; + this.parameter = parameter; } } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/TypeChecker.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TypeChecker.java index 66d847c59..ccbc39b35 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/TypeChecker.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/TypeChecker.java @@ -193,17 +193,81 @@ private void checkNode(ISyntaxNode node) && typedVariableNode.type().initialValue() != null) { checkVariableInitType(typedVariableNode); + return; } if (node instanceof IVariableReferenceNode variableReference) { checkVariableReference(variableReference); + return; } if (node instanceof ISystemFunctionNode sysFuncNode) { checkSystemFunctionParameter(sysFuncNode); + return; + } + + if (node instanceof IProcessingLoopFunctionNode function) + { + checkProcessingLoopFunctions(function); + } + + if (node instanceof IMathFunctionOperandNode function) + { + checkMathematicalSystemFunctions(function); + return; + } + + checkAlphaSystemFunctions(node); + } + + private void checkProcessingLoopFunctions(IProcessingLoopFunctionNode operand) + { + var type = inferDataType(operand.parameter()); + if (operand.parameter() instanceof ILiteralNode || type.format() == DataFormat.NONE) + { + report(ParserErrors.typeMismatch("Parameter must be a typed variable of any format, but is %s".formatted(type.toShortString()), operand)); + } + } + + private void checkMathematicalSystemFunctions(IMathFunctionOperandNode operand) + { + var type = inferDataType(operand.parameter()); + if (type.format() != DataFormat.NONE && !type.isNumericFamily()) + { + report(ParserErrors.typeMismatch("Parameter must be of type N, P, I or F, but is %s".formatted(type.toShortString()), operand)); + } + } + + private boolean checkAlphaSystemFunctions(ISyntaxNode node) + { + IDataType type; + + if (node instanceof ISortKeyOperandNode sortKeyNode) + { + type = inferDataType(sortKeyNode.variable()); + if (type.format() != DataFormat.ALPHANUMERIC || type.length() > 253 || type.hasDynamicLength()) + { + report(ParserErrors.typeMismatch("Parameter must be of type A with a maximum length of 253, but is %s".formatted(type.toShortString()), node)); + } + } + + if (node instanceof IValOperandNode valNode) + { + type = inferDataType(valNode.parameter()); + if (valNode.parameter() instanceof ILiteralNode) + { + return false; + } + + if (type.format() != DataFormat.NONE && type.format() != DataFormat.ALPHANUMERIC && type.format() != DataFormat.UNICODE) + { + report(ParserErrors.typeMismatch("Parameter must be of type A or U, but is %s".formatted(type.toShortString()), node)); + } } + + return true; } private void checkSystemFunctionParameter(ISystemFunctionNode sysFuncNode) @@ -552,7 +616,7 @@ private boolean containsDynamicDimension(IRangedArrayAccessNode ranged) private IDataType inferDataType(IOperandNode operand) { - if (operand instanceof IVariableReferenceNode variable && variable.reference()instanceof ITypedVariableNode typedRef) + if (operand instanceof IVariableReferenceNode variable && variable.reference()instanceof ITypedVariableNode typedRef && typedRef.type() != null) { return typedRef.type(); } diff --git a/libs/natparse/src/main/java/org/amshove/natparse/parsing/ValOperandNode.java b/libs/natparse/src/main/java/org/amshove/natparse/parsing/ValOperandNode.java index 2d25c6861..76fa860f9 100644 --- a/libs/natparse/src/main/java/org/amshove/natparse/parsing/ValOperandNode.java +++ b/libs/natparse/src/main/java/org/amshove/natparse/parsing/ValOperandNode.java @@ -5,16 +5,16 @@ class ValOperandNode extends BaseSyntaxNode implements IValOperandNode { - private IOperandNode operand; + private IOperandNode parameter; @Override - public IOperandNode operand() + public IOperandNode parameter() { - return operand; + return parameter; } - void setVariable(IOperandNode operand) + void setParameter(IOperandNode parameter) { - this.operand = operand; + this.parameter = parameter; } } diff --git a/libs/natparse/src/test/java/org/amshove/natparse/parsing/ConditionalParsingTests.java b/libs/natparse/src/test/java/org/amshove/natparse/parsing/ConditionalParsingTests.java index 1896f6a79..6e92ad139 100644 --- a/libs/natparse/src/test/java/org/amshove/natparse/parsing/ConditionalParsingTests.java +++ b/libs/natparse/src/test/java/org/amshove/natparse/parsing/ConditionalParsingTests.java @@ -550,16 +550,16 @@ void parseRelationalCriteriaWithVal() void parseRelationalCriteriaWithAbs() { var criteria = assertParsesCriteria("ABS(#VAR1) = ABS(#VAR2)", IRelationalCriteriaNode.class); - assertNodeType(criteria.left(), IAbsOperandNode.class); - assertNodeType(criteria.right(), IAbsOperandNode.class); + assertNodeType(criteria.left(), IMathFunctionOperandNode.class); + assertNodeType(criteria.right(), IMathFunctionOperandNode.class); } @Test void parseRelationalCriteriaWithFrac() { var criteria = assertParsesCriteria("FRAC(#VAR1) <> ABS(0)", IRelationalCriteriaNode.class); - assertNodeType(criteria.left(), IFracOperandNode.class); - assertNodeType(criteria.right(), IAbsOperandNode.class); + assertNodeType(criteria.left(), IMathFunctionOperandNode.class); + assertNodeType(criteria.right(), IMathFunctionOperandNode.class); } @Test diff --git a/libs/natparse/src/test/java/org/amshove/natparse/parsing/DataTypeCheckingShould.java b/libs/natparse/src/test/java/org/amshove/natparse/parsing/DataTypeCheckingShould.java index 99c0cc3c4..bc9341ad6 100644 --- a/libs/natparse/src/test/java/org/amshove/natparse/parsing/DataTypeCheckingShould.java +++ b/libs/natparse/src/test/java/org/amshove/natparse/parsing/DataTypeCheckingShould.java @@ -7,10 +7,66 @@ import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.ValueSource; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; class DataTypeCheckingShould { + @ParameterizedTest + @ValueSource(strings = + { + "F", "I", "N", "P" + }) + void seeNumericFamily(String type) + { + var format = type(DataFormat.fromSource(type), 8); + + assertThat(format.isNumericFamily()) + .as("%s is numeric family".formatted(format.toShortString())) + .isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = + { + "A", "B", "C", "D", "L", "T", "U" + }) + void seeNotNumericFamily(String type) + { + var format = type(DataFormat.fromSource(type), 8); + + assertThat(format.isNumericFamily()) + .as("%s is numeric family".formatted(format.toShortString())) + .isFalse(); + } + + @ParameterizedTest + @ValueSource(strings = + { + "A", "B", "U" + }) + void seeAlphanumericFamily(String type) + { + var format = type(DataFormat.fromSource(type), 8); + + assertThat(format.isAlphaNumericFamily()) + .as("%s is alphanumeric family".formatted(format.toShortString())) + .isTrue(); + } + + @ParameterizedTest + @ValueSource(strings = + { + "C", "D", "F", "I", "L", "N", "P" + }) + void seeNotAlphanumericFamily(String type) + { + var format = type(DataFormat.fromSource(type), 8); + + assertThat(format.isAlphaNumericFamily()) + .as("%s is alphanumeric family".formatted(format.toShortString())) + .isFalse(); + } + @ParameterizedTest @ValueSource(strings = { diff --git a/libs/natparse/src/test/java/org/amshove/natparse/parsing/OperandParsingTests.java b/libs/natparse/src/test/java/org/amshove/natparse/parsing/OperandParsingTests.java index 20ccf05e0..0ae69f6c6 100644 --- a/libs/natparse/src/test/java/org/amshove/natparse/parsing/OperandParsingTests.java +++ b/libs/natparse/src/test/java/org/amshove/natparse/parsing/OperandParsingTests.java @@ -147,81 +147,99 @@ void parseMultilineOperands() OTHERVAR """); var firstReference = assertNodeType(operand.get(0), IVariableReferenceNode.class); - assertIsVariableReference(firstReference, "#THEVAR"); + assertThat(firstReference.referencingToken().symbolName()).isEqualTo("#THEVAR"); var secondReference = assertNodeType(operand.get(1), IVariableReferenceNode.class); - assertIsVariableReference(secondReference, "OTHERVAR"); + assertThat(secondReference.referencingToken().symbolName()).isEqualTo("OTHERVAR"); } @Test - void parseVal() + void parseAbs() { - var operand = parseOperand("VAL(#THEVAR(1))"); - var valNode = assertNodeType(operand, IValOperandNode.class); - var ref = assertNodeType(valNode.operand(), IVariableReferenceNode.class); - assertIsVariableReference(ref, "#THEVAR"); - assertThat(assertNodeType(ref.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); + var operand = parseOperand("ABS(#THEVAR)"); + var absNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(absNode.parameter(), "#THEVAR"); } - @Test - void parseValWithNestedOperand() + @ParameterizedTest + @ValueSource(strings = { - var operand = parseOperand("VAL(OLD(#VAR))"); - var valNode = assertNodeType(operand, IValOperandNode.class); - var old = assertNodeType(valNode.operand(), IOldOperandNode.class); - assertIsVariableReference(old.operand(), "#VAR"); + "AVER(#THEVAR)", "NAVER(#THEVAR)" + }) + void parseAver(String operandSource) + { + var operand = parseOperand(operandSource); + var averNode = assertNodeType(operand, IMathFunctionOperandNode.class); + var reference = assertNodeType(averNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); } @Test - void parseInt() + void parseAtn() { - var operand = parseOperand("INT(#THEVAR(1))"); - var valNode = assertNodeType(operand, IIntOperandNode.class); - assertIsVariableReference(valNode.variable(), "#THEVAR"); - assertThat(assertNodeType(valNode.variable().dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); + var operand = parseOperand("ATN(#THEVAR)"); + var atnNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(atnNode.parameter(), "#THEVAR"); } @Test - void parseSum() + void parseCos() { - var operand = parseOperand("SUM(#THEVAR)"); - var sumNode = assertNodeType(operand, ISumOperandNode.class); - assertIsVariableReference(sumNode.variable(), "#THEVAR"); + var operand = parseOperand("COS(#THEVAR)"); + var cosNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(cosNode.parameter(), "#THEVAR"); } - @Test - void parseSumWithNestedOperand() + @ParameterizedTest + @ValueSource(strings = { - var operand = parseOperand("SUM(#THEVAR(1))"); - var sumNode = assertNodeType(operand, ISumOperandNode.class); - var reference = assertNodeType(sumNode.variable(), IVariableReferenceNode.class); - assertIsVariableReference(sumNode.variable(), "#THEVAR"); + "COUNT(#THEVAR)", "NCOUNT(#THEVAR)" + }) + void parseCount(String operandSource) + { + var operand = parseOperand(operandSource); + var countNode = assertNodeType(operand, IProcessingLoopFunctionNode.class); + var reference = assertNodeType(countNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); + } + + @ParameterizedTest + @ValueSource(strings = + { + "COUNT(#THEVAR(1))", "NCOUNT(#THEVAR(1))" + }) + void parseCountWithNestedOperand(String operandSource) + { + var operand = parseOperand(operandSource); + var countNode = assertNodeType(operand, IProcessingLoopFunctionNode.class); + var reference = assertNodeType(countNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); assertThat(assertNodeType(reference.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); } @Test - void parseTotal() + void parseExp() { - var operand = parseOperand("TOTAL(#THEVAR)"); - var totalNode = assertNodeType(operand, ITotalOperandNode.class); - assertIsVariableReference(totalNode.variable(), "#THEVAR"); + var operand = parseOperand("EXP(#THEVAR)"); + var expNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(expNode.parameter(), "#THEVAR"); } @Test - void parseCount() + void parseFrac() { - var operand = parseOperand("COUNT(#THEVAR)"); - var countNode = assertNodeType(operand, ICountOperandNode.class); - assertIsVariableReference(countNode.variable(), "#THEVAR"); + var operand = parseOperand("FRAC(#THEVAR)"); + var fracNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(fracNode.parameter(), "#THEVAR"); } @Test - void parseCountWithNestedOperand() + void parseInt() { - var operand = parseOperand("COUNT(#THEVAR(1))"); - var countNode = assertNodeType(operand, ICountOperandNode.class); - var reference = assertNodeType(countNode.variable(), IVariableReferenceNode.class); - assertIsVariableReference(countNode.variable(), "#THEVAR"); + var operand = parseOperand("INT(#THEVAR(1))"); + var intNode = assertNodeType(operand, IMathFunctionOperandNode.class); + var reference = assertNodeType(intNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); assertThat(assertNodeType(reference.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); } @@ -229,36 +247,124 @@ void parseCountWithNestedOperand() void parseLog() { var operand = parseOperand("LOG(#THEVAR(1))"); - var logNode = assertNodeType(operand, ILogOperandNode.class); + var logNode = assertNodeType(operand, IMathFunctionOperandNode.class); var reference = assertNodeType(logNode.parameter(), IVariableReferenceNode.class); assertIsVariableReference(reference, "#THEVAR"); assertThat(assertNodeType(reference.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); } @Test - void parseOld() + void parseMax() { - var operand = parseOperand("OLD(#THEVAR)"); - var oldNode = assertNodeType(operand, IOldOperandNode.class); - assertIsVariableReference(oldNode.operand(), "#THEVAR"); + var operand = parseOperand("MAX(#THEVAR)"); + var maxNode = assertNodeType(operand, IProcessingLoopFunctionNode.class); + assertIsVariableReference(maxNode.parameter(), "#THEVAR"); + } + + @ParameterizedTest + @ValueSource(strings = + { + "MIN(#THEVAR)", "NMIN(#THEVAR)" + }) + void parseMin(String operandSource) + { + var operand = parseOperand(operandSource); + var minNode = assertNodeType(operand, IProcessingLoopFunctionNode.class); + var reference = assertNodeType(minNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); } @Test - void parseAbs() + void parseOld() { - var operand = parseOperand("ABS(#THEVAR)"); - var absNode = assertNodeType(operand, IAbsOperandNode.class); - var parameter = assertNodeType(absNode.parameter(), IVariableReferenceNode.class); - assertIsVariableReference(parameter, "#THEVAR"); + var operand = parseOperand("OLD(#THEVAR)"); + var oldNode = assertNodeType(operand, IProcessingLoopFunctionNode.class); + assertIsVariableReference(oldNode.parameter(), "#THEVAR"); } @Test void parseSgn() { var operand = parseOperand("SGN(#THEVAR)"); - var sgnNode = assertNodeType(operand, ISignOperandNode.class); - var parameter = assertNodeType(sgnNode.parameter(), IVariableReferenceNode.class); - assertIsVariableReference(parameter, "#THEVAR"); + var sgnNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(sgnNode.parameter(), "#THEVAR"); + } + + @Test + void parseSin() + { + var operand = parseOperand("SIN(#THEVAR)"); + var sinNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(sinNode.parameter(), "#THEVAR"); + } + + @Test + void parseSortKey() + { + var operand = parseOperand("SORTKEY(#THEVAR)"); + var sortKey = assertNodeType(operand, ISortKeyOperandNode.class); + assertIsVariableReference(sortKey.variable(), "#THEVAR"); + } + + @Test + void parseSqrt() + { + var operand = parseOperand("SQRT(#THEVAR)"); + var sqrtNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(sqrtNode.parameter(), "#THEVAR"); + } + + @Test + void parseSum() + { + var operand = parseOperand("SUM(#THEVAR)"); + var sumNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(sumNode.parameter(), "#THEVAR"); + } + + @Test + void parseSumWithNestedOperand() + { + var operand = parseOperand("SUM(#THEVAR(1))"); + var sumNode = assertNodeType(operand, IMathFunctionOperandNode.class); + var reference = assertNodeType(sumNode.parameter(), IVariableReferenceNode.class); + assertIsVariableReference(reference, "#THEVAR"); + assertThat(assertNodeType(reference.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); + } + + @Test + void parseTan() + { + var operand = parseOperand("TAN(#THEVAR)"); + var tanNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(tanNode.parameter(), "#THEVAR"); + } + + @Test + void parseTotal() + { + var operand = parseOperand("TOTAL(#THEVAR)"); + var totalNode = assertNodeType(operand, IMathFunctionOperandNode.class); + assertIsVariableReference(totalNode.parameter(), "#THEVAR"); + } + + @Test + void parseVal() + { + var operand = parseOperand("VAL(#THEVAR(1))"); + var valNode = assertNodeType(operand, IValOperandNode.class); + var reference = assertNodeType(valNode.parameter(), IVariableReferenceNode.class); + assertThat(reference.referencingToken().symbolName()).isEqualTo("#THEVAR"); + assertThat(assertNodeType(reference.dimensions().first(), ILiteralNode.class).token().intValue()).isEqualTo(1); + } + + @Test + void parseValWithNestedOperand() + { + var operand = parseOperand("VAL(OLD(#VAR))"); + var valNode = assertNodeType(operand, IValOperandNode.class); + var oldNode = assertNodeType(valNode.parameter(), IProcessingLoopFunctionNode.class); + assertIsVariableReference(oldNode.parameter(), "#VAR"); } @Test @@ -266,20 +372,11 @@ void parseFunctionsAsAbsParameter() { moduleProvider.addModule("FUNC", new NaturalModule(null)); var operand = parseOperand("ABS(FUNC(<'A', 5>))"); - var abs = assertNodeType(operand, IAbsOperandNode.class); + var abs = assertNodeType(operand, IMathFunctionOperandNode.class); var functionAsParameter = assertNodeType(abs.parameter(), IFunctionCallNode.class); assertThat(functionAsParameter.referencingToken().symbolName()).isEqualTo("FUNC"); } - @Test - void parseFrac() - { - var operand = parseOperand("FRAC(#THEVAR)"); - var fracNode = assertNodeType(operand, IFracOperandNode.class); - var parameter = assertNodeType(fracNode.parameter(), IVariableReferenceNode.class); - assertIsVariableReference(parameter, "#THEVAR"); - } - @Test void parseNumberWithParam() { @@ -342,7 +439,7 @@ void parseArithmeticInArrayAccess() void parsePosOperand() { var operand = parseOperand("POS(#VAR.#VAR2)"); - assertThat(assertNodeType(operand, IPosNode.class).positionOf().token().symbolName()).isEqualTo("#VAR.#VAR2"); + assertThat(assertNodeType(operand, IPosOperandNode.class).positionOf().token().symbolName()).isEqualTo("#VAR.#VAR2"); } @Test @@ -423,7 +520,7 @@ void parseArrayAccessWithVariableRanges() var access = assertNodeType(operand, IVariableReferenceNode.class); assertThat(access.dimensions()).hasSize(1); var rangedAccess = assertNodeType(access.dimensions().first(), IRangedArrayAccessNode.class); - assertIsVariableReference(rangedAccess.lowerBound(), "#LOW"); + assertThat(assertNodeType(rangedAccess.lowerBound(), IVariableReferenceNode.class).referencingToken().symbolName()).isEqualTo("#LOW"); assertThat(assertNodeType(rangedAccess.upperBound(), ILiteralNode.class).token().intValue()).isEqualTo(50); } @@ -435,7 +532,7 @@ void parseArrayAccessWithVariableRangesInUpperBound() assertThat(access.dimensions()).hasSize(1); var rangedAccess = assertNodeType(access.dimensions().first(), IRangedArrayAccessNode.class); assertThat(assertNodeType(rangedAccess.lowerBound(), ILiteralNode.class).token().intValue()).isEqualTo(5); - assertIsVariableReference(rangedAccess.upperBound(), "#UP"); + assertThat(assertNodeType(rangedAccess.upperBound(), IVariableReferenceNode.class).referencingToken().symbolName()).isEqualTo("#UP"); } @Test @@ -485,7 +582,7 @@ void parsePostfixMinusOperands() var operand = parseOperand("-#VAR"); var postfix = assertNodeType(operand, IPrefixUnaryArithmeticExpressionNode.class); assertThat(postfix.postfixOperator()).isEqualTo(SyntaxKind.MINUS); - assertIsVariableReference(postfix.operand(), "#VAR"); + assertThat(assertNodeType(postfix.operand(), IVariableReferenceNode.class).referencingToken().symbolName()).isEqualTo("#VAR"); } @Test @@ -494,7 +591,7 @@ void parsePostfixPlusOperands() var operand = parseOperand("+ #VAR"); var postfix = assertNodeType(operand, IPrefixUnaryArithmeticExpressionNode.class); assertThat(postfix.postfixOperator()).isEqualTo(SyntaxKind.PLUS); - assertIsVariableReference(postfix.operand(), "#VAR"); + assertThat(assertNodeType(postfix.operand(), IVariableReferenceNode.class).referencingToken().symbolName()).isEqualTo("#VAR"); } @Test diff --git a/libs/natparse/src/test/java/org/amshove/natparse/parsing/StatementListParserShould.java b/libs/natparse/src/test/java/org/amshove/natparse/parsing/StatementListParserShould.java index 7b4685371..4537ca67f 100644 --- a/libs/natparse/src/test/java/org/amshove/natparse/parsing/StatementListParserShould.java +++ b/libs/natparse/src/test/java/org/amshove/natparse/parsing/StatementListParserShould.java @@ -1425,7 +1425,7 @@ void parseMove(String statement) { "OLD(#VAR1) INTO #VAR2", "OLD(*ISN) TO #VAR2", - "SUM(#VAR1) INTO #VAR2" + "SUM(#VAR1) INTO #VAR2", }) void parseMoveWithSystemFunctions(String statement) { @@ -3227,6 +3227,7 @@ void parseExpandArrayToDimension(String source) { var expand = assertParsesSingleStatement("EXPAND %s ARRAY #ARR TO (1:10,*:*,5:*)".formatted(source), IExpandArrayNode.class); assertIsVariableReference(expand.arrayToExpand(), "#ARR"); + assertIsVariableReference(expand.mutations().first(), "#ARR"); } @Test diff --git a/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/systemFunctionsParameter b/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/systemFunctionsParameter new file mode 100644 index 000000000..6dd5528d8 --- /dev/null +++ b/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/systemFunctionsParameter @@ -0,0 +1,148 @@ +DEFINE DATA LOCAL +1 #ASSIGNED (A) DYNAMIC +1 #GRP +2 #A255 (A255) +2 #A10 (A10) +2 #B10 (B10) +2 #U10 (U10) +2 #N10 (N10) +2 #P10 (P10) +2 #I4 (I4) +2 #F8 (F8) +2 #CV (C) +2 #D (D) +2 #L (L) +2 #T (T) +END-DEFINE + +#ASSIGNED := AVER(#N10) +#ASSIGNED := AVER(#P10) +#ASSIGNED := AVER(#I4) +#ASSIGNED := AVER(#F8) + +#ASSIGNED := NAVER(#N10) +#ASSIGNED := NAVER(#P10) +#ASSIGNED := NAVER(#I4) +#ASSIGNED := NAVER(#F8) + +#ASSIGNED := COUNT(#N10) +#ASSIGNED := COUNT(#P10) +#ASSIGNED := COUNT(#I4) +#ASSIGNED := COUNT(#F8) + +#ASSIGNED := NCOUNT(#N10) +#ASSIGNED := NCOUNT(#P10) +#ASSIGNED := NCOUNT(#I4) +#ASSIGNED := NCOUNT(#F8) + +#ASSIGNED := MAX(#N10) +#ASSIGNED := MAX(#P10) +#ASSIGNED := MAX(#I4) +#ASSIGNED := MAX(#F8) + +#ASSIGNED := MIN(#A10) +#ASSIGNED := MIN(#N10) +#ASSIGNED := MIN(#P10) +#ASSIGNED := MIN(#I4) +#ASSIGNED := MIN(#F8) +#ASSIGNED := MIN(#CV) +#ASSIGNED := MIN(#D) +#ASSIGNED := MIN(#T) + +#ASSIGNED := NMIN(#N10) +#ASSIGNED := NMIN(#P10) +#ASSIGNED := NMIN(#I4) +#ASSIGNED := NMIN(#F8) + +#ASSIGNED := OLD(#A10) +#ASSIGNED := OLD(#N10) +#ASSIGNED := OLD(#P10) +#ASSIGNED := OLD(#I4) +#ASSIGNED := OLD(#F8) +#ASSIGNED := OLD(#CV) +#ASSIGNED := OLD(#D) +#ASSIGNED := OLD(#T) + +#ASSIGNED := SUM(#N10) +#ASSIGNED := SUM(#P10) +#ASSIGNED := SUM(#I4) +#ASSIGNED := SUM(#F8) + +#ASSIGNED := TOTAL(#N10) +#ASSIGNED := TOTAL(#P10) +#ASSIGNED := TOTAL(#I4) +#ASSIGNED := TOTAL(#F8) + +#ASSIGNED := ABS(#N10) +#ASSIGNED := ATN(#N10) +#ASSIGNED := COS(#N10) +#ASSIGNED := EXP(#N10) +#ASSIGNED := FRAC(#N10) +#ASSIGNED := INT(#N10) +#ASSIGNED := LOG(#N10) +#ASSIGNED := SGN(#N10) +#ASSIGNED := SIN(#N10) +#ASSIGNED := SQRT(#N10) +#ASSIGNED := TAN(#N10) + +#ASSIGNED := ABS(#P10) +#ASSIGNED := ATN(#P10) +#ASSIGNED := COS(#P10) +#ASSIGNED := EXP(#P10) +#ASSIGNED := FRAC(#P10) +#ASSIGNED := INT(#P10) +#ASSIGNED := LOG(#P10) +#ASSIGNED := SGN(#P10) +#ASSIGNED := SIN(#P10) +#ASSIGNED := SQRT(#P10) +#ASSIGNED := TAN(#P10) + +#ASSIGNED := ABS(#I4) +#ASSIGNED := ATN(#I4) +#ASSIGNED := COS(#I4) +#ASSIGNED := EXP(#I4) +#ASSIGNED := FRAC(#I4) +#ASSIGNED := INT(#I4) +#ASSIGNED := LOG(#I4) +#ASSIGNED := SGN(#I4) +#ASSIGNED := SIN(#I4) +#ASSIGNED := SQRT(#I4) +#ASSIGNED := TAN(#I4) + +#ASSIGNED := ABS(#F8) +#ASSIGNED := ATN(#F8) +#ASSIGNED := COS(#F8) +#ASSIGNED := EXP(#F8) +#ASSIGNED := FRAC(#F8) +#ASSIGNED := INT(#F8) +#ASSIGNED := LOG(#F8) +#ASSIGNED := SGN(#F8) +#ASSIGNED := SIN(#F8) +#ASSIGNED := SQRT(#F8) +#ASSIGNED := TAN(#F8) + +#ASSIGNED := SORTKEY(#A10) +#ASSIGNED := VAL(#A10) +#ASSIGNED := VAL(#U10) +#ASSIGNED := VAL('123') + +#ASSIGNED := COUNT('Hey!') /* !{D:ERROR:NPP037} +#ASSIGNED := COUNT(#GRP) /* !{D:ERROR:NPP037} +#ASSIGNED := MAX('Hey!') /* !{D:ERROR:NPP037} +#ASSIGNED := MAX(#GRP) /* !{D:ERROR:NPP037} +#ASSIGNED := MIN('Hey!') /* !{D:ERROR:NPP037} +#ASSIGNED := NMIN(#GRP) /* !{D:ERROR:NPP037} +#ASSIGNED := NMIN('Hey!') /* !{D:ERROR:NPP037} +#ASSIGNED := NMIN(#GRP) /* !{D:ERROR:NPP037} +#ASSIGNED := OLD('Hey!') /* !{D:ERROR:NPP037} +#ASSIGNED := OLD(#GRP) /* !{D:ERROR:NPP037} +#ASSIGNED := SUM(#A10) /* !{D:ERROR:NPP037} +#ASSIGNED := SUM(#B10) /* !{D:ERROR:NPP037} +#ASSIGNED := SUM(#U10) /* !{D:ERROR:NPP037} +#ASSIGNED := VAL(#N10) /* !{D:ERROR:NPP037} +#ASSIGNED := SORTKEY(#N10) /* !{D:ERROR:NPP037} +#ASSIGNED := SORTKEY(#U10) /* !{D:ERROR:NPP037} +#ASSIGNED := SORTKEY(#A255) /* !{D:ERROR:NPP037} +#ASSIGNED := SORTKEY(#ASSIGNED) /* !{D:ERROR:NPP037} + +END