Files
brahman/crates/modules/charka/SDD.md
T
sergio 85156c1509 feat(charka): charka-runtime — soporte de ejecución (campos Num y Text)
El soporte que los programas COBOL transpilados enlazan. charka-codegen
emitirá Rust que llama a esta biblioteca, no Rust autónomo.

- 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.
- Text: campo alfanumérico (PIC X(n)) de longitud fija — store
  justifica a la izquierda y rellena/trunca; fill mueve figurativas.
- cobol_text_cmp: comparación alfanumérica con relleno de 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. 17 tests; fmt +
clippy limpios.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 20:27:28 +00:00

6.4 KiB

modules/charka/ — Transpilador COBOL → Rust

Propósito. Modernizar sistemas COBOL legados transpilándolos a Rust con un runtime determinista y un validador en sombra (shadow validator) que compara la salida del original y la del transpilado. Es el módulo más grande del ecosistema — el parser COBOL completo (CICS, SQL embebido, dialectos IBM Enterprise) es un esfuerzo multi-mes.

Crates

crate tipo rol
charka-bcd lib Aritmética decimal de punto fijo con semántica COBOL: Picture, Decimal, redondeo, ON SIZE ERROR
charka-lexer lib Tokenizador COBOL: formato fijo (tarjeta de 80 columnas) y libre
charka-parser lib Parser COBOL'85 (subconjunto): tokens → AST (Program)
charka-ir lib Representación intermedia: el AST con los statements del PROCEDURE ya tipados
charka-runtime lib Soporte de ejecución de los programas transpilados: campos Num y Text

charka-bcd

COBOL no calcula en binario flotante: opera sobre campos decimales de precisión fija (PIC S9(5)V99). Reproducir un programa COBOL exige reproducir esa aritmética dígito a dígito.

  • Picture — parsea la cláusula PICTURE numérica (9, V, S, 9(n)).
  • Decimal — punto fijo exacto (mantissa: i128 + scale); suma, resta y producto exactos; división con escala de resultado fija; redondeo Truncate/HalfUp; coerce a un Picture con detección de desbordamiento.
  • Determinista, sin dependencias de plataforma — mismo programa, mismos dígitos, en cualquier máquina.

charka-lexer

Primera etapa del pipeline: texto COBOL → secuencia de Token.

  • Lexer tonto: no conoce keywords ni la cláusula PICTURE — emite Word para todo identificador; la clasificación es del parser.
  • Tokens: Word (con guiones internos, WORKING-STORAGE), Number (sin signo), String (comillas dobladas colapsadas), Period, Symbol (( ) , ; : y operadores + - * / ** = < > <= >= <>).
  • Dos formatos: fijo (cols 1-6 secuencia, 7 indicadora, 8-72 código, 73-80 id) y libre. Comentarios por col 7 (*//) o * inicial en formato libre.
  • Cada token lleva línea/columna 1-based. LexError tipado.
  • Limitación v1: sin continuación de literales entre líneas (indicador -).

charka-parser

Segunda etapa: tokens → AST. Alcance v1 — el esqueleto del programa.

  • parse(&[Token]) -> Result<Program, ParseError>.
  • Program { program_id, data: Vec<DataItem>, paragraphs: Vec<Paragraph> }.
  • DATA division → árbol de DataItem (level, name, picture, value, children). Reensambla la cláusula PICTURE desde sus tokens (S9 ( 5 ) V99S9(5)V99); anida por número de nivel (01 y 77 son raíces; 88 cuelga del ítem precedente).
  • PROCEDURE divisionVec<Paragraph>, cada Paragraph con sus Sentence (tokens crudos — sin parseo a nivel de statement). Las sentencias previas al primer encabezado van a un párrafo implícito de nombre "".
  • Tolerante: salta encabezados de SECTION, entradas FD/SD y cláusulas de datos que no sean PICTURE/VALUE. ParseError sólo ante nivel inválido o dato sin nombre.
  • Limitación v1: no parsea statements, ni la ENVIRONMENT division, ni CICS / SQL embebido / dialectos IBM.

charka-ir

Tercera etapa: ProgramIr. Aquí se parsea cada Sentence cruda (tokens) a statements tipados — el PROCEDURE division pasa de tokens a árbol de instrucciones.

  • lower(&Program) -> Irtotal y tolerante, nunca falla.
  • Ir { program_id, data: Vec<DataItem>, procedures: Vec<Procedure> }. El modelo de datos pasa tal cual (sirve de tabla de símbolos).
  • Procedure { name, body: Vec<Stmt> }. Stmt cubre Move, Display, Accept, Compute, Add/Subtract/Multiply/Divide, If, Perform, GoTo, StopRun, Goback, Exit, Continue.
  • Expr — expresiones aritméticas con precedencia y paréntesis (Pratt: + - < * / < ** der.). Cond — comparaciones (símbolo o forma palabra) unidas por AND/OR/NOT, más nombres de condición (88).
  • Un verbo no soportado se conserva como Stmt::Unknown { verb, tokens } — el lowering jamás aborta.
  • COBOL no separa statements con un símbolo: cada uno corta donde empieza el verbo del siguiente. El parser usa palabras "frontera" (verbos + terminadores END-*/ELSE + conectores TO/GIVING...) para delimitar listas de operandos.
  • Fuera de alcance v1: EVALUATE, STRING/UNSTRING, E/S de ficheros, PERFORM VARYING, CICS, SQL embebido.

charka-runtime

El soporte de ejecución: lo que charka-codegen emite es Rust que enlaza contra este crate. Da a un programa transpilado la semántica de COBOL en tiempo de ejecución.

  • Num — campo numérico (PIC 9(5)V99): un Decimal conformado a su Picture. store/store_rounded truncan o redondean a la escala declarada; al desbordar conservan los dígitos de bajo orden (el ON SIZE ERROR sin cláusula). display da los dígitos con relleno de ceros.
  • Text — campo alfanumérico (PIC X(20)) de longitud fija: store justifica a la izquierda y rellena/trunca; fill mueve figurativas (SPACES, ZEROS).
  • cobol_text_cmp — comparación alfanumérica con relleno de espacios.
  • Reexporta Decimal/Picture/Rounding de charka-bcd para que el código generado sólo necesite use charka_runtime::*;.

Construido antes que charka-codegen (la nota de orden del plan los listaba al revés): el codegen emite llamadas contra esta API, así que el runtime debe existir primero — y es un crate autocontenido, verificable sin depender del código emitido.

Estado

charka-bcd (22 tests), charka-lexer (17 tests), charka-parser (15 tests), charka-ir (17 tests) y charka-runtime (17 tests) implementados y verdes. Pendiente — el resto del transpilador (Fase D del plan macro):

crate pendiente rol
charka-codegen emisión de Rust (IR → fuente Rust sobre el runtime)
charka-shadow validador en sombra (original vs transpilado)

Hito intermedio sugerido: subconjunto COBOL'85 puro antes de CICS/SQL.