feat(charka): SET ... TO TRUE — escribir nombres de condición (88)
La cara de escritura de los nombres de condición de COBOL: si
IF ES-VALIDO los lee, SET ES-VALIDO TO TRUE los escribe.
- IR: Stmt::SetTrue { conditions }.
- Parser: SET cond-1 cond-2 ... TO TRUE. Otras formas de SET
(índices, TO FALSE) caen a Stmt::Unknown.
- Codegen y shadow: SET cond TO TRUE asigna a su dato padre el valor
del 88 (un MOVE del valor a la variable).
- Corpus: programa nuevo 16-bandera (cambia banderas de texto y de
número con SET). Verificado: el intérprete sombra y el crate
compilado por scaffold dan la misma salida.
Tests: charka-ir 29, charka-codegen 23, charka-shadow 21. fmt +
clippy limpios.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -188,6 +188,9 @@ pub enum Stmt {
|
||||
/// `INITIALIZE targets...` — pone cada dato (o grupo) en su valor
|
||||
/// por defecto: 0 los numéricos, espacios los alfanuméricos.
|
||||
Initialize { targets: Vec<Operand> },
|
||||
/// `SET cond-name... TO TRUE` — hace verdaderos esos nombres de
|
||||
/// condición (nivel 88): asigna a su dato padre el valor del 88.
|
||||
SetTrue { conditions: Vec<String> },
|
||||
/// `PERFORM ...` — ver [`Perform`].
|
||||
Perform(Perform),
|
||||
/// `GO TO target`
|
||||
|
||||
@@ -460,6 +460,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_to_true_parses() {
|
||||
let b = body("SET ACTIVO LISTO TO TRUE.");
|
||||
match &b[0] {
|
||||
Stmt::SetTrue { conditions } => {
|
||||
assert_eq!(conditions, &vec!["ACTIVO".to_string(), "LISTO".to_string()]);
|
||||
}
|
||||
other => panic!("se esperaba SET, vino {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn several_statements_in_one_sentence() {
|
||||
let b = body("MOVE 1 TO X DISPLAY X STOP RUN.");
|
||||
|
||||
@@ -45,6 +45,7 @@ fn parse_one_stmt(c: &mut Cursor, stops: &[&str]) -> Stmt {
|
||||
"UNSTRING" => parse_unstring(c),
|
||||
"INSPECT" => parse_inspect(c),
|
||||
"INITIALIZE" => parse_initialize(c),
|
||||
"SET" => parse_set(c),
|
||||
"PERFORM" => parse_perform(c),
|
||||
"GO" => parse_goto(c),
|
||||
"STOP" => parse_stop(c),
|
||||
@@ -391,6 +392,24 @@ fn parse_unstring(c: &mut Cursor) -> Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_set(c: &mut Cursor) -> Stmt {
|
||||
c.bump(); // SET
|
||||
let mut conditions = Vec::new();
|
||||
while let Some(name) = parse_one_name(c) {
|
||||
conditions.push(name);
|
||||
}
|
||||
// La v1 sólo modela `SET ... TO TRUE`.
|
||||
if c.eat_word("TO") && c.eat_word("TRUE") {
|
||||
Stmt::SetTrue { conditions }
|
||||
} else {
|
||||
skip_to_stmt_boundary(c);
|
||||
Stmt::Unknown {
|
||||
verb: "SET".to_string(),
|
||||
tokens: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_initialize(c: &mut Cursor) -> Stmt {
|
||||
c.bump(); // INITIALIZE
|
||||
let mut rounded = false;
|
||||
|
||||
Reference in New Issue
Block a user