AST – Árbol de Sintaxis Abstracta
Archivo: src/ast.rs — 424 líneas
¿Por qué existe?
El AST (Abstract Syntax Tree) es la representación estructurada del código fuente de Forja
después del análisis léxico y sintáctico. Cada nodo del árbol captura un elemento del lenguaje
(expresiones, declaraciones, tipos, patrones) con todos sus datos semánticos, permitiendo que
las fases posteriores del compilador —análisis semántico, generación de bytecode, formateo,
transpilación— trabajen sobre una estructura de datos rica y tipada en lugar de texto plano.
Estructura raíz
Programa
Representa la unidad de compilación completa. Es la raíz del AST generado por el parser.
| Campo | Tipo | Descripción |
declaraciones | Vec<Declaracion> | Lista ordenada de declaraciones del programa (funciones, clases, variables, imports, etc.) |
Operadores
Operador — Operadores binarios (12 variantes)
| Variante | Categoría | Símbolo Forja | Descripción |
Suma | Aritmético | + | Suma de dos expresiones |
Resta | Aritmético | - | Resta de dos expresiones |
Multiplicacion | Aritmético | * | Multiplicación de dos expresiones |
Division | Aritmético | / | División de dos expresiones |
Modulo | Aritmético | % | Módulo (resto de división) de dos expresiones |
Mayor | Relacional | > | Comparación mayor que |
Menor | Relacional | < | Comparación menor que |
MayorIgual | Relacional | >= | Comparación mayor o igual que |
MenorIgual | Relacional | <= | Comparación menor o igual que |
IgualIgual | Relacional | == | Comparación de igualdad |
Diferente | Relacional | != | Comparación de desigualdad |
Y | Lógico | y | Conjunción lógica (AND) |
O | Lógico | o | Disyunción lógica (OR) |
OperadorUnario — Operadores unarios (2 variantes)
| Variante | Símbolo Forja | Descripción |
Negar | -expr | Negación numérica: invierte el signo de la expresión |
No | !expr | Negación lógica: invierte el valor booleano de la expresión |
Sistema de Tipos
Tipo — Tipos de datos (12 variantes)
| Variante | Descripción | Ejemplo Forja |
Entero | Número entero (i64) | variable x: Entero = 42 |
Decimal | Número de punto flotante (f64) | variable x: Decimal = 3.14 |
Texto | Cadena de caracteres (String) | variable s: Texto = "hola" |
Booleano | Valor booleano (bool) | variable b: Booleano = cierto |
Nulo | Valor nulo (null) | variable n: Nulo = nulo |
Exacto | Número exacto de precisión arbitraria (i128 + escala u32) | variable e: Exacto = 10.50 exacto |
Clase(String) | Nombre de clase definida por el usuario | variable p: Persona = ... |
Arreglo(Box<Tipo>) | Arreglo de elementos de tipo T | variable arr: [Entero] = [1, 2, 3] |
Funcion(Vec<Tipo>, Box<Tipo>) | Tipo función: (parametros) → retorno | variable f: (Entero) → Texto |
Resultado(Box<Tipo>, Box<Tipo>) | Resultado con Ok(T) y Error(E) | variable r: Resultado<Entero, Texto> |
Opcion(Box<Tipo>) | Valor opcional Option(T) | variable o: Opcion<Entero> |
RasgoObjeto(String) | Un rasgo usado como tipo base (polimorfismo) | variable r: Mostrable |
Parametro(String) | Parámetro de tipo genérico (T, U, etc.) | funcion id<T>(x: T) → T { x } |
Estructuras auxiliares
ParametroTipo
Representa un parámetro de tipo genérico en una función o clase (como T en funcion foo<T>(x: T)).
| Campo | Tipo | Descripción |
nombre | String | Nombre del parámetro de tipo (ej: "T", "U") |
Parametro
Parámetro de función, con soporte para préstamos (referencias) y tipo opcional (inferido).
| Campo | Tipo | Descripción |
nombre | String | Nombre del parámetro |
prestado | bool | Si es una referencia prestada (&T) |
mutable | bool | Si es una referencia mutable (&mut T) |
tipo | Option<Tipo> | Tipo del parámetro. None si se infiere |
VariableClase
Campo declarado dentro de una clase.
| Campo | Tipo | Descripción |
nombre | String | Nombre del campo |
tipo | Option<Tipo> | Tipo del campo. None si se infiere |
Atributo
Anotación o atributo (como @derive, @test) que puede aplicarse a funciones, clases, enums.
| Campo | Tipo | Descripción |
nombre | String | Nombre del atributo (ej: "derive", "test") |
argumentos | Vec<String> | Argumentos del atributo (ej: ["Mostrar", "Igualdad"]) |
Variante
Variante de un tipo enum (ej: Alguno(Entero)).
| Campo | Tipo | Descripción |
nombre | String | Nombre de la variante (ej: "Alguno") |
tipos | Vec<Tipo> | Tipos de datos asociados a la variante |
Patron — Patrones de matching (4 variantes)
| Variante | Descripción | Ejemplo Forja |
Variable(String) | Víncula el valor a una variable en el brazo | caso x -> ... |
Literal(Expresion) | Coincide contra un valor literal | caso 42 -> ... |
Constructor(String, Vec<Patron>) | Coincide contra un constructor con sub-patrones para sus campos | caso Alguno(v) -> ... |
Ignorar | Comodín que ignora el valor (equivale a _) | caso _ -> ... |
Contrato — Design by Contract
Representa una precondición (requiere), postcondición (asegura) o invariante (siempre).
| Campo | Tipo | Descripción |
condicion | Expresion | Expresión booleana que debe cumplirse |
mensaje | Option<String> | Mensaje de error opcional si la condición falla |
Metodo
Método completo (con cuerpo) dentro de una clase o implementación de rasgo.
| Campo | Tipo | Descripción |
nombre | String | Nombre del método |
parametros | Vec<Parametro> | Parámetros del método |
tipo_retorno | Option<Tipo> | Tipo de retorno (opcional, se infiere) |
cuerpo | Vec<Declaracion> | Cuerpo del método como lista de declaraciones |
precondiciones | Vec<Contrato> | Precondiciones (requiere) del método |
postcondiciones | Vec<Contrato> | Postcondiciones (asegura) del método |
FirmaMetodo
Firma de método sin cuerpo, usada en definiciones de rasgo (interfaz).
| Campo | Tipo | Descripción |
nombre | String | Nombre del método |
parametros | Vec<Parametro> | Parámetros del método |
tipo_retorno | Option<Tipo> | Tipo de retorno (opcional, se infiere) |
BrazoMatch
Brazo individual dentro de una expresión coincidir.
| Campo | Tipo | Descripción |
patron | Patron | Patrón contra el que se compara |
cuerpo | Vec<Declaracion> | Declaraciones a ejecutar si el patrón coincide |
BrazoSeleccionar
Brazo individual dentro de una expresión seleccionar (select sobre canales).
| Campo | Tipo | Descripción |
recepcion | Option<(String, Expresion)> | Some(variable, canal) para recepción; None para default/tiempo |
timeout_ms | u64 | Tiempo de espera en ms (0 = default/inmediato) |
cuerpo | Vec<Declaracion> | Declaraciones a ejecutar si el brazo se selecciona |
Expresiones
Expresion — Todas las expresiones del lenguaje (32 variantes)
Literales y valores
| Variante | Descripción | Ejemplo Forja |
LiteralNumero(i64) | Literal entero de 64 bits | 42, -10 |
LiteralDecimal(f64) | Literal de punto flotante | 3.14, -0.5 |
LiteralTexto(String) | Literal de cadena | "hola mundo" |
LiteralBooleano(bool) | Literal booleano | cierto, falso |
LiteralNulo | Literal nulo | nulo |
LiteralExacto(i128, u32) | Literal exacto (coeficiente + escala) | 10.50 exacto |
Identificadores y acceso
| Variante | Descripción | Ejemplo Forja |
Identificador { nombre, linea, columna } | Referencia a variable, función o miembro | x, PI |
AccesoMiembro { objeto, miembro } | Acceso a miembro de objeto | persona.nombre |
Index { objeto, indice } | Acceso por índice a arreglo | arr[0] |
Grupo(Box<Expresion>) | Expresión agrupada entre paréntesis | (a + b) * c |
Referencia { expr, mutable } | Referencia (préstamo) a una expresión | &x, &mut x |
Operaciones aritméticas y lógicas
| Variante | Descripción | Ejemplo Forja |
Binaria { izq, op, der } | Operación binaria entre dos expresiones | a + b, x > 5 |
Unaria { op, expr } | Operación unaria sobre una expresión | -x, !cond |
Ternario { cond, si_verdadero, si_falso } | Operador ternario condicional | cond ? cierto : falso |
Try(Box<Expresion>) | Operador de propagación de errores | expresion? |
Llamadas e instanciación
| Variante | Descripción | Ejemplo Forja |
LlamadaFuncion { nombre, argumentos } | Llamada a función por nombre | escribir("hola") |
LlamadaMetodo { objeto, metodo, argumentos } | Llamada a método sobre objeto | lista.agregar(5) |
Instanciacion { clase, argumentos } | Instanciación de clase | nuevo Persona("Ana") |
Closure { parametros, cuerpo } | Función anónima (closure) | func(x) { x + 1 } |
Estructuras de datos
| Variante | Descripción | Ejemplo Forja |
Arreglo(Vec<Expresion>) | Arreglo literal | [1, 2, 3] |
Mapa(Vec<(Expresion, Expresion)>) | Mapa literal (clave → valor) | #{"clave": valor} |
Constructores de tipo algebraico
| Variante | Descripción | Ejemplo Forja |
Ok(Box<Expresion>) | Constructor Ok de Resultado | Ok(42) |
Error(Box<Expresion>) | Constructor Error de Resultado | Error("falló") |
Algo(Box<Expresion>) | Constructor Algo de Opcion | Algo(42) |
Resultado | Referencia al valor de retorno (para postcondiciones) | resultado |
Anterior(Box<Expresion>) | Valor anterior de una expresión (para contratos) | anterior(x) |
Asignaciones como expresión
| Variante | Descripción | Ejemplo Forja |
Asignacion { variable, valor } | Asignación como expresión (retorna el valor) | x = 5 |
AsignacionCampo { objeto, campo, valor } | Asignación a campo como expresión | obj.campo = valor |
ArraySet { array, valor } | Asignación por índice como expresión | arr[i] = valor |
Concurrencia y control
| Variante | Descripción | Ejemplo Forja |
Hilo { cuerpo } | Creación de hilo ligero | hilo { ... } |
CanalNuevo | Creación de canal de comunicación | canal() |
Seleccionar { brazos } | Selección entre múltiples canales (select) | seleccionar { ... } |
Coincidir { expr, brazos } | Pattern matching sobre una expresión | coincidir expr { ... } |
Declaraciones
Declaracion — Todas las declaraciones del lenguaje (20 variantes)
Variables y asignaciones
| Variante | Descripción | Ejemplo Forja |
Variable { mutable, nombre, tipo, valor, linea, columna } | Declaración de variable (inmutable o mutable) | variable x = 5 / variable mutable y = 10 |
Asignacion { nombre, valor, linea, columna } | Asignación a variable existente | x = 10 |
AsignacionMiembro { objeto, miembro, valor, linea, columna } | Asignación a campo de objeto | este.nombre = "Ana" |
AsignacionIndex { nombre, indice, valor, linea, columna } | Asignación por índice | arr[0] = 10 |
AsignacionMultiple { variables, mutable, valor } | Asignación múltiple (ej: canal tx, rx) | variable tx, rx = canal() |
Funciones
| Variante | Descripción | Ejemplo Forja |
Funcion { nombre, parametros_tipo, parametros, tipo_retorno, cuerpo, externa, enlace_nombre, atributos, doc, precondiciones, postcondiciones } | Declaración de función completa con soporte para genéricos, FFI, atributos, documentación y contratos | funcion sumar(a: Entero, b: Entero) → Entero { a + b } |
Clases, enums, rasgos
| Variante | Descripción | Ejemplo Forja |
Clase { nombre, parametros_tipo, campos, metodos, atributos, invariantes } | Declaración de clase con campos, métodos, genéricos, atributos e invariantes | clase Persona { ... } |
Enum { nombre, variantes, atributos } | Declaración de tipo enum algebraico | tipo Opcion = Alguno(Entero) | Ninguno |
Rasgo { nombre, metodos } | Declaración de rasgo (interfaz) | rasgo Mostrable { ... } |
Implementacion { rasgo_nombre, clase_nombre, metodos } | Implementación de rasgo para una clase | implementar Mostrable para Persona { ... } |
Control de flujo
| Variante | Descripción | Ejemplo Forja |
Si { condicion, bloque_verdadero, bloque_falso } | Condicional con rama opcional sino | si cond { ... } sino { ... } |
Mientras { condicion, bloque } | Bucle mientras condicional | mientras cond { ... } |
Para { inicializacion, condicion, incremento, bloque } | Bucle para estilo C | para (variable i = 0; i < 10; i = i + 1) { ... } |
Repetir { cantidad, bloque } | Bucle con cantidad fija de repeticiones | repetir 5 { ... } |
Cuando { condicion, cuerpo, linea, columna } | Bloque reactivo/observador (cuando una condición cambia) | cuando x > 10 { ... } |
Retornar { valor } | Retorno de valor de función | retornar 42 |
Romper | Rompe el bucle actual | romper |
Continuar | Continua con la siguiente iteración del bucle | continuar |
Módulos y otros
| Variante | Descripción | Ejemplo Forja |
Importar(String) | Importación de módulo | importar math o importar "/ruta/absoluta" |
ImportarExterna(String) | Cargar librería externa (FFI) | importar externa "libreria.dll" |
LlamadaFuncion { nombre, argumentos } | Llamada a función como statement | escribir("hola") |
AccesoMiembro { objeto, miembro } | Acceso a miembro como statement | objeto.metodo() |
Expresion(Expresion) | Expresión usada como statement (ej: efecto secundario) | x + 1 |
Métodos auxiliares
Declaracion::es_externa()
| Firma | Descripción |
pub fn es_externa(&self) -> bool | Retorna cierto si la declaración es una función externa (FFI), es decir, Declaracion::Funcion { externa: true, .. } |
Pipeline de compilación
El AST es el centro del pipeline del compilador Forja:
- Código fuente → lexer produce tokens
- Tokens → parser construye el AST (
Programa) - AST → análisis semántico (resolución de nombres, verificación de tipos)
- AST → generación de bytecode o código nativo (ASM/LLVM)
- AST → formateo de código (formatter.rs recorre el AST)
- AST → transpilación a otros lenguajes
Diagrama de relación
┌─────────────┐ ┌─────────────┐ ┌──────────────────┐
│ lexer.rs │────▶│ parser.rs │────▶│ ast.rs (AST) │
└─────────────┘ └─────────────┘ └────────┬─────────┘
│
┌─────────────────────────────┼─────────────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ semantica.rs │ │ bytecode.rs │ │ formatter.rs │
│ (verificación) │ │ (generación) │ │ (formateo) │
└─────────────────┘ └────────┬─────────┘ └──────────────────┘
│
┌────────────┼────────────┐
│ │ │
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ compiler_ │ │ compiler_ │ │ vm_jit.rs / │
│ asm.rs │ │ llvm.rs │ │ vm_fast.rs │
└────────────┘ └────────────┘ └────────────┘