TypeCobolTeam / TypeCobol

TypeCobol is an Incremental Cobol parser for IBM Enterprise Cobol 6 for zOS syntax. TypeCobol is also an extension of Cobol 85 language which can then be converted to Cobol85.
Other
78 stars 26 forks source link

Missing diagnostics on MOVE FUNCTION... #1989

Open fm-117 opened 3 years ago

fm-117 commented 3 years ago

Describe the bug Some intrinsic functions are not allowed in a MOVE statement, our parser allows it but IBM compiler doesn't.

To Reproduce (Type)Cobol code that cause the bug : (if any)

       IDENTIFICATION DIVISION.
       PROGRAM-ID. Pgm1.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 data-name  PIC X(20).
       01 data-length PIC 9(3).
       PROCEDURE DIVISION.
      *OK
           MOVE FUNCTION UPPER-CASE('hello') TO DATA-NAME
           MOVE FUNCTION UPPER-CASE('hello') TO DATA-length
           MOVE LENGTH OF data-name TO data-length
           COMPUTE DATA-LENGTH = FUNCTION LENGTH('hello')
      *KO on IBM compiler
           MOVE FUNCTION LENGTH ('hello') TO data-length
           GOBACK
           .
       END PROGRAM Pgm1.

Expected behavior Our parser should create a diagnostic on MOVE FUNCTION LENGTH('hello') according to the IBM compiler behavior.

TODO:

fm-117 commented 3 years ago

This is related to the nature of functions. Cobol defines 4 types of intrinsic functions based on their return type:

And there are restrictions on how/where each types of functions can be used:

fm-117 commented 3 years ago

While most functions have a pre-determined return type, some (MIN and MAX) are overloaded and actual return type depends on argument types. Therefore, the separation between text functions and number functions can't be done during syntax check and has to be done during semantic check.

To help find whether a function is used inside or outside of an arithmetic expression, the visitor must be improved. Adding BeginExpression and EndExpression methods (based on what is done for CodeElement) would allow to track expression context.

The overload resolution mechanism would have to integrate into existing code, see inheritors of FunctionCall and BuildProfile methods.