Files
brahman/crates/modules/charka/SDD.md
T
sergio 71a4068d12 feat(charka): charka-ir — representación intermedia con statements tipados
Tercera etapa del transpilador: 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. La DATA
  division pasa tal cual y 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 (Pratt).
  Condiciones con comparadores símbolo/palabra, AND/OR/NOT y nombres
  de condición (nivel 88).
- Delimita statements por palabras frontera (COBOL no los separa con
  un símbolo). Verbo no soportado -> Stmt::Unknown con tokens crudos.
- Módulos: ast / kw / cursor / expr / stmt. 17 tests; fmt + clippy
  limpios.

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

5.2 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-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.

Estado

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

crate pendiente rol
charka-codegen emisión de Rust
charka-shadow validador en sombra (original vs transpilado)
charka-runtime runtime determinista (sobre charka-bcd)

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