GNU COBOL
Bueno, dijeron que no se podía hacer. En realidad, fui yo quien dijo que no se podía hacer. Ahora está hecho, y una característica de lenguaje obsoleta se volvió a implementar utilizando el método aplicado.
La pregunta dice:
Si se agrega un espacio en blanco o declaraciones adicionales (que no interrumpen el flujo del código) al código fuente, debe reflejarse en tiempo de ejecución (después de la compilación, si corresponde).
Se puede insertar cualquier cantidad de cosas antes de los tres DISPLAY
s que causan el inicio de la salida, y cualquier cosa después de los DISPLAY
s "interrumpiría el flujo del código", entonces está bien.
COBOL solía tener un TRACE
verbo (enunciado) que simplemente enumeraba los números de línea de origen a medida que se ejecutaban (sin acceso al número de línea en el programa). Aunque de uso limitado, he incluido una implementación de TRACE.
ID Division.
Program-ID. HIWHERE.
ENVIRONMENT DIVISION.
configuration section.
source-computer. TinkerToy with debugging mode.
Procedure Division.
Declaratives.
Debug-Declaratives Section.
Use For Debugging on a b
.
Debug-Declaratives-Paragraph.
Display Debug-Line "!"
.
End Declaratives
.
Main-Program Section.
DISPLAY "Perform"
Display "Hello World, from line " no advancing Perform b
display "GO TO"
Display "Hello World, from line " no advancing GO TO a
.
a.
dISPLay "Fall through"
Display "Hello World, from line " no advancing. b.
The-Last-bit-OF-the-PROGRAM.
GOBACK
.
La salida es
Perform
Hello World, from line 18!
GO TO
Hello World, from line 20!
Fall through
Hello World, from line 23!
Como una muestra del poder y la flexibilidad de escribir el lenguaje, este ejemplo utiliza mayúsculas y minúsculas y mayúsculas, todo al mismo tiempo. No importa, ya que cuando se procesa, todo se "dobla" a MAYÚSCULAS.
La única forma estándar de COBOL de obtener un número de línea de origen en el programa en ejecución, desde el programa en ejecución, es con un DEBUGGING
DECLARATIVE
. Dentro de un SECTION
, estrictamente dentro de un párrafo dentro de unSECTION
, de tal declaración tiene acceso al registro especial DEBUG-LINE
. Contiene el número de línea de origen del verbo (instrucción) que causó la transferencia del control a un nombre de procedimiento particular (párrafo o SECTION
).
Entonces, con PERFORM
, o GO TO
, o "caer" el párrafo en las declaraciones de depuración SECTION
se ejecuta.
Bien pero DISPLAY
no causa transferencia de control.
No hay problema. Ponlo en la misma línea que la transferencia de control.
Problema, ya que si "cualquier espacio en blanco adicional o declaraciones (que no interrumpan el flujo del código) se agrega al código fuente, debe reflejarse en tiempo de ejecución (después de compilar si corresponde)".
Por lo tanto, colóquelo en la misma línea pero frente a una transferencia de control, divida el contenido de la misma DISPLAY
en dos partes (recuerde: "En este contexto, queremos que se muestre el primer número de línea de la instrucción que genera la cadena" ) y muestra la primera parte antes de la transferencia de control, y la segunda parte, desde DEBUG-LINE
, una vez dentro del procedimiento de depuración.
El último truco difícil es para la "caída" (los "procedimientos" pueden ser PERFORM
editados, pueden ser el objetivo de un GO TO
, o pueden ingresarse simplemente siendo la siguiente línea). En este caso, pon elDISPLAY
en la línea que define el procedimiento, pero delante de la definición .
Los nombres de los "procedimientos" ( a
y b
) se han acortado severamente para permitir que quepan en la misma línea de origen que elDISPLAY
. Estrictamente, un nombre de procedimiento COBOL debe comenzar en algún lugar de la columna ocho a la columna 11. Sin embargo, la sintaxis es, en estos días, mucho más relajada al respecto. En la medida en que pueda definir un nombre de procedimiento en la misma línea que algún código. Incluso incrustado en el código. Se requiere cuidado y, ocasionalmente, una parada completa.
En el PROCEDURE DIVISION
cada punto completo que se muestra se requiere, y no más.
Compilar:
cobc -x -g hiwhere.cbl
Para ejecutar (linux):
COB_SET_DEBUG=Y ./hiwhere
Finalmente, el retorno de TRACE (sin READY / RESET).
ID Division.
Program-ID. tRacE.
ENVIRONMENT DIVISION.
configuration section.
source-computer. TinkerToy with debugging mode.
Procedure Division.
Declaratives.
Debug-Declaratives Section.
Use For Debugging on a
.
Debug-Declaratives-Paragraph.
Display Debug-Line
.
End Declaratives
.
Main-Program Section.
* Just append "perform a" to a single-line statement.
DISPLAY "1" . perform a
Display "2" . perform a
display "3" . perform a
* Or prepend "perform a." for a multi-line statement, or a
* statement which won't "come back".
perform a. GOBACK
.
a.
CONTINUE
.
Salida es:
1
17
2
18
3
19
20
Donde 1, 2 y 3 salen de las tres declaraciones DISPLAY, y 17, 18, 19 y 20 son los números de línea de las líneas "ejecutables" (sin depuración).