aBelle – eine kleine Sprache, die du bis in den Maschinencode verfolgst

Geschrieben wie Python, übersetzt für Windows und das ESP32-Board, Zeile für Zeile debuggt in Asmonite.

aBelle hat wenige Wörter, drei Typen und keine verborgenen Regeln. Ihr Compiler ist selbst in aBelle geschrieben. Er schreibt den Maschinencode und die Programmdatei selbst, ohne Assembler und ohne Linker. In Asmonite drückst du F9: Das Programm wird übersetzt und läuft im Debugger, mit Breakpoints, Schritten durch die Zeilen und den Werten der Variablen.

aBelle liegt ab Asmonite 0.12.0 im ZIP: die drei Compiler abelle.exe, abelle64.exe und abelle_esp32.exe neben Asmonite.exe, die Beispiele in examples\abelle und die F1-Hilfe. Es gilt die Lizenz von Asmonite: kostenlos, und was du damit schreibst, gehört dir.

Zwei erste Programme

Links ein Programm für Windows: Es holt sich WriteFile aus kernel32.dll und schreibt auf die Konsole. Rechts eines für das ESP32-Board: Die Register des Chips sind Felder an ihrer Adresse, und die LED blinkt.

Windows
extern "kernel32.dll":
    def GetStdHandle(n: i32) u32
    def WriteFile(h: u32, buf: pchar, n: u32,
                  written: pchar, ov: u32) i32

written: char[4]

def strlen(s: pchar) i32:
    n = 0
    while s[n] != 0: n += 1
    return n

def print(s: pchar):
    WriteFile(GetStdHandle(-11), s, u32(strlen(s)), written, 0)

def main() i32:
    print("Hello, world!\n")
    return 0
ESP32
target "esp32"

gpio:  u32[0x140] at 0x3FF44000    # the GPIO registers
iomux: u32[64]    at 0x3FF49000    # the function of each pin

LED = 2

def wait():
    for i in 0..500000: pass     # about half a second

def main():
    iomux[0x40 / 4] = 0x2800            # GPIO 2 is a GPIO
    gpio[(0x530 + 4 * LED) / 4] = 0x100
    gpio[0x24 / 4] = 1 << LED          # an output
    while True:
        gpio[0x08 / 4] = 1 << LED      # on
        wait()
        gpio[0x0C / 4] = 1 << LED      # off
        wait()

Die Dateien heißen .abel. Ein Block folgt auf eine Zeile mit : und ist vier Leerzeichen weiter eingerückt, wie in Python. Ein Programm für ein Board sagt das in seiner ersten Zeile mit target; ohne sie ist es eines für Windows.

Die Sprache auf einen Blick

aBelle ist bewusst klein: genau so viel, wie ein Compiler braucht, um sich selbst zu übersetzen, und dazu die Register eines Boards. Alles im Einzelnen steht in der Sprachbeschreibung (vorläufige Fassung).

WasWie
Typeni32 (der Standard), u32 für Adressen und Bitmuster, pchar die Adresse eines Bytes. Umwandeln immer ausdrücklich: u32(x)
Variablenglobal mit Typ: count: i32 = 0; lokal bei der ersten Zuweisung: n = 0
Felderfest: names: i32[100], src: char[2000]; wachsend: toks: i32[] mit append, len, resize; an einer Adresse: gpio: u32[0x140] at 0x3FF44000
Funktionendef add(a, b) i32:; Rekursion; eine Funktion darf vor ihrer Stelle benutzt werden
Abläufeif / elif / else, while, for i in 0..n:, break, continue, return
Rechnendie Operatoren von Python für ganze Zahlen, dazu x += 1 und die anderen; / schneidet zur 0 hin ab wie die Hardware
WindowsFunktionen einer DLL mit extern "kernel32.dll":, auch cdecl und ... für printf
Boardstarget "esp32" in der ersten Zeile; Register als Feld at ihrer Adresse, eine Funktion des ROM mit def ets_delay_us(us: u32) at 0x40008534
Mehrere Dateieninclude "inc/uart.abel" fügt den Text einer Datei ein, jede Datei einmal

Drei Ziele

Dieselbe Sprache, drei Compiler, jeder aus derselben Quelle bis auf den Teil, der den Code und die Datei schreibt.

Windows x86Windows x64ESP32
Compilerabelle.exeabelle64.exeabelle_esp32.exe
Wahlder StandardProject > aBelle for x64target "esp32"
Ausgabeein Konsolenprogramm (PE)ein Konsolenprogramm (PE32+)Code für das IRAM, Daten für das DRAM
F9übersetzt und startet im Debuggerlädt über das USB-Kabel ins RAM; Shift+F9 schreibt es zuerst in den Flash

Auf dem ESP32 kann ein aBelle-Programm auch als Datei auf dem Board liegen: Debug > ESP32 Board Files lädt es in die Konsole von examples/esp32/console.asm, die es startet, auf Wunsch nach jedem Reset.

Bibliotheken für den ESP32: UART und WLAN

Die Beispiele für den ESP32 binden Dateien aus examples\abelle\esp32\inc ein. Sie sind selbst in aBelle geschrieben: Du kannst sie lesen, ändern und im Debugger verfolgen.

DateiWas sie bringt
uart.abelText, Zahlen und Hexzahlen über UART0, den COM-Port des Boards
wifi.abeldas WLAN: den Dienst vom Board laden, Netze suchen, sich verbinden, Frames senden und empfangen, Fehler als Satz
net.abelARP, IPv4, ICMP (Ping), UDP, DHCP, DNS und mDNS
tcp.abelTCP, eine Verbindung zur Zeit, als Client oder Server
network.abelder Name und das Passwort deines WLAN

Das WLAN selbst läuft auf dem zweiten Kern des ESP32, das aBelle-Programm auf dem ersten. Hält der Debugger das Programm an einem Breakpoint an, bleibt die Verbindung stehen, und was ankommt, wartet in einem Puffer. So gehst du Zeile für Zeile durch einen DHCP-Austausch oder eine TCP-Verbindung. Einmal pro Board braucht es dafür Install WiFi; mehr auf der ESP32-Seite.

Debuggen im Quelltext

Der Compiler schreibt neben das Programm eine Map-Datei: welcher Code zu welcher Zeile gehört und wo die Variablen liegen. Asmonite debuggt damit direkt in der .abel-Datei.

Ein Compiler, der sich selbst übersetzt

aBelle ist so entstanden, wie Sprachen früher entstanden sind: in Stufen, bis die Sprache sich selbst trägt.

  1. Stufe 0, in Delphi geschrieben, übersetzt aBelle in Assembler für Asmonite.
  2. Der Compiler in aBelle, von Stufe 0 übersetzt, schreibt Maschinencode und Programmdatei selbst.
  3. Er übersetzt sich selbst in dieselbe Datei, Byte für Byte, in etwa 25 Millisekunden. Ab hier wächst aBelle in aBelle.

Der Compiler arbeitet in einem Durchgang: lesen, zerlegen und sofort Code schreiben, ohne Syntaxbaum. Über 350 Tests und ein Fuzzer mit zufälligen Programmen prüfen, dass alle Compiler dasselbe tun.

Beispiele

WindowsESP32
hello.abel – Hello, world!blink.abel – die LED blinkt
factorials.abel – Rekursionhello_uart.abel – Text über die serielle Schnittstelle
table.abel – das Einmaleinstimer.abel – Mikrosekunden mit dem Timer
fizzbuzz.abel – if / elif / elsetemperature.abel – der Sensor im Chip
primes.abel – das Sieb des Eratostheneschipinfo.abel, dice.abel, sieve.abel
strings.abel, printf.abel – Textreaction.abel – ein Reaktionsspiel, clock.abel – der Takt
WLAN: scan, dhcp, dns, ping, ntp, arpscan, wol, udpecho, httpget, webserver, telnetd

Die Beispiele für Windows liegen in examples\abelle, die für den ESP32 in examples\abelle\esp32. Alle ESP32-Beispiele mit Beschreibung →

Was es (noch) nicht gibt