cover image
< Home
Miscellany

How to Automatically Convert COBOL to Go

Although COBOL can be considered a legacy language, there are still billions of lines of COBOL in production. Modernizing these systems which are costly to run and maintain is a challenge. One solution to this issue is a COBOL to Go transpiler that I want to present in this article.

COBOL

COBOL first appeared in 1959 and is a compiled language designed for business use. Today, mainly big financial institutions and government agencies have systems running COBOL in production. It is deployed often on mainframe computers, for example the Z Mainframe running z/OS by IBM. It is a sizable market because roughly 10,000 mainframe computers operate worldwide.

Although object-oriented features are now also available, COBOL is mainly a procedural and imperative language.

This is a simple hello word program in COBOL:

hello.cob

* Sample COBOL program
IDENTIFICATION DIVISION.
PROGRAM-ID. hello.
PROCEDURE DIVISION.
     DISPLAY "Hello, world!".
     STOP RUN.

You can try it out on your own computer, for example with GnuCOBOL by running the following compile command:

$ cobc -x hello.cob
$ ./hello

Go

Go is a statically typed, compiled high-level programming language designed at Google by Robert Griesemer, Rob Pike, and Ken Thompson. Its advantages are the low entry barrier for new developers and that it is a compiled language with fast execution.

Thus, it is a good choice when trying to modernize legacy COBOL applications. The Go source code is easy to understand even for programmers new to Go.

That is an advantage because the market for COBOL software developers is challenging, as I describe in the next section.

Market for COBOL Programmers

Many big companies who have running systems in COBOL struggle in attracting programmers who can maintain these systems. The average age of COBOL software developers is high and there are few young developers who want to learn COBOL.

This is a risk for the companies who have many billions of lines of COBOL in production. That is why a possible migration solution like COBOL-to-Go from Enno Richter comes in handy.

COBOL-to-Go Converter

The senior COBOL programmer Enno Richter with many decades (50 years) of experience in COBOL programming developed a COBOL to Go transpiler called COBOL-to-Go. The transpiler evolved from an older RPG-to-COBOL project. It supports the COBOL-85 standard, but features of newer COBOL standards can be added on demand.

One of its advantages is that the resulting Go code is easy to read and clearly structured. There is no runtime system necessary and thus the resulting Go code remains independent from the COBOL-to-Go system. Go compiles to many operating systems and thus the COBOL program can run on potentially many operating systems.

All rights of the resulting Go code remain with the COBOL code copyright holders.

There are alternative COBOL transpilers, like a COBOL to Java transpiler in the market, but Enno Richter claims the results of his Go transpiler are easier to understand and maintain.

Example Code

The following snippet shows the COBOL code on the left hand side and the resulting transpiled Go code on the right hand side. You might need to scroll horizontally to see the resulting Go Code:

*                                                                      :00190:  // 00190:      *                                                                                                                                                                                
    *----------------------------------------------------------------*     :00191:  // 00191:      *----------------------------------------------------------------                                                                                                                
    **------* *-----------------------------------------------------**     :00192:  // 00192:      **------* *-----------------------------------------------------*                                                                                                                
    **  30  * *                     P R O G R A M M A B L A U F     **     :00193:  // 00193:      **  30  * *                     P R O G R A M M A B L A U F     *                                                                                                                
    **------* *-----------------------------------------------------**     :00194:  // 00194:      **------* *-----------------------------------------------------*                                                                                                                
     PROCEDURE DIVISION.                                                   :00195:  
    **---------------------------------------------------------------*     :00196:  // 00196:      **---------------------------------------------------------------                                                                                                                
    **  V e r a r b e i t u n g                                      *     :00197:  // 00197:      **  V e r a r b e i t u n g                                                                                                                                                      
    **---------------------------------------------------------------*     :00198:  // 00198:      **---------------------------------------------------------------                                                                                                                
         DISPLAY "Test_02400_START --------".                              :00199:  erse.DISlx(&DIS, "Test_02400_START --------") // COBZEI:00199      
                                                                                    ersestr1 = erse.DISout(fDISPLAY, &DIS, " ") // COBZEI:00199      
    *                                                                      :00200:  // 00200:      *                                                                                                                                                                                
    *                                                                      :00201:  // 00201:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00202:  // 00202:      **-----------------------------------------------------------*                                                                                                                   
    **  IF  LITERAL --- NUMERISCH  (Struktur)                    *         :00203:  // 00203:      **  IF  LITERAL --- NUMERISCH  (Struktur)                    *                                                                                                                   
    **-----------------------------------------------------------*         :00204:  // 00204:      **-----------------------------------------------------------*                                                                                                                   
    *    IF 12 > BBB-8                                                     :00205:  // 00205:      *    IF 12 > BBB-8                                                                                                                                                               
    *       MOVE SPACE TO BBB-1                                            :00206:  // 00206:      *       MOVE SPACE TO BBB-1                                                                                                                                                      
    *    END-IF.                                                           :00207:  // 00207:      *    END-IF.                                                                                                                                                                     
    *                                                                      :00208:  // 00208:      *                                                                                                                                                                                
    *                                                                      :00209:  // 00209:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00210:  // 00210:      **-----------------------------------------------------------*                                                                                                                   
    **  IF  NUMERISCH  (Struktur) --- LITERAL                    *         :00211:  // 00211:      **  IF  NUMERISCH  (Struktur) --- LITERAL                    *                                                                                                                   
    **-----------------------------------------------------------*         :00212:  // 00212:      **-----------------------------------------------------------*                                                                                                                   
    *    IF BBB-8 > 12                                                     :00213:  // 00213:      *    IF BBB-8 > 12                                                                                                                                                               
    *       MOVE SPACE TO BBB-1                                            :00214:  // 00214:      *       MOVE SPACE TO BBB-1                                                                                                                                                      
    *    END-IF.                                                           :00215:  // 00215:      *    END-IF.                                                                                                                                                                     
    *                                                                      :00216:  // 00216:      *                                                                                                                                                                                
    *                                                                      :00217:  // 00217:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00218:  // 00218:      **-----------------------------------------------------------*                                                                                                                   
    **  IF LITERAL --- NUMERISCH  (Nativ)                        *         :00219:  // 00219:      **  IF LITERAL --- NUMERISCH  (Nativ)                        *                                                                                                                   
    **-----------------------------------------------------------*         :00220:  // 00220:      **-----------------------------------------------------------*                                                                                                                   
    *    IF 12 > Z3                                                        :00221:  // 00221:      *    IF 12 > Z3                                                                                                                                                                  
    *       MOVE SPACE TO BBB-1                                            :00222:  // 00222:      *       MOVE SPACE TO BBB-1                                                                                                                                                      
    *    END-IF.                                                           :00223:  // 00223:      *    END-IF.                                                                                                                                                                     
    *                                                                      :00224:  // 00224:      *                                                                                                                                                                                
    *                                                                      :00225:  // 00225:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00226:  // 00226:      **-----------------------------------------------------------*                                                                                                                   
    **  IF NUMERISCH (Nativ) --- LITERAL                         *         :00227:  // 00227:      **  IF NUMERISCH (Nativ) --- LITERAL                         *                                                                                                                   
    **-----------------------------------------------------------*         :00228:  // 00228:      **-----------------------------------------------------------*                                                                                                                   
    *    IF Z3 > 12                                                        :00229:  // 00229:      *    IF Z3 > 12                                                                                                                                                                  
    *       MOVE SPACE TO BBB-1                                            :00230:  // 00230:      *       MOVE SPACE TO BBB-1                                                                                                                                                      
    *    END-IF.                                                           :00231:  // 00231:      *    END-IF.                                                                                                                                                                     
    *                                                                      :00232:  // 00232:      *                                                                                                                                                                                
    *                                                                      :00233:  // 00233:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00234:  // 00234:      **-----------------------------------------------------------*                                                                                                                   
    **  IF  NUMERISCH (Struktur) ---- NUMERISCH  (Struktur)      *         :00235:  // 00235:      **  IF  NUMERISCH (Struktur) ---- NUMERISCH  (Struktur)      *                                                                                                                   
    **-----------------------------------------------------------*         :00236:  // 00236:      **-----------------------------------------------------------*                                                                                                                   
         IF BBB_8 > HHH                                                    :00237:  if erse.IFNCVCV(&BBB_8_cv, ">", &HHH_cv) {      
            MOVE SPACE TO BBB_1                                            :00238:  erse.MVACVLI(&BBB_1_cv,"SPACE") // COBZEI:00238      
         END-IF.                                                           :00239:  }   // ENDIF      
    *                                                                      :00240:  // 00240:      *                                                                                                                                                                                
    *                                                                      :00241:  // 00241:      *                                                                                                                                                                                
    **-----------------------------------------------------------*         :00242:  // 00242:      **-----------------------------------------------------------*                                                                                                                   
    **  P R O G R A M M - E N D E                                *         :00243:  // 00243:      **  P R O G R A M M - E N D E                                *                                                                                                                   
    **-----------------------------------------------------------*         :00244:  // 00244:      **-----------------------------------------------------------*                                                                                                                   
         DISPLAY "Test_02400 ENDE  -------------".                         :00245:  erse.DISlx(&DIS, "Test_02400 ENDE  -------------") // COBZEI:00245      
                                                                                    ersestr1 = erse.DISout(fDISPLAY, &DIS, " ") // COBZEI:00245      
         STOP RUN.                                                         :00246:  //---------------------------------------------------------------      
                                                                                    //  STOP-RUN  (Ende der  Programmlogik)      
                                                                                    //---------------------------------------------------------------      
                                                                                    os.Exit(0)      
    **--------------------------------------------------------------**     :00247:  // 00247:      **--------------------------------------------------------------*                                                                                                                
    ** Ende :                                                       **     :00248:  // 00248:      ** Ende :                                                       *                                                                                                                
    ** ~~Projekt~111COBOL~Sourcen~Test_02400.cbl       (2023-04-20  **     :00249:  // 00249:      ** //Projekt/111COBOL/Sourcen/Test_02400.cbl       (2023-04-20  *                                                                                                                
    *                                                               **     :00250:  // 00250:      *                                                               *                                                                                                                
    **--------------------------------------------------------------**     :00251:  // 00251:      **--------------------------------------------------------------*     

As you can see, the resulting Go code is easy to understand and maintainable.

Enno Richter is looking for collaboration companies who can distribute his valuable project. If you are interested, write me a message or contact Enno Richter directly.

Conclusion

With this article I hope you could see that there are solutions to the issue of a lack of COBOL programmers in the market. One such solution is the COBOL-to-Go transpiler that might be the missing piece of your COBOL migration.

References

Cover photo by Pete Linforth from Pixabay

Published

22 Jul 2024

Thomas Derflinger

Written by Thomas Derflinger

I am a visionary entrepreneur and software developer. In this blog I mainly write about web programming and related topics like IoT.