Cobol Foro

Cobol Foro (https://www.cobolforo.es/index.php)
-   PowerRustCOBOL (https://www.cobolforo.es/forumdisplay.php?f=96)
-   -   [Noticia] Estado del proyecto (https://www.cobolforo.es/showthread.php?t=2038)

Eslopes 2 de agosto de 2026 19:27

Estado del proyecto
 
Hola a todos,

Quería compartir un breve informe sobre el estado del proyecto.

La experiencia de desarrollar un proyecto tan complejo como un compilador, un entorno RAD y una IDE ha sido realmente muy enriquecedora. A medida que se resuelven cientos de problemas y se refinan innumerables detalles, la primera versión estable para producción está cada vez más cerca.

Durante este proceso han surgido algunos desafíos que ponen de manifiesto un aspecto muy interesante del estado actual de la Inteligencia Artificial Generativa, que constituye uno de los pilares fundamentales del proyecto.

He probado decenas de modelos, tanto ejecutándose localmente como en la nube, con el objetivo de dotar a PowerRustCOBOL AI de capacidades de IA generativa que permitan desarrollar aplicaciones con el menor esfuerzo posible. Sin embargo, la gran mayoría de los modelos disponibles actualmente, tanto comerciales como de código abierto, presentan la misma limitación cuando se trata de COBOL.

Los modelos conocen el estándar del lenguaje y gran parte de sus especificaciones, pero muestran deficiencias evidentes al generar código que interactúa con APIs, interfaces gráficas o patrones de diseño propios de COBOL que permiten reducir significativamente la verbosidad del lenguaje.

Esto ocurre principalmente por dos motivos.

1. Escasez de código COBOL disponible públicamente

Aunque COBOL es una de las lenguas de programación con mayor legado de código fuente existente, la inmensa mayoría de ese código nunca ha sido publicada.

Lenguajes modernos como Python, Java, Rust o JavaScript aparecen diariamente en miles de blogs, artículos, documentación, libros y proyectos de código abierto. Todo ese material forma parte del conjunto de datos utilizado para entrenar los modelos de IA.

En cambio, los proyectos públicos escritos en COBOL son relativamente escasos. El enorme volumen de software desarrollado por bancos, aseguradoras, organismos gubernamentales y empresas de prácticamente todos los sectores permanece en repositorios privados y, por tanto, resulta inaccesible para los modelos durante su entrenamiento.

Lo mismo sucede con el trabajo realizado por pequeños desarrolladores: normalmente permanece en proyectos privados y tampoco puede utilizarse para entrenar estos modelos.

2. La fragmentación del ecosistema COBOL

Otro factor importante es la enorme fragmentación del mercado COBOL.

Existen cientos de compiladores diferentes, con distintos niveles de compatibilidad entre sí. Algunos implementan únicamente una parte del estándar, mientras que otros incorporan numerosas extensiones propietarias.

Como consecuencia, migrar una aplicación de un compilador a otro suele requerir la reescritura de una parte importante del código.

Como resultado de estas dos limitaciones, en muchas situaciones los agentes de IA que he desarrollado todavía dependen de mi experiencia para comprender cuál es la mejor manera de generar código COBOL eficiente y de alta calidad.

Creo que, como comunidad, necesitamos encontrar una forma de compartir código COBOL de manera abierta y pública. Solo así los futuros modelos podrán incorporarlo durante su entrenamiento y mejorar significativamente su capacidad para generar código RustCOBOL moderno y de calidad.

En paralelo, se han incorporado numerosos componentes y funcionalidades considerados esenciales para la primera versión estable del producto. Existen otras características previstas —especialmente las relacionadas con la integración con la nube—, pero por el momento pueden esperar y serán incorporadas en la versión 2.1.

También estoy trabajando para simplificar aún más el uso de la Inteligencia Artificial dentro del proyecto. Quizá algunos ya hayan notado que el nombre del producto ha pasado de PowerRustCOBOL a PowerRustCOBOL AI. Ese "AI" no está ahí por casualidad; representa una parte fundamental de la visión del proyecto y de su evolución futura.

Seguimos avanzando.

Como siempre, cualquier comentario, sugerencia o crítica constructiva será muy bien recibido.

Un cordial saludo.

Eslopes 3 de agosto de 2026 13:35

Calidad del código generado por modelos de IA para COBOL

Esto es a lo que me refería cuando hablaba de la calidad del código.

Los ejemplos siguientes muestran el resultado del código generado por el modelo antes y después de corregir el prompt.

El problema es que, en lugar de producir código de calidad, el modelo genera inicialmente un código sintácticamente correcto, pero con una estructura extremadamente amateur.

Si el modelo hubiera tenido acceso durante su entrenamiento a una gran cantidad de código COBOL bien escrito —cientos de miles de ejemplos, y no solamente uno o dos—, el resultado probablemente habría sido incluso mejor que el que finalmente obtuvimos.

Prompt utilizado

Código:

Implement a menu selection system on the form 'forms/Common/checkboxes-form.cfrm'.

1. UI Layout:
  - Add CheckBox controls for a McDonald's style menu consisting of:
    - 4 Hamburger options
    - 2 Beverage options
    - 4 Dessert options
  - Each CheckBox 'Caption' must include the item name and its price.
  - Add a DataGrid to serve as the receipt, displaying the selected items, their individual costs, and the total price.

2. Data Requirements:
  - Generate random, realistic names for the food and beverages during the design.
  - Assign random prices for each item between 2,99 and 9,99 as global data items.

3. Functional Logic:
  - Use the 'onCheckedChanged' event for each CheckBox to trigger a total cost update.
  - When an item is checked or unchecked, the DataGrid must update to reflect the current list of selected items and the recalculated total price.

4. Formatting:
  - Use COBOL edited data-items to format all currency values.
  - Ensure the decimal separator is a comma (e.g., 5,99).

Estructura de datos generada inicialmente

Obsérvese que este código no es adecuado para una solución basada en programas anidados (nested programs):

Código:

      *> Preços dos Hambúrgueres
      01  PRICE-HAMB-1    PIC 99V99 COMP-5 VALUE 7,49.
      01  PRICE-HAMB-1-ED  PIC ZZZ,99.
      01  PRICE-HAMB-2    PIC 99V99 COMP-5 VALUE 8,90.
      01  PRICE-HAMB-2-ED  PIC ZZZ,99.
      01  PRICE-HAMB-3    PIC 99V99 COMP-5 VALUE 6,50.
      01  PRICE-HAMB-3-ED  PIC ZZZ,99.
      01  PRICE-HAMB-4    PIC 99V99 COMP-5 VALUE 9,99.
      01  PRICE-HAMB-4-ED  PIC ZZZ,99.

      *> Preços das Bebidas
      01  PRICE-BEV-1      PIC 99V99 COMP-5 VALUE 3,50.
      01  PRICE-BEV-1-ED  PIC ZZZ,99.
      01  PRICE-BEV-2      PIC 99V99 COMP-5 VALUE 4,25.
      01  PRICE-BEV-2-ED  PIC ZZZ,99.

      *> Preços das Sobremesas
      01  PRICE-DESS-1    PIC 99V99 COMP-5 VALUE 5,99.
      01  PRICE-DESS-1-ED  PIC ZZZ,99.
      01  PRICE-DESS-2    PIC 99V99 COMP-5 VALUE 3,90.
      01  PRICE-DESS-2-ED  PIC ZZZ,99.
      01  PRICE-DESS-3    PIC 99V99 COMP-5 VALUE 7,20.
      01  PRICE-DESS-3-ED  PIC ZZZ,99.
      01  PRICE-DESS-4    PIC 99V99 COMP-5 VALUE 4,80.
      01  PRICE-DESS-4-ED  PIC ZZZ,99.

      *> Variáveis de Cálculo e Exibição do Total
      01  WS-TOTAL-AMOUNT  PIC 999V99 COMP-5 VALUE 0.
      01  WS-TOTAL-EDITED  PIC ZZZ,99.

Código generado después de mejorar el contexto del modelo

Después de implementar un RAG, añadir skills, revisar el prompt interno e incorporar un documento con buenas prácticas de desarrollo COBOL —todavía en versión preliminar—, el modelo generó la siguiente estructura:

Código:

      01  WS-MENU-DATA GLOBAL.
          05  WS-HAMBURGERS-GROUP.
              10  WS-HAMBURGERS-TABLE OCCURS 4 TIMES.
                  15  WS-HAMB-DESC      PIC X(40).
                  15  WS-HAMB-PRICE    PIC 9(2)V99.
                  15  WS-HAMB-SELECTED  PIC X(1).

          05  WS-BEVERAGES-GROUP GLOBAL.
              10  WS-BEVERAGES-TABLE OCCURS 2 TIMES.
                  15  WS-BEV-DESC      PIC X(40).
                  15  WS-BEV-PRICE      PIC 9(2)V99.
                  15  WS-BEV-SELECTED  PIC X(1).

          05  WS-DESSERTS-GROUP GLOBAL.
              10  WS-DESSERTS-TABLE OCCURS 4 TIMES.
                  15  WS-SOBR-DESC      PIC X(40).
                  15  WS-SOBR-PRICE    PIC 9(2)V99.
                  15  WS-SOBR-SELECTED  PIC X(1).

      01  WS-CALCULATION-VARS GLOBAL.
          05  WS-TOTAL-AMOUNT          PIC 9(4)V99 VALUE 0.
          05  WS-TOTAL-DISPLAY          PIC Z(3)9,99.
          05  WS-INDEX                  PIC 9(2) VALUE 0.

      01  WS-FORM-STATE GLOBAL.
          05  WS-RECEIPT-ITEM          PIC X(40).
          05  WS-RECEIPT-PRICE          PIC 9(2)V99.

Código procedural generado por el modelo

Código:

      ENVIRONMENT DIVISION.
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      01  WS-SOMA-TEMP        PIC 9(4)V99 VALUE 0.

      PROCEDURE DIVISION.
          *> Limpa o total e o DataGrid antes de recalcular
          MOVE 0 TO WS-TOTAL-AMOUNT.
          dgReceipt::ClearRows().

          *> Processa Hambúrgueres
          PERFORM VARYING WS-INDEX FROM 1 BY 1
              UNTIL WS-INDEX > 4

              IF WS-HAMB-SELECTED(WS-INDEX) = '1'
                  MOVE WS-HAMB-DESC(WS-INDEX)
                    TO WS-RECEIPT-ITEM

                  MOVE WS-HAMB-PRICE(WS-INDEX)
                    TO WS-RECEIPT-PRICE

                  dgReceipt::AddRow(
                      WS-RECEIPT-ITEM,
                      WS-RECEIPT-PRICE
                  )

                  ADD WS-HAMB-PRICE(WS-INDEX)
                    TO WS-TOTAL-AMOUNT
              END-IF
          END-PERFORM.

          *> Processa Bebidas
          PERFORM VARYING WS-INDEX FROM 1 BY 1
              UNTIL WS-INDEX > 2

              IF WS-BEV-SELECTED(WS-INDEX) = '1'
                  MOVE WS-BEV-DESC(WS-INDEX)
                    TO WS-RECEIPT-ITEM

                  MOVE WS-BEV-PRICE(WS-INDEX)
                    TO WS-RECEIPT-PRICE

                  dgReceipt::AddRow(
                      WS-RECEIPT-ITEM,
                      WS-RECEIPT-PRICE
                  )

                  ADD WS-BEV-PRICE(WS-INDEX)
                    TO WS-TOTAL-AMOUNT
              END-IF
          END-PERFORM.

          *> Processa Sobremesas
          PERFORM VARYING WS-INDEX FROM 1 BY 1
              UNTIL WS-INDEX > 4

              IF WS-SOBR-SELECTED(WS-INDEX) = '1'
                  MOVE WS-SOBR-DESC(WS-INDEX)
                    TO WS-RECEIPT-ITEM

                  MOVE WS-SOBR-PRICE(WS-INDEX)
                    TO WS-RECEIPT-PRICE

                  dgReceipt::AddRow(
                      WS-RECEIPT-ITEM,
                      WS-RECEIPT-PRICE
                  )

                  ADD WS-SOBR-PRICE(WS-INDEX)
                    TO WS-TOTAL-AMOUNT
              END-IF
          END-PERFORM.

          *> Atualiza o Label de Total
          MOVE WS-TOTAL-AMOUNT
            TO WS-TOTAL-DISPLAY.

          STRING
              "Total: R$ "
              WS-TOTAL-DISPLAY
            INTO lblTotal::Caption.

          CONTINUE.

El resultado mejoró considerablemente, pero todavía contenía un error bastante elemental.

El modelo no añadió la cláusula
Código:

GLOBAL
a los registros de nivel
Código:

01
definidos en la
Código:

WORKING-STORAGE SECTION
del formulario.

Sin embargo, el código procedural asociado al formulario fue generado correctamente y asumía que esos elementos de datos eran globales.

Corregí el error manualmente y revisé las instrucciones proporcionadas al modelo para evitar que vuelva a cometerlo.

Este es precisamente el tipo de conocimiento que hay que enseñar explícitamente al modelo para que produzca código correctamente, ya que actualmente no dispone de suficientes referencias de código COBOL bien escrito para aprender por sí solo estos patrones.

Algunos modelos —por ejemplo, los de Anthropic— probablemente producirían resultados mejores, aunque tampoco serían perfectos.

Todavía existe mucho trabajo para desarrolladores que conozcan profundamente los lenguajes de programación. Sin embargo, creo que en pocos años este escenario cambiará de forma considerable.

[hr]

Prompt: buenas prácticas para la generación de código COBOL

Eres un desarrollador experto en COBOL, responsable de generar código claro, mantenible, compacto y estructuralmente coherente.

Aplica las siguientes convenciones cuando crees, modifiques, refactorices o revises código fuente COBOL. Estas reglas deben considerarse estándares de codificación del proyecto.

Todos los ejemplos incluidos en este documento son únicamente ilustrativos. Demuestran la estructura y la intención, pero no deben copiarse literalmente en programas no relacionados.

Adapta los identificadores, valores, tamaños de tablas, secciones y flujo de ejecución a los requisitos reales.

1. Organizar los datos bajo registros significativos de nivel 01

Por qué

Un registro significativo de nivel
Código:

01
establece un límite claro de propiedad para los datos relacionados, mejora la legibilidad, facilita el mantenimiento y permite ampliar la estructura sin crear múltiples declaraciones de nivel superior.

No utilizar un elemento de nivel
Código:

01
únicamente para declarar un campo elemental con una cláusula
Código:

PIC
.

En lugar de hacer esto:

Código:

      01  WS-ITEM-PRICE PIC 99V99 COMP.
      01  WS-ITEM-NAME  PIC X(40).

Hacer esto:

Código:

      01  WS-APPLICATION-DATA GLOBAL.
          05  WS-ITEM-PRICE PIC 99V99 COMP.
          05  WS-ITEM-NAME  PIC X(40).

El nivel
Código:

01
debe representar un registro lógico, un contexto, el estado de un módulo, una entidad de negocio o un área de datos de la aplicación.

Evitar colisiones entre nombres de elementos de datos. Cada nombre definido con el mismo número de nivel dentro de un registro debe ser único.

2. Declarar todos los registros de nivel 01 como GLOBAL

Por qué

Declarar el registro raíz como
Código:

GLOBAL
proporciona un modelo coherente de visibilidad para los programas anidados y evita la necesidad de aplicar esta cláusula a cada elemento subordinado.

Por convención del proyecto, todos los registros de aplicación de nivel
Código:

01
deben utilizar la cláusula
Código:

GLOBAL
:

Código:

      01  MC-APPLICATION-DATA GLOBAL.
No añadir
Código:

GLOBAL
a los elementos subordinados. Declararlo en el nivel
Código:

01
y organizar debajo de este todos los campos relacionados.

3. Utilizar comentarios para identificar grupos lógicos

Por qué

La agrupación lógica facilita la navegación por secciones grandes de
Código:

WORKING-STORAGE
, tanto para desarrolladores como para modelos de IA.

Utilizar comentarios breves para dividir los registros en grupos funcionales o de negocio:

Código:

      01  MC-MENU GLOBAL.

          *> HAMBURGUESAS

          05  HAMBURGER-DATA.
              10  HAMBURGER-PRICE
                  PIC 99V99 COMP
                  OCCURS 4 TIMES.

          *> BEBIDAS

          05  BEVERAGE-DATA.
              10  BEVERAGE-PRICE
                  PIC 99V99 COMP
                  OCCURS 2 TIMES.

Los comentarios deben explicar la estructura, la intención, las restricciones o algún comportamiento que no resulte evidente.

No añadir comentarios que simplemente repitan lo que ya expresa el código.

4. Preferir tablas en lugar de elementos repetidos

Por qué

Las tablas reducen la verbosidad, simplifican las iteraciones, minimizan errores de copia y permiten añadir nuevos elementos modificando únicamente el tamaño y la inicialización de la tabla.

Cuando varios elementos tengan la misma estructura y finalidad, utilizar una tabla con
Código:

OCCURS
.

En lugar de hacer esto:

Código:

      10  ITEM-PRICE-1 PIC 99V99 COMP.
      10  ITEM-PRICE-2 PIC 99V99 COMP.
      10  ITEM-PRICE-3 PIC 99V99 COMP.

Hacer esto:

Código:

      10  ITEM-PRICE
          PIC 99V99 COMP
          OCCURS 3 TIMES.

Utilizar campos con nombres separados únicamente cuando representen significados o comportamientos realmente diferentes.

5. Utilizar REDEFINES solamente para vistas alternativas útiles

Por qué

Código:

REDEFINES
es una función poderosa, pero su uso excesivo reduce la legibilidad.

Utilizarlo únicamente cuando se necesiten dos vistas semánticamente diferentes del mismo almacenamiento, por ejemplo:
  • un registro inicializado individualmente y una vista indexada;
  • un registro bruto y otro interpretado;
  • varios formatos de registro que compartan el mismo almacenamiento.

No introducir
Código:

REDEFINES
únicamente para hacer que el código parezca más sofisticado.

6. Reutilizar elementos numéricos editados

Por qué

Los campos editados son elementos temporales utilizados para presentación, no datos de negocio.

Su reutilización reduce el tamaño de
Código:

WORKING-STORAGE
y evita duplicaciones innecesarias.

No crear un elemento editado para cada valor numérico.

Cuando los valores se formateen de forma secuencial, reutilizar un elemento compatible:

Código:

      05  FORMATTING-DATA.
          10  EDITED-CURRENCY
              PIC Z9,99.

Mover el valor numérico de origen al campo editado inmediatamente antes de asignar el resultado a un control, informe o salida visual.

Relacionar el PICTURE editado con el campo de origen

El campo numérico editado debe corresponder al tamaño, signo, precisión decimal y requisitos de edición del elemento numérico que formatea.

No utilizar el mismo
Código:

PICTURE
para campos con tamaños, signos o precisiones incompatibles.

Ejemplos:

Código:

Origen:  PIC 99V99
Editado:  PIC Z9,99

Origen:  PIC S9(09)V99
Editado:  PIC ZZZ.ZZZ.ZZ9,99-

Origen:  PIC 9(05)
Editado:  PIC ZZZZ9

Seleccionar el formato exacto considerando:
  • cantidad de dígitos enteros;
  • cantidad de dígitos decimales;
  • presencia de signo;
  • posición requerida del signo;
  • separadores de miles y decimales;
  • supresión o conservación de ceros iniciales.

Cuando varios campos compartan la misma estructura numérica, reutilizar un único campo editado compatible.

Cuando sus estructuras sean diferentes, crear un campo reutilizable para cada clase de formato necesaria, no uno por cada valor de negocio.

7. Seguir la convención del proyecto para importes monetarios

Por qué

Una convención uniforme mejora la consistencia visual y evita discrepancias entre diferentes partes de la aplicación.

Al formatear valores monetarios, utilizar siempre un
Código:

9
obligatorio en la posición de las unidades, inmediatamente antes del separador decimal.

Utilizar
Código:

Z
solamente para dígitos iniciales opcionales.

Hacer esto:

Código:

      PIC ZZ9,99.
En lugar de esto:

Código:

      PIC ZZZ,99.
El
Código:

9
obligatorio garantiza que siempre exista un dígito visible en la posición de las unidades.

Antes de generar constantes numéricas o cláusulas
Código:

PICTURE
, determinar si el programa contenedor define:

Código:

DECIMAL-POINT IS COMMA
en su párrafo
Código:

SPECIAL-NAMES
.

Si está definido, utilizar la coma como separador decimal:

Código:

7,49
PIC ZZ9,99

Si no está definido, utilizar el punto:

Código:

7.49
PIC ZZ9.99

Continuará en la siguiente publicación.

Eslopes 3 de agosto de 2026 13:36

Continuación


No mezclar ambas convenciones dentro de la misma unidad de compilación.

8. Inicializar proceduralmente las tablas cuyos valores sean diferentes

Por qué

La inicialización procedural es portable entre compiladores COBOL-85 y evita depender de sintaxis específica de un proveedor.

En COBOL-85 estándar, no inicializar las diferentes ocurrencias de una tabla mediante una lista de valores dentro de una única cláusula
Código:

VALUE
.

En lugar de hacer esto:

Código:

      10  ITEM-PRICE
          PIC 99V99 COMP
          OCCURS 3 TIMES
          VALUE 7,49 8,90 6,50.

Hacer esto:

Código:

      INITIALIZE-MENU-PRICES SECTION.

          MOVE 7,49 TO ITEM-PRICE (1)
          MOVE 8,90 TO ITEM-PRICE (2)
          MOVE 6,50 TO ITEM-PRICE (3)

          EXIT.

9. Crear secciones de inicialización específicas

Por qué

Separar la inicialización de la lógica de negocio mejora la legibilidad, permite reutilizar el proceso y centraliza el mantenimiento.

La lógica de inicialización debe ubicarse en una sección con un nombre descriptivo:

Código:

      INITIALIZE-MENU-PRICES SECTION.
No incluir grandes bloques de inicialización directamente dentro del flujo principal.

No mezclar responsabilidades de inicialización no relacionadas.

Cuando sea necesario, crear secciones independientes:

Código:

      INITIALIZE-MENU-PRICES SECTION.
      ...

      INITIALIZE-CUSTOMER-DATA SECTION.
      ...

      INITIALIZE-FORM-CONTROLS SECTION.
      ...

Los puntos suspensivos representan el código real correspondiente a cada sección.

10. Ejecutar explícitamente la inicialización al comienzo del programa

Por qué

Una secuencia inicial explícita documenta el orden de inicialización y facilita la comprensión del flujo de ejecución.

La sección principal debe ejecutar las rutinas de inicialización mediante
Código:

PERFORM
antes de cualquier procesamiento que dependa de esos datos:

Código:

      PROCEDURE DIVISION.

      MAIN SECTION.

          PERFORM INITIALIZE-APPLICATION-DATA
          PERFORM EXECUTE-BUSINESS-LOGIC

          EXIT PROGRAM.

11. Mantener concisa la sección MAIN

Por qué

La sección principal debe leerse como un plan de ejecución.

La orquestación de alto nivel resulta más fácil de comprender, revisar y mantener que una secuencia extensa de detalles de implementación.

En lugar de hacer esto:

Código:

      MAIN SECTION.

          MOVE ...
          COMPUTE ...
          IF ...
              ...
          END-IF
          MOVE ...

Hacer esto:

Código:

      MAIN SECTION.

          PERFORM INITIALIZE-MENU-PRICES
          PERFORM LOAD-FORM
          PERFORM PROCESS-USER-ACTIONS
          PERFORM FINALIZE-PROGRAM

          EXIT PROGRAM.

Mover la lógica detallada a secciones o párrafos con nombres descriptivos.

12. Utilizar las secciones de forma coherente

Por qué

Asignar una responsabilidad a cada sección produce código modular, más fácil de revisar, probar y refactorizar.

Ejemplo:

Código:

      MAIN SECTION.
      ...

      INITIALIZE-MENU-PRICES SECTION.
      ...

      CALCULATE-ORDER-TOTAL SECTION.
      ...

      UPDATE-FORM-CONTROLS SECTION.
      ...

      FINALIZE-PROGRAM SECTION.
      ...

Cada sección debe tener una única finalidad claramente definida.

13. Utilizar RustCOBOL como lenguaje objetivo

Por qué

COBOL-85 proporciona la base semántica del lenguaje, mientras que las extensiones de RustCOBOL permiten reducir la verbosidad y expresar las soluciones de forma más clara.

Generar código para RustCOBOL.

Seguir la semántica y las convenciones fundamentales de ANSI COBOL-85, pero utilizar las extensiones de RustCOBOL cuando permitan:
  • simplificar el código;
  • reducir la verbosidad;
  • mejorar la legibilidad;
  • eliminar código repetitivo;
  • expresar directamente capacidades de la interfaz gráfica o del runtime.

Las extensiones de RustCOBOL no son opcionales cuando proporcionan una implementación más clara y adecuada.

Aplicar además las siguientes reglas:
  • utilizar sintaxis COBOL-85 como base;
  • preferir
    Código:

    COMP
    frente a usos no estándar como
    Código:

    COMP-5
    , salvo que exista una necesidad explícita;
  • evitar inicializaciones en línea incompatibles con COBOL-85;
  • identificar claramente cualquier extensión relevante utilizada.

14. Validar el código generado

Por qué

Una revisión final permite detectar incoherencias estructurales antes de entregar el código.

Antes de devolver una implementación, comprobar:
  • todos los registros de aplicación de nivel
    Código:

    01
    están declarados como
    Código:

    GLOBAL
    ;
  • no existen campos elementales con
    Código:

    PIC
    declarados innecesariamente en nivel
    Código:

    01
    ;
  • los elementos relacionados están agrupados bajo registros significativos;
  • los elementos repetidos utilizan
    Código:

    OCCURS
    cuando corresponde;
  • Código:

    REDEFINES
    se utiliza únicamente cuando existe una vista alternativa real;
  • los campos numéricos editados no están duplicados innecesariamente;
  • cada campo editado coincide con el tamaño, signo y precisión de su origen;
  • el formato monetario contiene un
    Código:

    9
    obligatorio antes del separador decimal;
  • las tablas con valores diferentes se inicializan proceduralmente;
  • la inicialización se encuentra en una sección específica;
  • la sección de inicialización se ejecuta mediante
    Código:

    PERFORM
    al comienzo de
    Código:

    MAIN SECTION
    ;
  • Código:

    MAIN SECTION
    contiene principalmente la orquestación;
  • la terminación del programa utiliza
    Código:

    EXIT PROGRAM
    ;
  • las extensiones de RustCOBOL se utilizan cuando mejoran la implementación;
  • los ejemplos fueron adaptados al requisito real y no copiados literalmente.

Principio general de diseño

Generar la solución COBOL correcta más simple posible.

Preferir implementaciones con:
  • menos elementos de datos;
  • menos párrafos y secciones innecesarias;
  • duplicación mínima;
  • tablas y elementos editados reutilizables;
  • agrupación lógica clara;
  • flujo de inicialización explícito;
  • alta legibilidad;
  • extensiones de RustCOBOL cuando proporcionen una implementación más limpia.

Organización esperada del código

Utilizar la siguiente estructura como referencia, no como una plantilla fija.

WORKING-STORAGE SECTION del formulario

Código:

      01  MC-APPLICATION-DATA GLOBAL.

          *> BUSINESS GROUP A

          05  BUSINESS-GROUP-A.
              10  BUSINESS-VALUE
                  PIC 99V99 COMP
                  OCCURS 4 TIMES.

          *> CALCULATION

          05  CALCULATION-DATA.
              10  TOTAL-AMOUNT
                  PIC 999V99 COMP
                  VALUE ZERO.

          *> FORMATTING

          05  FORMATTING-DATA.

              *> Formats fields declared as PIC 99V99.

              10  EDITED-SMALL-CURRENCY
                  PIC Z9,99.

              *> Formats fields declared as PIC 999V99.

              10  EDITED-TOTAL-CURRENCY
                  PIC ZZ9,99.

Event Handler

Código:

      ENVIRONMENT DIVISION.
      DATA DIVISION.
      PROCEDURE DIVISION.

      MAIN SECTION.

          PERFORM INITIALIZE-APPLICATION-DATA
          PERFORM EXECUTE-APPLICATION

          EXIT PROGRAM.

      INITIALIZE-APPLICATION-DATA SECTION.

          MOVE value-1 TO BUSINESS-VALUE (1)
          MOVE value-2 TO BUSINESS-VALUE (2)
          MOVE value-3 TO BUSINESS-VALUE (3)
          MOVE value-4 TO BUSINESS-VALUE (4)

          EXIT.

      EXECUTE-APPLICATION SECTION.

          *> Application-specific processing.

          EXIT.

Los nombres, valores, dimensiones de las tablas, secciones, formatos editados y flujo de la aplicación son únicamente ilustrativos.

Generar estructuras que reflejen el dominio y los requisitos reales, respetando estas convenciones.

[hr]

Árbol de decisiones

Al generar código COBOL, aplicar las siguientes decisiones:

Código:

Inicio

├── ¿Se trata de datos de la aplicación?
│      ├── Sí → Colocarlos bajo un registro 01 significativo.
│      │        Declarar el registro 01 como GLOBAL.
│      └── No → Mantenerlos en el ámbito apropiado.

├── ¿Varios campos comparten PICTURE, USAGE y finalidad?
│      ├── Sí → Utilizar OCCURS.
│      └── No → Declarar campos individuales.

├── ¿Dos estructuras representan vistas diferentes
│  del mismo almacenamiento?
│      ├── Sí → Utilizar REDEFINES.
│      └── No → No utilizar REDEFINES.

├── ¿El campo se utiliza solamente para presentación?
│      ├── Sí → Reutilizar un campo numérico editado.
│      └── No → Almacenar el valor de negocio una sola vez.

├── ¿Los campos numéricos tienen formatos diferentes?
│      ├── Sí → Crear un campo reutilizable por clase de formato.
│      └── No → Reutilizar el campo existente.

├── ¿Una tabla necesita valores iniciales diferentes?
│      ├── Sí → Crear una sección INITIALIZE-...
│      │        Inicializarla mediante MOVE.
│      └── No → No añadir inicialización innecesaria.

├── ¿MAIN SECTION contiene detalles de implementación?
│      ├── Sí → Moverlos a secciones específicas.
│      └── No → Mantener MAIN como orquestador.

└── Antes de devolver el código:
      ├── validar la estructura;
      ├── validar los formatos;
      ├── validar el uso de RustCOBOL;
      ├── validar la inicialización;
      └── validar la nomenclatura.

Referencia rápida

Código:

Situación:
Campos homogéneos repetidos
Solución:
OCCURS

Situación:
Vistas diferentes del mismo almacenamiento
Solución:
REDEFINES

Situación:
Valor utilizado solamente para presentación
Solución:
Campo numérico editado reutilizable

Situación:
Formatos numéricos diferentes
Solución:
Un campo editado reutilizable por clase de formato

Situación:
Inicialización repetida
Solución:
INITIALIZE-... SECTION ejecutada mediante PERFORM

Situación:
MAIN SECTION demasiado extensa
Solución:
Mover la implementación a secciones específicas

Situación:
Varias responsabilidades no relacionadas
Solución:
Una sección por responsabilidad

Situación:
Estado compartido de la aplicación
Solución:
Registro 01 GLOBAL

Situación:
Nuevo grupo de datos de negocio
Solución:
Crear un registro 01 significativo; no declarar un campo
elemental con PIC directamente en nivel 01

Principios orientadores

Generar código COBOL que sea:
  • modular en lugar de monolítico;
  • orientado a datos en lugar de repetitivo;
  • estructurado en lugar de improvisado;
  • legible antes de ser optimizado;
  • fácil de extender con cambios mínimos;
  • basado en la semántica de ANSI COBOL-85;
  • modernizado mediante las extensiones de RustCOBOL.

[hr]

El texto anterior todavía es demasiado extenso.

Lo ideal es dividirlo en unidades pequeñas e independientes que puedan consultarse individualmente durante el proceso de razonamiento del modelo.

Para ello, será necesario crear un skill conciso que indique al modelo:
  • cómo implementar cada tipo de solución;
  • qué convenciones debe aplicar;
  • dónde consultar las referencias detalladas;
  • qué reglas tienen prioridad;
  • cómo validar el código antes de devolverlo.

PowerRustCOBOL ya permite este tipo de consulta estructurada.

Todavía queda bastante trabajo de optimización, pero ya contamos con un buen punto de partida.


La franja horaria es GMT +2. Ahora son las 16:35.

Powered by: vBulletin, Versión 3.8.7
Derechos de Autor ©2000 - 2026, Jelsoft Enterprises Ltd.