Translate

Mostrando las entradas con la etiqueta LLVM. Mostrar todas las entradas
Mostrando las entradas con la etiqueta LLVM. Mostrar todas las entradas

martes, 5 de mayo de 2026

Crear un mini lenguaje que compile a LLVM IR (paso a paso)


En el post anterior vimos qué es LLVM y por qué cambió la forma de construir compiladores.


Ahora vamos a lo interesante: crear un mini lenguaje propio y compilarlo a LLVM IR

Vamos a construir un lenguaje súper simple que permita esto:

sum(10, 20)


Y lo transforme en LLVM IR listo para compilar.

Nuestro “compilador” va a tener:

  • Parser (muy básico)
  • AST (árbol)
  • Generador de LLVM IR


Paso 1: Definir el lenguaje


Nuestro lenguaje soporta:

Función: sum(a, b)

Números enteros


Ejemplo válido:

sum(4, 5)


Paso 2: Representar el AST

En pseudocódigo:

java id="y0yqg3"

interface Expr {}


class Number implements Expr {

    int value;

}


class Sum implements Expr {

    Expr left;

    Expr right;

}


Paso 3: Parser (ultra simple)


Para simplificar, parseamos a mano:

java id="x7p0a1"

Expr parse(String input) {

    // sum(10,20)

    String inside = input.substring(4, input.length() - 1);

    String[] parts = inside.split(",");


    return new Sum(

        new Number(Integer.parseInt(parts[0])),

        new Number(Integer.parseInt(parts[1]))

    );

}


Sí, es naive, pero suficiente para entender el flujo


Paso 4: Generar LLVM IR

Acá está la magia 💣


java id="l6c0qw"

String generate(Expr expr) {

    if (expr instanceof Sum s) {

        return """

        define i32 @main() {

            %a = add i32 %d, %d

            ret i32 %a

        }

        """.formatted(

            ((Number)s.left).value,

            ((Number)s.right).value

        );

    }

    throw new RuntimeException("Unsupported");

}


Resultado

Entrada:

sum(10, 20)


Salida:

llvm id="0a8v8l"

define i32 @main() {

  %a = add i32 10, 20

  ret i32 %a

}


Ya es LLVM IR válido


Paso 5: Ejecutarlo

Guardás el archivo como main.ll y usás:


bash id="3e7twz"

lli main.ll


o lo compilás con:


bash id="z4c9yb"

llc main.ll


Aunque el ejemplo es simple, reproduce el flujo real:

1. Texto → AST

2. AST → IR

3. IR → código ejecutable


Exactamente lo que hacen lenguajes como Rust o compiladores como Clang

Lo difícil NO es generar código máquina.

Lo difícil es definir bien el lenguaje y su semántica.


LLVM te resuelve:

  • optimización
  • portabilidad
  • generación de código



miércoles, 15 de abril de 2026

¿Qué es LLVM? Introducción a la infraestructura detrás de los compiladores modernos


Si alguna vez te preguntaste cómo lenguajes como Rust o Swift generan código tan eficiente…

La respuesta probablemente sea: LLVM. LLVM no es un compilador tradicional es una infraestructura para construir compiladores.


Durante años, herramientas como GCC siguieron este modelo:

  • Todo en uno (frontend + optimización + backend)
  • Difícil de extender
  • Costoso crear nuevos lenguajes


Resultado: crear un lenguaje era MUY complejo


LLVM cambia el enfoque: Separar el compilador en piezas reutilizables


¿Cómo funciona LLVM?

El proceso se divide en 3 partes:

Frontend

  • Convierte tu lenguaje a LLVM IR
  • Cada lenguaje define su frontend


LLVM IR (Intermediate Representation)

Es el corazón del sistema:

  • Representación intermedia
  • Independiente del hardware
  • Optimizable


Ejemplo:

llvm id="u7j1k0"

define i32 @main() {

  %1 = add i32 10, 20

  ret i32 %1

}


Un “lenguaje común” entre todos los compiladores


Backend

Convierte el IR en código máquina:

  • x86
  • ARM
  • RISC-V

LLVM se encarga de esto


¿Por qué es tan importante? Porque reduce drásticamente la complejidad:

Antes: Lenguaje = compilador completo

Ahora: Lenguaje = frontend + LLVM


LLVM es muy usado, entre los lenguajes que lo usan podemos encontrar:

  • Rust
  • Swift
  • C/C++ con Clang
  • Kotlin Native


LLVM separa responsabilidades:

  • Lenguaje → Frontend
  • Optimización → LLVM
  • Hardware → Backend


Esto permite innovación más rápida y reutilización masiva

LLVM es el motivo por el cual hoy crear un lenguaje es mucho más accesible que antes.

viernes, 24 de febrero de 2023

Programación poliglota con GraalVM parte 2


Seguimos con GraalVM 

Veamos un ejemplo queremos ejecutar una aplicación javascript o node que dentro llama a codigo ruby, por ejemplo. 

Vamos a tener que crear un archivo .js que lo llamaré ejemplo.js que contenga lo siguiente: 


var array = Polyglot.eval("ruby", "[1,2,42,4]")

console.log(array[2]);


Y lo ejecutamos con : 


js --polyglot --jvm ejemplo.js

42

node --polyglot --jvm ejemplo.js

42


Así de fácil o queremos ejecutar en una aplicación R, javascript :

array <- eval.polyglot("js", "[1,2,42,4]")
print(array[3L])

Y lo corremos con : 

Rscript --polyglot --jvm ejemplo.R
[1] 42

Y puedo seguir con ejemplos pero creo que se entiende :D


Dejo link : https://www.graalvm.org/reference-manual/polyglot-programming/#running-polyglot-applications