e52b3fb572
La etapa final del transpilador. generate(&Ir) -> String produce un fuente Rust (un main.rs) que, compilado contra charka-runtime, ejecuta la lógica del programa COBOL. - struct Program con un campo Num/Text por dato elemental; new() lo inicializa desde las cláusulas VALUE. - Un método p_<párrafo> por párrafo del PROCEDURE; run() los encadena en orden (el «caer» de COBOL); main() construye y corre. - Cada Stmt -> código Rust: MOVE->.store/.fill, DISPLAY->println!, COMPUTE y aritmética -> expresiones Decimal, IF->if/else, PERFORM-> llamada / for / while, STOP RUN->process::exit. - Tolerante: lo no transpilable (Stmt::Unknown, dato sin resolver, **) se emite como comentario // charka: — el código generado compila. - Saneado de identificadores COBOL->Rust (choques con keywords). - Verificado de punta a punta: un programa COBOL demo transpila a Rust que compila contra charka-runtime y produce la salida esperada. - Módulos: emit / sym / expr / stmt. 14 tests; fmt + clippy limpios. El pipeline COBOL->Rust corre de punta a punta. Falta sólo charka-shadow (validador en sombra). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
144 lines
7.4 KiB
Markdown
144 lines
7.4 KiB
Markdown
# Changelog — charka
|
|
|
|
Transpilador COBOL → Rust. El módulo más grande del ecosistema (Fase D
|
|
del plan macro) — el parser COBOL completo es un esfuerzo multi-mes.
|
|
|
|
### feat(charka-codegen): emisión de Rust desde el IR
|
|
|
|
Crate nuevo `crates/modules/charka/charka-codegen` — la etapa final del
|
|
pipeline. `generate(&Ir) -> String` produce un fuente Rust (un
|
|
`main.rs`) que, compilado contra `charka-runtime`, ejecuta la lógica
|
|
del programa COBOL.
|
|
|
|
- Un `struct Program` con un campo por cada dato elemental — `Num`
|
|
para los numéricos, `Text` para los alfanuméricos; `Program::new()`
|
|
los inicializa desde sus cláusulas `VALUE`.
|
|
- Un método `p_<párrafo>(&mut self)` por cada párrafo del PROCEDURE;
|
|
`run()` los encadena en orden (el «caer» de COBOL); `main()`
|
|
construye el `Program` y lo corre.
|
|
- Cada `Stmt` → código Rust: `MOVE`→`.store`/`.fill`,
|
|
`DISPLAY`→`println!`, `COMPUTE` y la aritmética → expresiones
|
|
`Decimal`, `IF`→`if`/`else`, `PERFORM`→ llamada de método / `for` /
|
|
`while`, `GO TO`→ llamada + `return`, `STOP RUN`→`process::exit`.
|
|
- Tolerante: lo no transpilable (`Stmt::Unknown`, un dato sin resolver,
|
|
el operador `**`) se emite como comentario `// charka:`; el código
|
|
generado siempre compila.
|
|
- Saneado de identificadores COBOL→Rust (incl. choques con keywords).
|
|
- Verificado de punta a punta: un programa COBOL de demostración
|
|
transpila a Rust que compila contra `charka-runtime` y produce la
|
|
salida esperada (`COMPUTE`, `IF`, `PERFORM`, `DISPLAY`).
|
|
- 14 tests del fuente emitido; fuera de alcance v1: grupos como campo,
|
|
`REDEFINES`, `OCCURS`, `PERFORM ... THRU` como rango, E/S.
|
|
|
|
### feat(charka-runtime): soporte de ejecución — campos Num y Text
|
|
|
|
Crate nuevo `crates/modules/charka/charka-runtime` — el soporte que los
|
|
programas COBOL transpilados enlazan. `charka-codegen` no emitirá Rust
|
|
autónomo: emitirá Rust que llama a esta biblioteca.
|
|
|
|
- `Num` — campo numérico (`PIC 9(5)V99`): un `Decimal` conformado a su
|
|
`Picture`. `store` trunca a la escala declarada; `store_rounded`
|
|
redondea; al desbordar la parte entera conserva los dígitos de bajo
|
|
orden (el `ON SIZE ERROR` de COBOL sin cláusula). `display` da los
|
|
dígitos con relleno de ceros y signo si corresponde.
|
|
- `Text` — campo alfanumérico (`PIC X(n)`) de longitud fija: `store`
|
|
justifica a la izquierda y rellena con espacios o trunca; `fill`
|
|
mueve las constantes figurativas (`SPACES`, `ZEROS`).
|
|
- `cobol_text_cmp` — comparación alfanumérica que rellena el más corto
|
|
con espacios.
|
|
- Reexporta `Decimal`/`Picture`/`Rounding` de `charka-bcd`.
|
|
- Construido antes que `charka-codegen` (la nota de orden del plan los
|
|
listaba al revés): el codegen emite contra esta API, así que el
|
|
runtime debe existir primero — y se verifica solo, sin el codegen.
|
|
- 17 tests: campo en cero, `VALUE` inicial, truncado y redondeo,
|
|
desbordamiento que conserva bajo orden, magnitud sin signo y signo
|
|
con signo, justificación y relleno de texto, `fill`, comparación.
|
|
|
|
### feat(charka-ir): representación intermedia — statements tipados
|
|
|
|
Crate nuevo `crates/modules/charka/charka-ir` — la tercera etapa del
|
|
pipeline: `Program` → `Ir`. El PROCEDURE division pasa de sentencias
|
|
con tokens crudos a un árbol de instrucciones tipadas.
|
|
|
|
- `lower(&Program) -> Ir` — total y tolerante: nunca falla.
|
|
- `Ir { program_id, data, procedures }`. El modelo de datos (la DATA
|
|
division) pasa tal cual — sirve de tabla de símbolos.
|
|
- `Stmt` cubre `MOVE`, `DISPLAY`, `ACCEPT`, `COMPUTE`, `ADD`,
|
|
`SUBTRACT`, `MULTIPLY`, `DIVIDE`, `IF`/`ELSE`/`END-IF`, `PERFORM`
|
|
(fuera de línea, en línea, `TIMES`, `UNTIL`), `GO TO`, `STOP RUN`,
|
|
`GOBACK`, `EXIT`, `CONTINUE`.
|
|
- Expresiones de `COMPUTE` con precedencia y paréntesis (`+ -` <
|
|
`* /` < `**` asociativo a derecha). Condiciones de `IF`/`UNTIL` con
|
|
comparadores en forma símbolo (`= < > <= >= <>`) o palabra
|
|
(`EQUAL TO`, `GREATER THAN`...), `AND`/`OR`/`NOT` y nombres de
|
|
condición (datos de nivel 88).
|
|
- COBOL no termina los statements con un símbolo: el parser delimita
|
|
las listas de operandos con palabras "frontera" (verbos,
|
|
terminadores `END-*`/`ELSE`, conectores `TO`/`GIVING`/`BY`...).
|
|
- Un verbo no soportado se conserva como `Stmt::Unknown { verb,
|
|
tokens }` — el lowering nunca aborta.
|
|
- Fuera de alcance v1: `EVALUATE`, `STRING`/`UNSTRING`, E/S de
|
|
ficheros, `PERFORM VARYING`, CICS, SQL embebido.
|
|
- 17 tests: MOVE simple y multi-destino, DISPLAY con figurativas,
|
|
precedencia de COMPUTE, flag ROUNDED, ADD in-place vs GIVING,
|
|
SUBTRACT, DIVIDE BY/INTO, IF/ELSE, condiciones con AND, nombre de
|
|
condición, PERFORM párrafo/TIMES/UNTIL en línea, varios statements
|
|
en una sentencia, verbo desconocido, programa completo.
|
|
|
|
### feat(charka-parser): parser COBOL'85 → AST
|
|
|
|
Crate nuevo `crates/modules/charka/charka-parser` — la segunda etapa del
|
|
pipeline: `Vec<Token>` → `Program` (AST). Alcance v1: el esqueleto del
|
|
programa.
|
|
|
|
- `parse(&[Token]) -> Result<Program, ParseError>`. El AST: `Program`
|
|
(`program_id`, `data`, `paragraphs`), `DataItem`, `Paragraph`,
|
|
`Sentence`.
|
|
- Particiona el flujo de tokens en las cuatro divisiones por sus
|
|
encabezados (`X DIVISION`); de la IDENTIFICATION extrae el
|
|
`PROGRAM-ID`.
|
|
- **DATA division** → árbol de `DataItem`: número de nivel, nombre,
|
|
cláusula `PICTURE` reensamblada (`S9` `(` `5` `)` `V99` →
|
|
`S9(5)V99`) y `VALUE`. Anida por número de nivel — 01 y 77 son
|
|
raíces, 88 cuelga del ítem precedente.
|
|
- **PROCEDURE division** → `Vec<Paragraph>`, cada párrafo con sus
|
|
`Sentence` (tokens crudos; sin parseo a nivel de statement, eso es
|
|
`charka-ir`). Las sentencias previas al primer encabezado van a un
|
|
párrafo implícito de nombre "".
|
|
- Parser tolerante: salta encabezados de `SECTION`, entradas `FD`/`SD`
|
|
y cláusulas de datos que no sean `PICTURE`/`VALUE`. `ParseError` sólo
|
|
ante un número de nivel inválido o un dato sin nombre.
|
|
- 15 tests: PROGRAM-ID (forma larga y `ID` corta), ítems planos y
|
|
anidados, reensamblado de PICTURE, variantes de VALUE, niveles 88,
|
|
`FILLER`, párrafos y párrafo implícito, encabezado de sección,
|
|
programa completo de punta a punta, nivel inválido.
|
|
|
|
### feat(charka-lexer): tokenizador de COBOL
|
|
|
|
Crate nuevo `crates/modules/charka/charka-lexer` — la primera etapa del
|
|
pipeline del transpilador: texto COBOL → secuencia de `Token`.
|
|
|
|
- **Lexer deliberadamente tonto**: no conoce keywords ni la cláusula
|
|
`PICTURE`; emite `Word` para todo identificador y deja la
|
|
clasificación al parser.
|
|
- Tokens: `Word` (palabras COBOL con guiones internos), `Number`
|
|
(literal sin signo), `String` (comillas dobladas colapsadas),
|
|
`Period` (el `.` terminador), `Symbol` (paréntesis, separadores y
|
|
operadores `+ - * / ** = < > <= >= <>`).
|
|
- Dos formatos de fuente: **fijo** (la tarjeta de 80 columnas — cols
|
|
1-6 secuencia, 7 indicadora, 8-72 código, 73-80 identificación) y
|
|
**libre**. Comentarios por la columna indicadora (`*`/`/`) o por `*`
|
|
inicial en formato libre.
|
|
- Cada `Token` lleva línea y columna 1-based; `LexError` tipado
|
|
(literal sin cerrar, carácter inesperado).
|
|
- Limitación v1 documentada: no soporta continuación de literales entre
|
|
líneas (indicador `-`). Subconjunto COBOL'85, el hito intermedio.
|
|
- 17 tests: sentencias, palabras con guiones, literales y comillas
|
|
dobladas, números vs terminador, operadores, ambos formatos,
|
|
tracking de posición, errores.
|
|
|
|
### feat(charka-bcd): aritmética decimal con semántica COBOL
|
|
|
|
(Pre-existente.) `Picture` + `Decimal` de punto fijo exacto — ver el
|
|
SDD del módulo. 22 tests.
|