Written like Python, compiled for Windows and the ESP32 board, debugged line by line in Asmonite.
aBelle has few words, three types and no hidden rules. Its compiler is written in aBelle itself. It writes the machine code and the program file itself, without an assembler and without a linker. In Asmonite you press F9: the program is compiled and runs in the debugger, with breakpoints, steps through the lines and the values of the variables.
From Asmonite 0.12.0 on aBelle is in the ZIP: the three compilers abelle.exe, abelle64.exe and abelle_esp32.exe next to Asmonite.exe, the examples in examples\abelle and the F1 help. The license of Asmonite applies: free, and what you write with it is yours.
On the left a program for Windows: it takes WriteFile from kernel32.dll and writes to the console. On the right one for the ESP32 board: the registers of the chip are arrays at their address, and the LED blinks.
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
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()
The files are called .abel. A block follows a line with : and is indented four spaces further, as in Python. A program for a board says so in its first line with target; without it, it is one for Windows.
aBelle is small on purpose: just what a compiler needs to translate itself, and the registers of a board. All of it in detail is in the language description (provisional version).
| What | How |
|---|---|
| Types | i32 (the default), u32 for addresses and bit patterns, pchar the address of a byte. Converting always explicitly: u32(x) |
| Variables | global with a type: count: i32 = 0; local at the first assignment: n = 0 |
| Arrays | fixed: names: i32[100], src: char[2000]; growing: toks: i32[] with append, len, resize; at an address: gpio: u32[0x140] at 0x3FF44000 |
| Functions | def add(a, b) i32:; recursion; a function may be used before its place |
| Control flow | if / elif / else, while, for i in 0..n:, break, continue, return |
| Arithmetic | the operators of Python for whole numbers, and x += 1 and the others; / cuts towards 0 as the hardware does |
| Windows | functions of a DLL with extern "kernel32.dll":, also cdecl and ... for printf |
| Boards | target "esp32" in the first line; registers as an array at their address, a function of the ROM with def ets_delay_us(us: u32) at 0x40008534 |
| Several files | include "inc/uart.abel" puts in the text of a file, each file once |
The same language, three compilers, each from the same source but for the part that writes the code and the file.
| Windows x86 | Windows x64 | ESP32 | |
|---|---|---|---|
| Compiler | abelle.exe | abelle64.exe | abelle_esp32.exe |
| Chosen by | the default | Project > aBelle for x64 | target "esp32" |
| Output | a console program (PE) | a console program (PE32+) | code for the IRAM, data for the DRAM |
| F9 | compiles and starts in the debugger | loads into the RAM over the USB cable; Shift+F9 writes it into the flash first | |
On the ESP32 an aBelle program can also stay on the board as a file: Debug > ESP32 Board Files uploads it to the console of examples/esp32/console.asm, which starts it, after every reset if you like.
The examples for the ESP32 include files from examples\abelle\esp32\inc. They are written in aBelle themselves: you can read them, change them and follow them in the debugger.
| File | What it brings |
|---|---|
uart.abel | text, numbers and hex numbers over UART0, the COM port of the board |
wifi.abel | the WiFi: load the service from the board, find networks, connect, send and receive frames, errors as a sentence |
net.abel | ARP, IPv4, ICMP (ping), UDP, DHCP, DNS and mDNS |
tcp.abel | TCP, one connection at a time, as a client or a server |
network.abel | the name and the password of your network |
The WiFi itself runs on the second core of the ESP32, the aBelle program on the first. When the debugger holds the program at a breakpoint, the connection stays up, and what comes in waits in a buffer. So you go line by line through a DHCP exchange or a TCP connection. Once per board this needs Install WiFi; more on the ESP32 page.
Next to the program the compiler writes a map file: which code belongs to which line and where the variables are. With it Asmonite debugs right in the .abel file.
pchar with its text, arrays as a list, growing arrays with their lengthaBelle came about the way languages used to: in stages, until the language carries itself.
The compiler works in one pass: read, split into tokens and write code at once, without a syntax tree. Over 350 tests and a fuzzer with random programs check that all compilers do the same.
| Windows | ESP32 |
|---|---|
hello.abel – Hello, world! | blink.abel – the LED blinks |
factorials.abel – recursion | hello_uart.abel – text over the serial port |
table.abel – the times table | timer.abel – microseconds from the timer |
fizzbuzz.abel – if / elif / else | temperature.abel – the sensor in the chip |
primes.abel – the sieve of Eratosthenes | chipinfo.abel, dice.abel, sieve.abel |
strings.abel, printf.abel – text | reaction.abel – a reaction game, clock.abel – the clock |
WiFi: scan, dhcp, dns, ping, ntp, arpscan, wol, udpecho, httpget, webserver, telnetd |
The examples for Windows are in examples\abelle, those for the ESP32 in examples\abelle\esp32. All ESP32 examples with a description →
include only puts in text), numbers of 64 bits.f(i)[0]) and the expression x and a or b as a choice do not work; a helper variable does.inc put a prefix in front of their names for that (wl_, u_, md_).