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>
46 lines
1.0 KiB
Rust
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
|
|
}
|
|
}
|