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>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
//! `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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user