Dash
Escribe código limpio, sintetiza ejecutables nativos.
Un lenguaje de alto nivel para el Amiga, con una sintaxis que se lee como Ruby o Python. Se traduce a C y se compila en tu PC a un ejecutable de 68k: sin intérprete ni máquina virtual en el Amiga.
De tu código a un ejecutable de 68k
Tres programas de verdad. Lo que escribes, el C que genera Dash (un fragmento) y lo que sale en el Amiga.
- Dash
- C
- m68k-amigaos-gcc
- Amiga
Window MiVentana
title "Hola Dash"
width 400
height 150
end
Main
MiVentana.open
EventLoop
On Close
Print "Adiós!"
Stop
end
end
end// User Code
win_MiVentana = OpenWindowTags(NULL,
WA_Left, 50, WA_Top, 50,
WA_Width, 400, WA_Height, 150,
WA_Title, (ULONG)"Hola Dash",
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_SizeGadget, FALSE,
WA_Borderless, FALSE,
WA_Activate, TRUE,
WA_MinWidth, 40, WA_MinHeight, 20,
WA_MaxWidth, (ULONG)~0, WA_MaxHeight, (ULONG)~0,
WA_GimmeZeroZero, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW,
_dash_screen ? WA_CustomScreen : TAG_IGNORE, (ULONG)_dash_screen,
TAG_DONE);
if (!win_MiVentana) _dash_exit(20);
_dash_win = win_MiVentana;
_dash_rp = win_MiVentana->RPort;
{
BOOL running = TRUE;
struct IntuiMessage *msg;
ULONG msg_class;
UWORD msg_code;
ULONG _dash_tmev = _dash_tmp_mark();
while (running) {
_dash_tmp_release(_dash_tmev); /* temporaries of the previous messages */
WaitPort(win_MiVentana->UserPort);
while (win_MiVentana && (msg = (struct IntuiMessage *)GetMsg(win_MiVentana->UserPort))) {
msg_class = msg->Class;
msg_code = msg->Code;
(void)msg_code;
ReplyMsg((struct Message *)msg);
switch (msg_class) {
case IDCMP_CLOSEWINDOW: {
Printf("Adi\363s!\n");
running = FALSE;
}
break;
}
}
}
if (win_MiVentana) {
if (_dash_win == win_MiVentana) _dash_win = NULL;
_dash_before_close(win_MiVentana);
CloseWindow(win_MiVentana);
win_MiVentana = NULL;
}
_dash_tmp_release(_dash_tmev);
Una ventana con su bucle de eventos. El ejecutable entero, con su runtime, ocupa esto:
5 KB de ejecutable
const ID_SALUDA = 1
const ID_LIMPIA = 2
Main
if mui_app_begin("Hola MUI", "HOLAMUI") == 0
Print "No se puede usar MUI"
else
win = mui_window_begin("Hola MUI", 1)
saludo = mui_text("\33cPulsa un botón")
mui_hgroup_begin()
saluda = mui_button("_Saluda")
limpia = mui_button("_Limpia")
mui_group_end()
mui_window_end()
mui_on_press(saluda, ID_SALUDA)
mui_on_press(limpia, ID_LIMPIA)
mui_window_open(win)
veces = 0
while true
ev = mui_wait_event()
if ev == -1
break
end
if ev == ID_SALUDA
veces = veces + 1
Print "Hola número #{veces}"
end
if ev == ID_LIMPIA
veces = 0
Print "A cero"
end
end
mui_app_end()
end
end// User Code
if (((LONG)_dash_mui_app_begin("Hola MUI", "HOLAMUI") == 0)) {
Printf("No se puede usar MUI\n");
} else {
LONG win = (LONG)_dash_mui_window_begin("Hola MUI", 1);
LONG saludo = (LONG)_dash_mui_text("\33cPulsa un bot\363n");
(void)((LONG)_dash_mui_group_begin(1));
LONG saluda = (LONG)_dash_mui_button("_Saluda");
LONG limpia = (LONG)_dash_mui_button("_Limpia");
_dash_mui_group_end();
_dash_mui_window_end();
_dash_mui_on_press((APTR)saluda, ID_SALUDA);
_dash_mui_on_press((APTR)limpia, ID_LIMPIA);
(void)(_dash_mui_window_open((APTR)win));
LONG veces = 0;
{ ULONG _dash_tm1 = _dash_tmp_mark();
while (TRUE) {
_dash_tmp_release(_dash_tm1);
LONG ev = _dash_mui_wait_event();
if ((ev == (-1))) {
break;
}
if ((ev == ID_SALUDA)) {
veces = (veces + 1);
Printf("%s\n", DashString_concat("Hola n\372mero ", DashString_from_int(veces)));
}
if ((ev == ID_LIMPIA)) {
veces = 0;
Printf("A cero\n");
}
}
_dash_tmp_release(_dash_tm1); }
_dash_mui_app_end();
}
_dash_exit_cleanup();
Una ventana MUI con dos botones y sus atajos de teclado. MUI 3.8 o 5.
9.1 KB de ejecutable
Window Caja
title "Gravedad con Fixed"
width 320
height 200
end
const SUELO = 180
struct Bola
x: Fixed
y: Fixed
vx: Fixed
vy: Fixed
color: Int
func mover(g: Fixed)
self.vy = self.vy + g
self.x = self.x + self.vx
self.y = self.y + self.vy
if self.y > SUELO
self.y = SUELO
self.vy = -self.vy * Fixed(0.85) # loses some speed at each bounce
end
if self.x < 8 or self.x > 300
self.vx = -self.vx
end
end
func dibujar()
gfx_pen(self.color)
gfx_circle_fill(Int(self.x), Int(self.y), 6)
end
end
Main
Caja.open
g = Fixed(0.35)
bolas = [Bola(20, 10, Fixed(1.5), 0, 1), Bola(60, 30, Fixed(-1.25), 0, 2),
Bola(110, 5, Fixed(0.75), 0, 3), Bola(160, 50, Fixed(2.2), 0, 1),
Bola(220, 20, Fixed(-0.6), 0, 2), Bola(280, 40, Fixed(1.1), 0, 3)]
corriendo = true
while corriendo
for b in bolas
gfx_pen(0)
gfx_circle_fill(Int(b.x), Int(b.y), 6)
b.mover(g)
b.dibujar()
end
wait_vblank()
if window_check_close()
corriendo = false
end
end
endstatic void Bola_mover(_Dash_Bola *self, DashFixed g) {
self->vy = (self->vy + g);
self->x = (self->x + self->vx);
self->y = (self->y + self->vy);
if ((self->y > ((DashFixed)(LONG)(SUELO) << 16))) {
self->y = ((DashFixed)(LONG)(SUELO) << 16);
self->vy = _dash_fx_mul((-self->vy), ((DashFixed)55706));
}
if (((self->x < ((DashFixed)524288)) || (self->x > ((DashFixed)19660800)))) {
self->vx = (-self->vx);
}
}
Bolas que caen y botan con números de coma fija: la gravedad, 0,85 al rebotar… y en C, enteros. En un 68000, multiplicar en Fixed es 2,6 veces más rápido que en Float.
8.8 KB de ejecutable
581 funciones para todo el Amiga
Ventanas, gráficos, sonido, red y el sistema, sin escribir C y sin acordarte de qué librería abrir:
- Interfaz
- Intuition, GadTools, ReAction y MUI 3.8 o 5 (con zona de dibujo con doble búfer).
- Gráficos
- Copper, Blitter y BOBs, sprites de hardware y por software, doble búfer, RTG (CyberGraphX y Picasso96), y IFF, PNG, JPEG o GIF por datatypes.
- Red
- TCP y UDP, y HTTPS con AmiSSL 5.1 que reanuda la sesión TLS.
- El lenguaje
- Tipos inferidos, structs con métodos, lambdas, listas y diccionarios con tipo, Float y Fixed 16.16, módulos. Memoria por contador de referencias: sin recolector y sin pausas.
- Si hace falta
- C dentro del código (@native, @c) y enlazar librerías (@link).
- MUI82
- ReAction79
- Tareas en otro proceso58
- Intuition46
- Gráficos avanzados43
- Entrada30
- Gráficos29
- Sistema26
- Red (TCP)24
- DOS24
- RTG21
- Audio21
- GadTools19
- Texto18
- Menús, búferes, TLS, fuentes y más61
Con VS Code
La extensión «Dash for Amiga» colorea el código, marca los errores mientras escribes, completa, va a la definición y formatea. Compila y ejecuta en FS-UAE o Amiberry, depura con F5 (también en un Amiga de verdad, por la red) y trae un editor visual de ventanas MUI.
Se instala desde el fichero .vsix de su página en GitHub (versión 0.2.1).

Hecho con Dash
Dash crece con programas de verdad: lo que les falta se añade al lenguaje, y luego lo tiene cualquiera.
Qué necesitas
- En el Amiga
- AmigaOS 3.0 o posterior; un 68000 basta. MUI y HTTPS piden un 68020.
- En tu PC
- Linux, macOS o WSL2, con Python 3.10, la librería Lark y el compilador cruzado m68k-amigaos-gcc. Dash compila en el PC: no en el Amiga.
Tachyon
Trasfondo