From 583b007748d6729f6cfbae839bde9a60bd712d8c Mon Sep 17 00:00:00 2001 From: Markus Amshove Date: Wed, 10 May 2023 19:10:31 +0200 Subject: [PATCH] Typecheck parameter to *LENGTH --- .../amshove/natparse/parsing/TypeChecker.java | 34 +++++++++++++++++-- .../typing/lengthParameterMustBeDynamic | 20 +++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/lengthParameterMustBeDynamic 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 4bad07699..d2822b280 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 @@ -5,9 +5,7 @@ import org.amshove.natparse.ReadOnlyList; import org.amshove.natparse.lexing.SyntaxKind; import org.amshove.natparse.natural.*; -import org.amshove.natparse.natural.builtin.BuiltInFunctionTable; -import org.amshove.natparse.natural.builtin.IBuiltinFunctionDefinition; -import org.amshove.natparse.natural.builtin.SystemVariableDefinition; +import org.amshove.natparse.natural.builtin.*; import org.amshove.natparse.natural.conditionals.ISpecifiedCriteriaNode; import java.util.ArrayList; @@ -79,6 +77,36 @@ private void checkNode(ISyntaxNode node) { checkVariableReference(variableReference); } + + if (node instanceof ISystemFunctionNode sysFuncNode) + { + checkSystemFunctionParameter(sysFuncNode); + } + } + + private void checkSystemFunctionParameter(ISystemFunctionNode sysFuncNode) + { + if (sysFuncNode.systemFunction() == SyntaxKind.SV_LENGTH) + { + for (var parameter : sysFuncNode.parameter()) + { + var type = inferDataType(parameter); + if (type == null) + { + continue; + } + + if (type.format() != DataFormat.ALPHANUMERIC && type.format() != DataFormat.UNICODE && type.format() != DataFormat.BINARY) + { + report(ParserErrors.typeMismatch("Parameter to *LENGTH must be of type A, B or U", parameter)); + } + + if (!type.hasDynamicLength()) + { + report(ParserErrors.typeMismatch("Parameter to *LENGTH must have dynamic length (e.g. A DYNAMIC)", parameter)); + } + } + } } private void checkDecideOnBranches(IDecideOnNode decideOn) diff --git a/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/lengthParameterMustBeDynamic b/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/lengthParameterMustBeDynamic new file mode 100644 index 000000000..f352a01a8 --- /dev/null +++ b/libs/natparse/src/test/resources/org/amshove/natparse/parsing/typing/lengthParameterMustBeDynamic @@ -0,0 +1,20 @@ +DEFINE DATA LOCAL +1 #ADYN (A) DYNAMIC +1 #BDYN (B) DYNAMIC +1 #UDYN (U) DYNAMIC +1 #A10 (A10) +1 #B10 (B10) +1 #U10 (U10) +1 #N10 (N10) +1 #I (I4) +END-DEFINE + +#I := *LENGTH(#ADYN) +#I := *LENGTH(#BDYN) +#I := *LENGTH(#UDYN) +#I := *LENGTH(#A10) /* !{D:ERROR:NPP037} +#I := *LENGTH(#B10) /* !{D:ERROR:NPP037} +#I := *LENGTH(#U10) /* !{D:ERROR:NPP037} +#I := *LENGTH(#N10) /* !{D:ERROR:NPP037} + +END