sectorforth is een compacte implementatie van de Forth-programmeertaal, specifiek geschreven voor de 16-bit x86-architectuur om in een bootsector van 512 bytes te passen. Het systeem is gebaseerd op een minimalistische set van acht primitieven, vijf variabelen en twee I/O-functies, waardoor complexere functionaliteit in Forth zelf kan worden gebouwd.
Belangrijke kenmerken:
- Minimalisme: De set primitieven is zeer beperkt; zelfs het parsen van getallen moet door de gebruiker worden geïmplementeerd.
- Compilatie & Uitvoering: Het project is ontwikkeld met NASM en kan via een makefile worden omgezet in een binair bestand of een diskette-image, dat vervolgens in QEMU kan worden uitgevoerd of gedebugged.
- Interface: De interpreter verwerkt input per regel (tot 4 KB). Bij een onbekend woord wordt een rode
!! foutmelding getoond en de status van de interpreter gereset.
Het project is geïnspireerd door een Usenet-thread uit 1996 en de implementatie van jonesforth. Voor theoretische achtergrond wordt verwezen naar Starting Forth en Moving Forth.
sectorforth
Batterijen niet inbegrepen
sectorforth bevat uitsluitend de acht primitieven die in de bovengenoemde Usenet-post worden beschreven, vijf variabelen voor het manipuleren van de interne status en twee I/O-primitieven.
Met deze minimale set bouwstenen kunnen woorden voor vertakkingen, compileren, het manipuleren van de return-stack, enzovoort, volledig in Forth zelf worden geschreven (zie de voorbeelden).
De colon-compiler (:) is beschikbaar, waardoor nieuwe woorden eenvoudig kunnen worden gedefinieerd (wat betekent dat ; uiteraard ook aanwezig is).
In tegenstelling tot veel Forth-implementaties probeert sectorforth onbekende woorden niet om te zetten naar getallen, aangezien getallen kunnen worden gegenereerd met behulp van de beschikbare primitieven. De twee meegeleverde I/O-primitieven zijn voldoende om een krachtigere interpreter te schrijven die getallen kan parsen.
Primitieven
| Primitief | Stack-effecten | Beschrijving |
@ | ( addr -- x ) | Haalt de geheugeninhoud op op adres addr |
! | ( x addr -- ) | Slaat x op op adres addr |
sp@ | ( -- sp ) | Geeft de pointer naar de top van de data-stack |
rp@ | ( -- rp ) | Geeft de pointer naar de top van de return-stack |
0= | ( x -- flag ) | -1 als de top van de stack 0 is, anders 0 |
+ | ( x y -- z ) | Som van de twee getallen aan de top van de stack |
nand | ( x y -- z ) | NAND-operatie op de twee getallen aan de top van de stack |
exit | ( r:addr -- ) | Pop de return-stack en hervat de uitvoering op addr |
key | ( -- x ) | Leest een toetsaanslag als ASCII-karakter |
emit | ( x -- ) | Print de low byte van x als een ASCII-karakter |
Variabelen
| Variabele | Beschrijving |
state | 0: voer woorden uit; 1: compileer woordadressen naar het woordenboek |
tib | Terminal input buffer, waar de input wordt geparsed |
>in | Huidige parsing-offset in de terminal input buffer |
here | Pointer naar de volgende vrije positie in het woordenboek |
latest | Pointer naar de meest recente vermelding in het woordenboek |
Compileren
sectorforth is ontwikkeld met NASM 2.15.01. Oudere versies van NASM zijn waarschijnlijk in staat om het te compileren, maar dit is niet getest.
Om sectorforth te compileren, voert u simpelweg make uit:
$ make
Dit produceert een gecompileerd binair bestand (sectorforth.bin) en een diskette-image (sectorforth.img) waarin het binaire bestand in de bootsector staat.
Uitvoeren
De makefile bevat twee targets voor het uitvoeren van sectorforth in QEMU:
- debug: start QEMU in debug-modus, waarbij de uitvoering is gepauzeerd. Hiermee kunt u een remote target instellen in GDB (
target remote localhost:1234) en breakpoints plaatsen voordat sectorforth begint te draaien.
- run: start sectorforth simpelweg in QEMU.
Gebruik
Per regel kan er tot 4 KB aan input worden ingevoerd. Na het indrukken van de enter-toets parst de interpreter één woord per keer en interpreteert dit (dat wil zeggen: voert het uit of compileert het, afhankelijk van de huidige waarde van de state-variabele).
sectorforth print niet de ok-prompt die bekend is bij Forth-gebruikers. Wanneer een woord echter niet in het woordenboek wordt gevonden, wordt de foutmelding !! in het rood geprint om aan te geven dat er een fout is opgetreden.
Wanneer een woord niet in het woordenboek wordt gevonden, wordt de status van de interpreter gereset: de data- en return-stacks, alsovwel als de terminal input buffer worden geleegd, en de interpreter wordt teruggezet in de interpretatiemodus. Andere fouten (bijvoorbeeld het compileren van een ongeldig adres in een woorddefinitie en het proberen hiervan uit te voeren) worden niet netjes afgehandeld en zullen de interpreter laten crashen.
Codestructuur
De commentaren in de code gaan uit van bekendheid met Forth en hoe dit gewoonlijk wordt geïmplementeerd.
Voor wie niet bekend is met Forth, wordt aangeraden om Starting Forth van Leo Brodie te lezen.
Voor wie niet bekend is met hoe Forth op x86 wordt geïmplementeerd, wordt verwezen naar de assembly-code van jonesforth van Richard W.M. Jones. sectorforth is sterk geïnspireerd door jonesforth, hoewel die laatste de basis beter uitlegt in de commentaren.
Voor een uitstekende introductie in threaded code technieken en het implementeren van Forth op verschillende architecturen, wordt Moving Forth van Brad Rodriguez aangeraden.
sectorforth
Batterijen niet inbegrepen
sectorforth bevat uitsluitend de acht primitieven die in de bovengenoemde Usenet-post worden beschreven, vijf variabelen voor het manipuleren van de interne status en twee I/O-primitieven.
Met deze minimale set bouwstenen kunnen woorden voor vertakkingen, compileren, het manipuleren van de return-stack, enzovoort, volledig in Forth zelf worden geschreven (zie de voorbeelden).
De colon-compiler (:) is beschikbaar, waardoor nieuwe woorden eenvoudig kunnen worden gedefinieerd (wat betekent dat ; uiteraard ook aanwezig is).
In tegenstelling tot veel Forth-implementaties probeert sectorforth onbekende woorden niet om te zetten naar getallen, aangezien getallen kunnen worden gegenereerd met behulp van de beschikbare primitieven. De twee meegeleverde I/O-primitieven zijn voldoende om een krachtigere interpreter te schrijven die getallen kan parsen.
Primitieven
| Primitief | Stack-effecten | Beschrijving |
@ | ( addr -- x ) | Haalt de geheugeninhoud op op adres addr |
! | ( x addr -- ) | Slaat x op op adres addr |
sp@ | ( -- sp ) | Geeft de pointer naar de top van de data-stack |
rp@ | ( -- rp ) | Geeft de pointer naar de top van de return-stack |
0= | ( x -- flag ) | -1 als de top van de stack 0 is, anders 0 |
+ | ( x y -- z ) | Som van de twee getallen aan de top van de stack |
nand | ( x y -- z ) | NAND-operatie op de twee getallen aan de top van de stack |
exit | ( r:addr -- ) | Pop de return-stack en hervat de uitvoering op addr |
key | ( -- x ) | Leest een toetsaanslag als ASCII-karakter |
emit | ( x -- ) | Print de low byte van x als een ASCII-karakter |
Variabelen
| Variabele | Beschrijving |
state | 0: voer woorden uit; 1: compileer woordadressen naar het woordenboek |
tib | Terminal input buffer, waar de input wordt geparsed |
>in | Huidige parsing-offset in de terminal input buffer |
here | Pointer naar de volgende vrije positie in het woordenboek |
latest | Pointer naar de meest recente vermelding in het woordenboek |
Compileren
sectorforth is ontwikkeld met NASM 2.15.01. Oudere versies van NASM zijn waarschijnlijk in staat om het te compileren, maar dit is niet getest.
Om sectorforth te compileren, voert u simpelweg make uit:
$ make
Dit produceert een gecompileerd binair bestand (sectorforth.bin) en een diskette-image (sectorforth.img) waarin het binaire bestand in de bootsector staat.
Uitvoeren
De makefile bevat twee targets voor het uitvoeren van sectorforth in QEMU:
- debug: start QEMU in debug-modus, waarbij de uitvoering is gepauzeerd. Hiermee kunt u een remote target instellen in GDB (
target remote localhost:1234) en breakpoints plaatsen voordat sectorforth begint te draaien.
- run: start sectorforth simpelweg in QEMU.
Gebruik
Per regel kan er tot 4 KB aan input worden ingevoerd. Na het indrukken van de enter-toets parst de interpreter één woord per keer en interpreteert dit (dat wil zeggen: voert het uit of compileert het, afhankelijk van de huidige waarde van de state-variabele).
sectorforth print niet de ok-prompt die bekend is bij Forth-gebruikers. Wanneer een woord echter niet in het woordenboek wordt gevonden, wordt de foutmelding !! in het rood geprint om aan te geven dat er een fout is opgetreden.
Wanneer een woord niet in het woordenboek wordt gevonden, wordt de status van de interpreter gereset: de data- en return-stacks, alsovwel als de terminal input buffer worden geleegd, en de interpreter wordt teruggezet in de interpretatiemodus. Andere fouten (bijvoorbeeld het compileren van een ongeldig adres in een woorddefinitie en het proberen hiervan uit te voeren) worden niet netjes afgehandeld en zullen de interpreter laten crashen.
Codestructuur
De commentaren in de code gaan uit van bekendheid met Forth en hoe dit gewoonlijk wordt geïmplementeerd.
Voor wie niet bekend is met Forth, wordt aangeraden om Starting Forth van Leo Brodie te lezen.
Voor wie niet bekend is met hoe Forth op x86 wordt geïmplementeerd, wordt verwezen naar de assembly-code van jonesforth van Richard W.M. Jones. sectorforth is sterk geïnspireerd door jonesforth, hoewel die laatste de basis beter uitlegt in de commentaren.
Voor een uitstekende introductie in threaded code technieken en het implementeren van Forth op verschillende architecturen, wordt Moving Forth van Brad Rodriguez aangeraden.