Files
brahman/crates/modules/charka/charka-codegen/src/emit.rs
T
sergio e52b3fb572 feat(charka): charka-codegen — emisión de Rust desde el IR
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>
2026-05-21 20:36:26 +00:00

46 lines
1.0 KiB
Rust

//! `Emitter` — un acumulador de código Rust con control de sangría.
/// Acumula líneas de código Rust generado, llevando la sangría actual.
pub(crate) struct Emitter {
out: String,
depth: usize,
}
impl Emitter {
pub(crate) fn new() -> Self {
Self {
out: String::new(),
depth: 0,
}
}
/// Escribe una línea con la sangría actual.
pub(crate) fn line(&mut self, s: &str) {
for _ in 0..self.depth {
self.out.push_str(" ");
}
self.out.push_str(s);
self.out.push('\n');
}
/// Una línea en blanco.
pub(crate) fn blank(&mut self) {
self.out.push('\n');
}
/// Aumenta un nivel de sangría.
pub(crate) fn indent(&mut self) {
self.depth += 1;
}
/// Reduce un nivel de sangría.
pub(crate) fn dedent(&mut self) {
self.depth = self.depth.saturating_sub(1);
}
/// Entrega el código acumulado.
pub(crate) fn finish(self) -> String {
self.out
}
}