feat(charka): OCCURS — tablas y referencias con subíndice
Los arrays de COBOL, que antes el transpilador descartaba en silencio.
Una rebanada vertical amplia que atraviesa el pipeline entero.
- Parser: la cláusula OCCURS n [TIMES] se captura en DataItem.
- IR: Operand::Indexed { name, index } — una referencia ELEM(I), con
subíndice 1-based. Los destinos de los statements pasan de
Vec<String> a Vec<Operand>, así que se puede escribir a un elemento
de tabla (MOVE x TO ELEM(I), COMPUTE ELEM(I) = ...). model::Field
gana occurs: Option<u32>.
- Codegen: un campo OCCURS se emite como Vec<Num>/Vec<Text>,
inicializado con vec![..; n]; una referencia con subíndice indexa el
vector (1-based -> 0-based).
- Shadow: en el intérprete todo campo es un vector — un escalar es de
longitud 1, una tabla de n; las referencias se resuelven a
(nombre, índice).
- Corpus: programa nuevo 11-tabla (llena una tabla con cuadrados y los
suma). Verificado: el intérprete sombra y el crate compilado por
scaffold dan ambos SUMA DE CUADRADOS = 000055.
Alcance v1: OCCURS elemental, una dimensión, subíndice de un operando.
Fuera: OCCURS de grupo, multidimensional, DEPENDING ON.
Tests: charka-parser 16, charka-ir 24, charka-codegen 18,
charka-shadow 16. fmt + clippy limpios.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -103,10 +103,26 @@ pub(crate) fn parse_operand(c: &mut Cursor) -> Operand {
|
||||
num.text
|
||||
});
|
||||
}
|
||||
match c.bump() {
|
||||
let base = match c.bump() {
|
||||
Some(t) => token_to_operand(&t),
|
||||
None => Operand::Num("0".into()),
|
||||
None => return Operand::Num("0".into()),
|
||||
};
|
||||
// Subíndice de tabla: `name(index)`. La v1 toma un solo subíndice;
|
||||
// lo demás dentro del paréntesis se descarta.
|
||||
if let Operand::Data(name) = &base {
|
||||
if c.eat_sym("(") {
|
||||
let index = parse_operand(c);
|
||||
while !c.at_sym(")") && !c.done() {
|
||||
c.bump();
|
||||
}
|
||||
c.eat_sym(")");
|
||||
return Operand::Indexed {
|
||||
name: name.clone(),
|
||||
index: Box::new(index),
|
||||
};
|
||||
}
|
||||
}
|
||||
base
|
||||
}
|
||||
|
||||
/// Clasifica un token suelto como operando.
|
||||
|
||||
Reference in New Issue
Block a user