English | Castellano
Development Amiga Synthesis Hub
A high-level programming language for the Commodore Amiga: its compiler makes the Amiga executable itself, on the PC or on the Amiga itself, and when asked it goes through C with the Amiga gcc.
Write clean code, synthesise native executables.
Current version: 2.0.1 (./dash --version). What each number means and what each version brings: docs/VERSIONES.en.md.
./dash Source (.dash) → Dash compiler → 68000 code + runtime → executable (hunk)
./dash --gcc Source (.dash) → Parser (Lark) → AST → Analyzer → CodeGen → C → GCC → executable (hunk)
Programming the Amiga in C means manual memory management, pointers, endless includes and knowing the AmigaOS API inside out. Dash removes that friction: a clear syntax inspired by Ruby/Python, inferred types and direct access to Intuition, Graphics, Audio, Sprites, Copper and more.
The result is a native m68k binary. No interpreters, no VM, no compromise.
Window MiVentana
title "Hola Dash"
width 400
height 150
end
Main
MiVentana.open
EventLoop
On Close
Print "Adiós!"
Stop
end
end
end./dash examples/hola.dash -o bin/hola- Variables with type inference (no declarations)
- Integers (also
0xDFF000,$DFF000,0b1010),Float(its own floating point) andFixed(16.16 fixed point: decimals at integer speed on a 68000) nilfor structs, lists and strings (linked lists, trees, "no target")- Arithmetic, logical, comparison and bitwise expressions (
& | ^ ~ << >>, also inconst) - Control flow:
if/elif/else,while,for/in,for/range(also descending and withstep),breakandcontinue - Functions with parameters, return values and recursion; functions as values and lambdas
- Lists with literals, indexing, slicing,
.lengthand an element type ([String],[Nodo]...) that grow (push,pop,insert,remove); dictionaries{String: T}, also of lists and of dictionaries, withd.get(clave, defecto)(a single lookup); the functions and methods that return lists or dictionaries keep the type of their elements - Strings with interpolation of any expression (
"#{a + 1}","#{f(x)}"), efficient concatenation and functions (str_find,str_replace,str_split,str_upper...); aBoolis written astrue/false - Structs with methods,
weakfields for back references - Constants and enumerations
- Module imports, and imports of MUI windows made with the visual editor (
.dashui); anything starting with_in a module (functions, constants, globals, structs, enums) is private and does not clash with another module - Lexical scope
- Automatic memory: strings, lists and structs free themselves (per-iteration temporaries and reference counting), with no garbage collector and no pauses
AmigaOS 3 has no memory protection: in C, a null pointer or a division by zero takes the whole system down. A Dash program, on the other hand, stops with a message and leaves the Amiga as it was:
nilfields: reading or writing a field of a struct that isnil, or calling one of its methods, givesError: campo de nil (en juego.dash:42). Without that check, the read would return garbage and the write would go to address 0, where the processor's vectors live.- Processor exceptions: odd address, illegal instruction, division by zero, CHK, TRAPV... (what in C is a
Guru, usually from
@nativecode or from a library that gets a bad pointer). Each program installs its own handler in its task (tc_TrapCode) and, instead of the Guru, says which exception it was and where in the executable.
In both cases the program does its usual cleanup (it closes its windows, screens and libraries and frees its memory) and exits with return code 20; from the Workbench, the message comes up in a requester. It works on any Amiga, even a 68000 with no MMU, and it costs little: Tachyon (30,000 lines) grows by 0.1%. What it can't prevent is a write through a wild pointer in your own C code, which can break another part of the system without anyone noticing. Details in the manual ("Runtime errors").
836 built-in functions, all implemented (list generated from the code in docs/BUILTINS.en.md).
- Intuition — Windows, screens, event loops (also across several windows), menus,
On Click,On Timer;window_createwith the inner size (flag 8) and the window borders (window_border_top...) and the screen font (screen_font_height,screen_font_text_width) for placing gadgets - Interfaces — GadTools (with keyboard shortcuts and gadgets measured with the font), ReAction (up to 4
windows) and MUI 3.8 or 5: a drawing area of its own (with double buffering, fills, repainting just one area with
mui_canvas_update_areaand the mouse without clicking withmui_canvas_on_moveandmui_canvas_pointer_x/_y), timer, signals and full-screen windows (with MUI 3.8 a frame of 4 and 3 pixels remains around them); visual editor for MUI windows for VS Code - Graphics — Drawing primitives, colors, bitmaps, transparency and gradients (fast on RTG too), RGB24 buffers in the window (also scaled: video)
- Sprites — Hardware sprites and soft sprites
- Copper — Programmable copper lists
- Blitter — BOBs and blitting operations
- Audio — Tones, 8SVX samples and sounds built sample by sample (
audio.device), and ProTracker modules (music_*, its own player) - IFF and datatypes — ILBM, PNG, JPEG, GIF images, or from RGB/RGBA pixels in memory (with
transparency, also on RTG and without
picture.datatype; on RTG, real alpha: they blend with what lies beneath), with no limit on images at once (previously 64); disk fonts, including outline fonts (minimum size 2: with 1 or 0, AmigaOS 3.2's diskfont and bullet write outside their memory), and RGB colors - Network — With
bsdsocket.library(any stack: Roadshow, AmiTCP, MiamiDx): TCP as client and as server (net_listen,net_accept), UDP with broadcast (net_udp_*) and TLS with AmiSSL (5.1 or later, or earlier ones) that checks the certificate; step-by-step connections, without waiting; the TLS session with each server is resumed on the next connection;net_signalwakes the program when the network has something; the network also from atask_starttask. HTTP is not a builtin: each program implements it over TCP and TLS - Processes —
task_start: a@nativefunction in another AmigaOS process;task_signalsignals when it finishes - Desktop and system —
desktop_canvas*: drawing on the Workbench backdrop, behind the icons (planar and RTG, with and without backdrop; also with Directory Opus 5 or Scalos as the desktop);cpu_*: the CPU use of each task;break_check: stopping a windowless program with Ctrl-C;single_instance: only one copy at a time;@workbench_output "NIL:": no console window when started from the icon;tooltype; commodities (cx_broker,cx_hotkey,cx_command,cx_wait: the program in Exchange and with a hotkey);run_programandprogram_relaunch;@version(forC:Version) andprogram_version() - Monitors — Mounted disks with their size and free space (
disks_read); Roadshow network interfaces with their state and bytes (net_ifs_read); SANA-II drivers in use, with any stack, with their packets and bytes (net_drivers_read,net_driver_read); WiFi signal (wifi_read,wifi_read_device); Poseidon USB devices (usb_hid_*); acceleration curve of each mouse (mouse_curve) and the mouse preferences - Languages, date and time —
locale.librarycatalogs:@catalog "X.catalog",tr(id, texto)(also in.dashuifiles),catalog_open;tools/catalogo.pymakes the.cd,.ctand.catalogfiles without FlexCat.clock_readandclock_year...clock_second;date_text(formato)withFormatDatein the user's language - DOS — Files and directories, ASL requesters (file, color, font), arguments and tooltypes,
watching files (
file_notify,file_changed) - RTG — Graphics cards with CyberGraphX or Picasso96 (
rtg_*: screens, pixels, blocks, scaling) - Double Buffering — Flicker-free animation
- FFI — Direct calls to C/AmigaOS functions; your own C inline (
@native,@c) or linked (@link), with its headers (@header) and declared C functions (@extern)
Programs need Kickstart 3.0 or higher (they use exec V39 memory pools) and run on
a 68000. MUI (3.8 or 5) and TLS (AmiSSL 5.1 or later) require a 68020 or higher. Some functions require
more: networking, a TCP/IP stack; net_ifs_read and wifi_read, Roadshow; usb_hid_*, Poseidon; ReAction, the
AmigaOS 3.2 classes.
- HTTP as a builtin: each program implements it over TCP and TLS.
- Raw sockets (ICMP, for a ping) or raw frames from a SANA-II driver: for now, with
@native. - Classes (OOP) and macros: these are open questions, undecided.
- Exports: deliberately ruled out.
- Tachyon (formerly dashweb): a web browser for the Amiga with MUI: XHTML, CSS, JavaScript (QuickJS) and HTTPS. It is the largest project written in Dash, and whatever it lacks gets added to Dash. It has alpha test versions in its releases.
- Trasfondo: a resource monitor (date and time, CPU, memory, tasks, disks, network and WiFi) painted on the Workbench backdrop, behind the icons; it is a commodity. Versions in its releases.
- Ratonera: per-device mouse acceleration (
mouse_curve,usb_hid_*), in development.
The extension in editor/vscode turns VS Code into an environment for Dash: syntax coloring, errors as you type,
completion, go to definition and rename; compiling and running on the emulated Amiga (A1200, A500, AmigaOS 3.2 or
with a graphics card); debugging with breakpoints, variables and stepping, also on a real Amiga over the
network; and a visual editor for MUI windows that shows them in the emulator. It uses the compiler from this repository.
The published version is 0.3.0, which tells you when a new version of Dash is out.
A 6-minute tutorial, with subtitles: the first project, writing code, the window, compiling and running, debugging and debugging on a real Amiga.
- Dash, as in Installation (for
--gccand programs with C, bebbo's gcc too; for the emulator, FS-UAE and a Kickstart ROM; for MUI windows,tools/get_mui_sdk.shandtools/emu_sys_mui.sh). - The extension: the file
dash-mui-editor-0.4.0.vsixfrom the release, and in VS Code (1.86 or later) Extensions: Install from VSIX..., orcode --install-extension dash-mui-editor-0.4.0.vsix. It can also be built:cd editor/vscode && npm install && npm run package. - A project: Dash: Nuevo proyecto. If its folder is not inside this repository, Dash: Elegir la
carpeta del compilador (the
dash.pathsetting). The Primeros pasos con Dash walkthrough guides you step by step, and if something is missing the extension says what and how to get it.
The extension is a thin layer: what it does is done by the tools in this repository, in the
dash.path folder.
| In VS Code | Done by |
|---|---|
| Syntax coloring | editor/vscode/syntaxes/dash.tmLanguage.json, generated from the grammar (tools/gen_tmgrammar.py) |
| Errors as you type, completion, go to definition, rename, format | compiler/lsp.py (the same compiler) |
| Compile | ./dash |
| Run, memory and profile | ./dash and tools/emu_run.py (FS-UAE or Amiberry) |
| Visual editor and Ver en Amiga | .dashui (compiler/dashui.py) and tools/emu_preview.py |
| Debug (F5) | ./dash --debug, tools/emu_run.py --dbgserver and tools/amiga/dbgserver.dash; with C in the program, ./dash --gcc --debug, tools/emu_run.py --gdbserver, m68k-amigaos-gdb with tools/gdb/dash.py and bgdbserver |
That is why, when you update Dash (git pull), what the extension knows about the language is updated too, without
reinstalling it. The extension and the compiler live in the same repository so that they do not drift apart.
Dash compiles in two ways, with the same command:
Straight to hunk (./dash) |
Through C with gcc (./dash --gcc) |
|
|---|---|---|
| What it does | Dash's compiler generates the 68000 code and the executable (hunk) itself | The program becomes C and bebbo's Amiga gcc builds it |
| What it needs | A C compiler for the PC, make and Python 3 |
Also the Amiga gcc (30 minutes to 2 hours to build) and Lark |
| Where it runs | On the PC (Linux, macOS) and on the Amiga itself | On the PC |
| What for | Any program in Dash | Programs with C inside (@native, @c, @header) and gcc's options (-O, -O0, --small, --multifile, --no-hunk) |
The straight one is the usual one: it is all you need to start. The C path is installed apart, only if you need
it. When a program has C in it, or asks for a gcc option, ./dash takes it through C by itself and says so in a
line.
# Ubuntu / Debian
sudo apt install -y git make gcc python3
# CachyOS / Arch Linux
sudo pacman -S --needed git make gcc python
git clone --branch v2.0.1 https://github.com/FreeMEM/dash.git
cd dash
make -C dashc # Dash's compiler, in a few seconds
./dash examples/hola.dash -o bin/holaTo try programs without an Amiga: FS-UAE (sudo apt install fs-uae or sudo pacman -S fs-uae), a Kickstart ROM
in $DASH_KICKSTART and python3 tools/emu_run.py bin/hola.
xcode-select --install # Apple's clang, make, git and Python 3
git clone --branch v2.0.1 https://github.com/FreeMEM/dash.git
cd dash
make -C dashc
./dash examples/hola.dash -o bin/holaFS-UAE for macOS: brew install --cask fs-uae. The compiler builds the same with gcc and with clang (checked on
Linux: the same executables, byte for byte), but it hasn't been tried on a Mac yet; if something fails, please
open an issue.
The compiler also runs on the Amiga itself (68000, AmigaOS 2.0 or later). The
releases have dash-2.0.1-amiga.lha: unpack it, and its Instalar
copies the Dash drawer (the dash command, its runtimes, lib/ and the examples) and adds the DASH: assign and
the Path to S:User-Startup. Then, from a Shell:
dash DASH:examples/hola.dash -o RAM:hola
RAM:hola
With the same source, the executable comes out identical to the one ./dash makes on the PC. There is no --gcc
on the Amiga.
It needs bebbo's Amiga gcc and the Lark parser, on the same PC where ./dash already works. Besides programs with
C, this path looks ahead: gcc can generate PowerPC code, and that is the way to compiling for MorphOS and
AmigaOS 4.
# 1. System dependencies
sudo apt update
sudo apt install -y python3 python3-pip python3-dev make wget curl openssl git gcc g++ \
lhasa libgmp-dev libmpfr-dev libmpc-dev flex bison \
gettext texinfo ncurses-dev autoconf rsync libreadline-dev
# 2. Dash's parser
pip install lark --break-system-packages
# 3. Amiga cross-compiler (m68k-amigaos-gcc)
git clone https://github.com/BlitterStudio/m68k-amigaos-gcc.git ~/m68k-amigaos-gcc
cd ~/m68k-amigaos-gcc
make update
sudo mkdir -p /opt/amiga && sudo chown $USER /opt/amiga
make all -j$(nproc)
make sdk=cgx # CyberGraphX headers (rtg_* functions)
# 4. Add it to the PATH
echo 'export PATH="/opt/amiga/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# 5. Try it (in Dash's folder)
./dash --gcc examples/hola.dash -o bin/hola# 1. System dependencies
sudo pacman -S --needed python python-pip make wget curl openssl git gcc \
lhasa gmp mpfr libmpc flex bison gettext texinfo \
ncurses autoconf rsync readline
# 2. Dash's parser
pip install lark --break-system-packages
# 3. Amiga cross-compiler (m68k-amigaos-gcc)
git clone https://github.com/BlitterStudio/m68k-amigaos-gcc.git ~/m68k-amigaos-gcc
cd ~/m68k-amigaos-gcc
make update
sudo mkdir -p /opt/amiga && sudo chown $USER /opt/amiga
make all -j$(nproc)
make sdk=cgx # CyberGraphX headers (rtg_* functions)
# 4. Add it to the PATH
echo 'export PATH="/opt/amiga/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# 5. Try it (in Dash's folder)
./dash --gcc examples/hola.dash -o bin/holaBuilding the cross-compiler takes between 30 minutes and 2 hours depending on your hardware. See docs/INSTALACION.md for the full guide, troubleshooting and advanced options (macOS, GCC versions, elf2hunk).
./dash archivo.dash -o bin/archivo # straight to hunk
./dash --fpu --memcheck archivo.dash -o bin/archivo
./dash --gcc archivo.dash -o bin/archivo # through C with gcc
./dash --gcc -O0 archivo.dash -o bin/archivo # gcc's options (with them it goes through C even without --gcc)
make -C dashc amiga # the compiler for the Amiga (with bebbo's gcc)The language, the builtins and what programs do are the same on both paths. --fpu, --cpu, --memcheck,
--stack and --debug work with both. The straight one takes no C inside the program (@native, @c,
@header) and none of the options -O, -O0, --small, --multifile and --no-hunk: with them, ./dash
takes the program through C by itself and says so ("dash: el programa lleva C: se compila por C con gcc").
--debug prepares the program for the debugger of the dbg_* builtins, VS Code's; a program with C is debugged
with gdb.
Outside C also works without --gcc: it is compiled apart with the Amiga gcc and linked. @link names the object
or library, @extern declares its functions and @export marks the Dash functions that C calls by name.
@link "c/saludo.o"
@extern("saludo") func suma(a: Int, b: Int) -> Int
@export func triple(x: Int) -> Int
return x * 3
endAll about the straight compiler (options, @extern types, the Amiga compiler and when to use --gcc) is in the
reference manual, section 24.
# Compile to an Amiga executable (straight to hunk; with --gcc, through C with gcc -O2)
./dash archivo.dash -o bin/archivo
# Unoptimized (easier to debug)
./dash -O0 archivo.dash -o bin/archivo
# For the debugger (gdb, VS Code): -O0 -g and the C lines point to the .dash
./dash --debug archivo.dash -o bin/archivo
# Quiet: only warnings, errors and the result (not every command and step)
./dash -q archivo.dash -o bin/archivo
# Smaller (gcc -Os): ~7 % smaller, 10-50 % slower in loops
./dash --small archivo.dash -o bin/archivo
# Minimum program stack (16 KB by default; 0 = whatever the shell gives, 720 bytes less)
./dash --stack 32768 archivo.dash -o bin/archivo
# For Amigas with a 68881/68882 FPU (Float with FPU instructions; 68020+)
./dash --fpu archivo.dash -o bin/archivo
# For accelerated Amigas: code for that CPU or better (68020, 68030, 68040, 68060); it will not start on a lower one
./dash --cpu 68040 archivo.dash -o bin/archivo
# Memory check: warns about double frees and use after free, and about what is still alive at exit
./dash --memcheck archivo.dash -o bin/archivo
# Profile: calls and time (own and total) of each function at exit
./dash --profile archivo.dash -o bin/archivo
# Run in FS-UAE without a window and see the output (Kickstart in $DASH_KICKSTART or AROS)
tools/emu_run.py archivo.dash
tools/emu_run.py --autoclose 3 ventana.dash # closes by itself after 3 s
tools/emu_run.py --autoclose 30 --screenshot 20 shot.png ventana.dash # screenshot after 20 s
tools/emu_run.py --debug r archivo.dash # at each debug_break(), the registers (FS-UAE debugger)
# Compile all the examples
./compile_all.sh
# Only transpile to C (without compiling)
python3 -m compiler.main archivo.dash -o build/archivo.c
# Run tests (--emu: also those that check the output in FS-UAE; --emu-a500: also on an A500;
# --emu-32: also on an A1200 with AmigaOS 3.2, the only one that tests ReAction)
python3 tests/run_tests.py
python3 tests/run_tests.py --emu --emu-a500 --emu-32
# Measure speed, memory and size on an emulated A500 and A1200, and save the measurement
tools/bench.py --save "descripción del cambio"
tools/bench_report.py # data and page for the comparison dashboard (build/bench_report/)
# Random programs against reference counting: output compared with a model and --memcheck
tools/fuzz_refcount.py -n 100Test bench variables: DASH_KICKSTART (A1200 ROM), DASH_KICKSTART_A500 (A500 ROM),
DASH_EMU_SYS (directory with Libs, C and Classes from a Workbench, for the tests that need it; it
can be extracted from a hard disk with tools/emu_sys_from_hdf.sh), and for --emu-32 DASH_KICKSTART_32 (3.2 ROM)
and DASH_EMU_SYS_32 (the same files from a Workbench 3.2). On that machine the Workbench is loaded before
the programs (emu_run.py --workbench): the 3.2 window.class expects it. For MUI and HTTPS, the systems with
MUI (DASH_EMU_SYS_MUI, DASH_EMU_SYS_32_MUI) and with AmiSSL (DASH_EMU_SYS_SSL, DASH_EMU_SYS_32_SSL). The
# rtg tests use a 68040 machine with a graphics card and DASH_EMU_SYS_32_RTG (a Workbench 3.2 with
Picasso96). All of it in docs/INSTALACION.en.md.
dash Main CLI
compiler/ Transpiler (Python/Lark)
grammar.py Language grammar
transformer.py Parse tree → AST
ast_nodes.py AST nodes
analyzer.py Semantic analysis
codegen.py C code generation
amiga_builtins.py Amiga API bindings
dashui.py Visual editor windows (.dashui) as Dash code
lsp.py Language server for VS Code (with lsp_index.py and lsp_format.py)
debuglines.py ./dash --debug: C lines mapped to the .dash
lib/amiga/ Standard Amiga modules
runtime/softfloat/ Software floating point (addition and multiplication in 68000 assembly)
tools/ Emulator (emu_run.py, emu_preview.py, screenshots with tools/amiga/shot.c), emulated systems
(emu_sys_*.sh), MUI SDK, AmiSSL and bgdbserver (get_*.sh), debugger (gdb_relay.py,
gdb/dash.py), benchmarks (bench.py, bench_report.py), catalogs (catalogo.py),
fuzz_refcount.py, gen_builtins_doc.py, gen_tmgrammar.py
editor/vscode/ VS Code extension: syntax coloring, errors as you type, compiling, emulator, debugger, MUI
visual editor
examples/ Example programs (34)
tests/ Test suite (tests/errors: must fail; tests/runtime: runtime on the PC;
tests/lsp and tests/unit: Python tests; tests/bench: benchmarks)
docs/ Documentation
- Language documentation — Complete guide
- Reference manual — Programmer's reference
- Comparison with Blitz, AMOS and C — Speed, memory and stability measured on the A500 and A1200
- Quick Reference — Cheat sheet
- Built-in functions — The actual list, generated from the code
- Versions — What each number means and the notes of each version
- MUI in Dash — Design of the MUI API
- MUI visual editor — The
.dashuiformat and the VS Code extension - Amiga API — Design catalogue of the API (the original; the actual list is BUILTINS.en.md)
- Installation — Setting up the environment
- Functional requirements and system requirements — The original requirements, with what was done, what was ruled out and what is missing
- Roadmap — Development plan and log of what has been done
MIT (see LICENSE). Programs compiled with Dash can carry any licence you like.
The software float (runtime/softfloat/fp-bit.*) comes from GCC: GPL with the runtime exception,
which allows the programs to be distributed under any licence.
