Diagrama – Generación de diagramas Mermaid del AST

Archivo: src/diagrama.rs

🔥 Propósito: Genera un diagrama de flujo Mermaid.js a partir del AST de un programa Forja, mostrando visualmente el flujo de control (condicionales, bucles, funciones, clases). Ideal para entender visualmente cómo se ejecuta un programa.

CLI: forja diagrama

El comando forja diagrama (o forja grafico) genera un diagrama Mermaid a partir de un archivo .fa:

⚡ Uso
forja diagrama "ejemplo.fa"                // genera ejemplo.mmd
forja diagrama "ejemplo.fa" -o "salida.mmd" // archivo específico
forja diagrama "ejemplo.fa" -o -             // stdout
💡 El archivo .mmd generado se puede visualizar en cualquier herramienta compatible con Mermaid.js (GitHub Markdown, mermaid.live, editores con plugin Mermaid).

Estructura: DiagramGenerator

La estructura principal es DiagramGenerator (599 líneas). Genera diagramas en sintaxis Mermaid graph TD recorriendo el AST recursivamente.

Métodos públicos

MétodoDescripción
pub fn new() -> SelfCrea un nuevo generador de diagramas vacío
pub fn generar(&mut self, p: &Programa) -> StringRecibe un AST (Programa) y retorna un string en formato Mermaid graph TD

Cómo funciona

El generador recorre el árbol AST de forma recursiva y genera nodos Mermaid para cada tipo de declaración y expresión:

  1. Punto de entrada: generar() crea un nodo "Inicio" y un nodo "Fin", y enlaza el bloque principal de declaraciones entre ellos.
  2. Bloques secuenciales: Cada declaración produce nodos con flechas --> entre sí. Las funciones y clases se agrupan en subgraph.
  3. Condicionales si/sino: Crea un nodo rombo { } con la condición, y dos ramas: -- Si --> y -- Sino --> que se unen al final.
  4. Bucles mientras: Nodo rombo + flecha de retroalimentación (be --> cond_node) + salida -- No -->.
  5. Bucles para: Tres nodos: Init (rectángulo), Condición (rombo), Incremento (rectángulo) con retroalimentación.
  6. Bucles repetir: Nodo rombo con -- Bucle --> y retroalimentación, más -- Fin -->.
  7. Funciones: Se envuelven en subgraph Fn_nombre con su propio Inicio/Fin interno.
  8. Clases: Se envuelven en subgraph Class_nombre, y cada método en un sub-subgraph.
  9. Bloque cuando: Similar a un condicional, con nodo rombo y cuerpo.

Tipos de nodos Mermaid usados

FormaSintaxis MermaidUso en DiagramGenerator
Inicio / Fin([label])Nodos redondeados para start/end de función y programa
Acción[label]Variables, asignaciones, llamadas, retornos
Decisión{label}Condiciones de si, mientras, para, repetir

Ejemplo de entrada y salida

Dado este programa Forja:

📄 ejemplo.fa
funcion saludar(nombre) {
    escribir("Hola, " + nombre)
}

variable x = 10
si (x > 5) {
    saludar("Mundo")
}

El generador produce un diagrama Mermaid como este:

📊 ejemplo.mmd (Mermaid)
graph TD
    N0([Inicio])
    subgraph Fn_saludar ["funcion saludar(nombre)"]
        N1([Inicio])
        N2[escribir("Hola, " + nombre)]
        N3([Fin])
        N1 --> N2
        N2 --> N3
    end

    N4[x = 10]
    N0 --> N4
    N5{si (x > 5)}
    N4 --> N5
    N6[saludar("Mundo")]
    N5 -- Si --> N6
    N7([Fin])
    N6 --> N7
    N5 -- Sino --> N7
💡 El archivo .mmd se puede incrustar directamente en GitHub Markdown con ```mermaid, o en cualquier página web que soporte Mermaid.js.

Declaraciones soportadas

El generador maneja todos estos tipos de declaraciones del AST:

DeclaraciónRepresentación en el diagrama
variable x = 5Nodo rectángulo: [var x = 5]
constante x = 5Nodo rectángulo: [const x = 5]
x = 10 (asignación)Nodo rectángulo: [x = 10]
funcion f(p) { ... }subgraph Fn_f con Inicio → cuerpo → Fin
clase C { ... }subgraph Class_C con subgraph por método
si (cond) { ... } sino { ... }Nodo rombo + ramas Si/Sino + merge
mientras (cond) { ... }Nodo rombo + retroalimentación + salida No
para (i=0; i<N; i++) { ... }Init → Cond(rombo) → cuerpo → Inc → retroalimentación
repetir (N) { ... }Nodo rombo repetir N veces + retroalimentación
cuando (var) { ... }Nodo rombo cuando (var) + cuerpo
retornar exprNodo rectángulo: [retornar expr]
f(args) (llamada)Nodo rectángulo: [f(args)]
importar ruta o importar "ruta/absoluta"Comentario: %% Importar ruta
tipo X = A | BNodo rectángulo con la definición
rasgo R { metodos }subgraph Rasgo_R
implementa R para C { ... }subgraph Impl_R_C con métodos
variable a, b = exprNodo rectángulo: [a, b = expr]

Expresiones soportadas

El generador también renderiza expresiones dentro de los nodos: literales, identificadores, operaciones binarias/unarias, llamadas, acceso a miembros, instanciación (nuevo), referencias (& / &mut), arreglos, mapas, indexación, coincidir, hilo, canal(), seleccionar, try (?), asignación, Ok()/Error()/Algo(), y keywords de contratos (resultado, anterior).

Integración WASM

diagrama.rs está compilado a WebAssembly en el crate forja-wasm, permitiendo generar diagramas Mermaid directamente en el navegador desde el Playground.

⚠️ El generador produce únicamente el texto Mermaid (.mmd). Para visualizarlo necesitás un renderizador Mermaid.js externo. El comando CLI guarda el archivo, no lo renderiza.