feat(charka): charka-ir — representación intermedia con statements tipados
Tercera etapa del transpilador: Program -> Ir. El PROCEDURE division pasa de sentencias con tokens crudos a un árbol de instrucciones tipadas. - lower(&Program) -> Ir: total y tolerante, nunca falla. La DATA division pasa tal cual y sirve de tabla de símbolos. - Stmt cubre MOVE, DISPLAY, ACCEPT, COMPUTE, ADD, SUBTRACT, MULTIPLY, DIVIDE, IF/ELSE/END-IF, PERFORM (fuera de línea, en línea, TIMES, UNTIL), GO TO, STOP RUN, GOBACK, EXIT, CONTINUE. - Expresiones de COMPUTE con precedencia y paréntesis (Pratt). Condiciones con comparadores símbolo/palabra, AND/OR/NOT y nombres de condición (nivel 88). - Delimita statements por palabras frontera (COBOL no los separa con un símbolo). Verbo no soportado -> Stmt::Unknown con tokens crudos. - Módulos: ast / kw / cursor / expr / stmt. 17 tests; fmt + clippy limpios. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
//! Predicados sobre las palabras clave de COBOL. COBOL no termina los
|
||||
//! statements con un símbolo: una sentencia es una secuencia de
|
||||
//! statements que se delimitan por la aparición del siguiente verbo.
|
||||
//! Estos predicados le dicen al parser dónde corta un statement.
|
||||
|
||||
/// ¿Es `w` un verbo que inicia un statement? (En mayúsculas.)
|
||||
pub(crate) fn is_verb(w: &str) -> bool {
|
||||
matches!(
|
||||
w,
|
||||
"ACCEPT"
|
||||
| "ADD"
|
||||
| "ALTER"
|
||||
| "CALL"
|
||||
| "CANCEL"
|
||||
| "CLOSE"
|
||||
| "COMPUTE"
|
||||
| "CONTINUE"
|
||||
| "DELETE"
|
||||
| "DISPLAY"
|
||||
| "DIVIDE"
|
||||
| "EVALUATE"
|
||||
| "EXIT"
|
||||
| "GO"
|
||||
| "GOBACK"
|
||||
| "IF"
|
||||
| "INITIALIZE"
|
||||
| "INSPECT"
|
||||
| "MERGE"
|
||||
| "MOVE"
|
||||
| "MULTIPLY"
|
||||
| "OPEN"
|
||||
| "PERFORM"
|
||||
| "READ"
|
||||
| "RELEASE"
|
||||
| "RETURN"
|
||||
| "REWRITE"
|
||||
| "SEARCH"
|
||||
| "SET"
|
||||
| "SORT"
|
||||
| "START"
|
||||
| "STOP"
|
||||
| "STRING"
|
||||
| "SUBTRACT"
|
||||
| "UNSTRING"
|
||||
| "WRITE"
|
||||
)
|
||||
}
|
||||
|
||||
/// ¿Es `w` un terminador de ámbito (`END-IF`, `ELSE`, `WHEN`...)?
|
||||
pub(crate) fn is_terminator(w: &str) -> bool {
|
||||
matches!(
|
||||
w,
|
||||
"ELSE"
|
||||
| "WHEN"
|
||||
| "END-IF"
|
||||
| "END-PERFORM"
|
||||
| "END-EVALUATE"
|
||||
| "END-ADD"
|
||||
| "END-SUBTRACT"
|
||||
| "END-MULTIPLY"
|
||||
| "END-DIVIDE"
|
||||
| "END-COMPUTE"
|
||||
| "END-READ"
|
||||
| "END-WRITE"
|
||||
| "END-CALL"
|
||||
| "END-STRING"
|
||||
| "END-UNSTRING"
|
||||
| "END-SEARCH"
|
||||
| "END-START"
|
||||
| "END-DELETE"
|
||||
| "END-REWRITE"
|
||||
| "END-RETURN"
|
||||
)
|
||||
}
|
||||
|
||||
/// ¿Es `w` una palabra de conexión de una cláusula (`TO`, `GIVING`...)?
|
||||
fn is_connector(w: &str) -> bool {
|
||||
matches!(
|
||||
w,
|
||||
"TO" | "FROM"
|
||||
| "GIVING"
|
||||
| "BY"
|
||||
| "INTO"
|
||||
| "THRU"
|
||||
| "THROUGH"
|
||||
| "UNTIL"
|
||||
| "TIMES"
|
||||
| "ROUNDED"
|
||||
| "THEN"
|
||||
| "WITH"
|
||||
| "UPON"
|
||||
| "REMAINDER"
|
||||
| "VARYING"
|
||||
)
|
||||
}
|
||||
|
||||
/// ¿Marca `w` el final de una lista de operandos o de nombres? Es así
|
||||
/// para todo verbo, terminador o conector — ninguno puede ser un dato.
|
||||
pub(crate) fn is_boundary(w: &str) -> bool {
|
||||
is_verb(w) || is_terminator(w) || is_connector(w)
|
||||
}
|
||||
Reference in New Issue
Block a user