BookinglyTech News
Software

Singeli declara estable su núcleo: un DSL sobre BQN para exprimir SIMD

El lenguaje, implementado en BQN, ya acumula 5.000 líneas en producción dentro de CBQN y afronta ahora su parte menos pulida: los includes estándar de SIMD.

2 min de lecturaLobsters0 vistas

Singeli es un lenguaje específico de dominio para construir algoritmos de altas prestaciones, SIMD incluido, con abstracciones flexibles sobre código que corresponde a instrucciones individuales. Su autor da por estable el núcleo y considera que el proyecto, con 5.000 líneas en producción dentro de CBQN, ya es usable.

La implementación está escrita en BQN. El frontend emite IR y el backend lo traduce a C; el IR es lo bastante simple como para que añadir otros backends, LLVM o código máquina, no suponga mucho trabajo. Los cambios de ruptura que ha habido se hicieron con un periodo de deprecación de unos seis meses, y a partir de ahora la intención es no tocar el núcleo: si aparece un diseño mejor para algo, se sacará un include nuevo antes que romper lo que ya funciona.

Compilar y depurar

singeli input.singeli -o output.c genera el C. Para ejecutar Singeli directamente hay que tener CBQN instalado como bqn en el PATH, o invocarlo como /path/to/bqn singeli ....

Los errores de compilación llegan con traza de parseo o de pila, y show{} imprime lo que se le pase en tiempo de compilación. En ejecución, lprintf{} del include 'debug/printf' hace lo propio. El C emitido es verboso, pero conserva los nombres de funciones y variables del fuente, lo que ayuda a orientarse. Para no pelearse con el ciclo compilar-depurar está el playground interactivo, y singeli-lsp aporta parseo y resolución de nombres en el editor.

El modelo

Singeli es ante todo un lenguaje de metaprogramación: el código hace cosas complicadas en compilación para emitir programas que en ejecución hacen cosas relativamente simples. La herramienta básica es el generador, escrito con {parámetros}, que cubre un terreno parecido al de las macros de C o las plantillas de C++, pero con más margen. Se expanden durante la compilación, tienen alcance léxico, admiten recursión y forman un lenguaje Turing completo. Los operadores no vienen de serie: cada uno se declara como infijo o prefijo apuntando a un generador, con su precedencia y su asociatividad.

Los tipos usan la sintaxis valor:tipo en lugar de tipo valor, y las funciones se declaran con fn. Tampoco hay una única construcción for: el lenguaje ofrece un mecanismo general para definir bucles y luego una sintaxis @for que recorre punteros convirtiéndolos en valores dentro del cuerpo y solo escribe en memoria si el valor cambió.

Lo que todavía no está a la altura son los includes estándar, sobre todo en las instrucciones SIMD más sofisticadas. Es la parte que el propio autor señala como menos sólida, y la que marca cuánto se puede escribir sin bajar a mano a la instrucción concreta.