气Qi lang

Interpreter in C · MIT-Lizenz

Eine Sprache, die in chinesischer Schrift geschrieben wird

气 (Qi) ist eine leichtgewichtige, schnelle und quelloffene Programmiersprache mit chinesischen Schlüsselwörtern. Der Name kommt vom Pinyin des Zeichens „气“ — Luft. Genau so soll die Sprache sein: flink, leicht und vollständig durchschaubar.

Quelltext im Repository durchstöbern

01 — Herkunft

Aus einem Artikel wurde ein Interpreter

Den Anstoß gab ein Artikel darüber, wie Programmiersprachen überhaupt entstehen. Andrew Yang wollte selbst einen Interpreter bauen, sah sich mehrere Implementierungen an — und stellte fest, dass alle auf dem Englischen aufsetzen.

Also die Gegenprobe: eine Programmiersprache, die auf einer „fremden“ natürlichen Sprache beruht, in diesem Fall auf dem Chinesischen. Was passiert dann? Welche Nachteile fallen auf? Den Einstieg lieferten frei verfügbare Quellen, vor allem Crafting Interpreters; danach entstanden die Konzepte überwiegend in Eigenarbeit.

Warum der Name Qi?

Qi ist die Pinyin-Umschrift von „气“, dem chinesischen Zeichen für Luft. Schnell, leicht, transparent — die Eigenschaften der Luft sind das Programm der Sprache.

Eine ganze Sprache von Null an zu bauen ist ziemlich hart. Genau das machte den Reiz aus.

02 — Erste Zeile

So klingt „Hallo Welt“ auf Qi

打印行("你好,世界")

Nicht nur die Zeichenkette steht in chinesischer Schrift, sondern auch der Aufruf selbst: Schlüsselwörter, Funktionsnamen und Satzzeichen folgen der Schriftkonvention — inklusive der Klammern in voller Breite.

Auch die Werte tragen chinesische Namen. Im Protokoll der Testsuite tauchen etwa der Wahrheitswert 假 und Listen in der Form 【零,1,2,3】 auf — mit eckigen Klammern und Trennzeichen der jeweiligen Schrift.

Wer die Sprache in ihrer eigenen Schriftwelt lesen möchte: die Projektbeschreibung liegt zusätzlich als README.zh.md auf Chinesisch vor.

03 — Vier Eigenschaften

Worauf Qi ausgelegt ist

  1. Auf dem Chinesischen aufgebaut

    Englischsprachige Menschen vergessen leicht, welchen Vorsprung ihnen die vertrauten Schlüsselwörter geben: Wer Englisch spricht, errät den Sinn eines Python-Schnipsels schon aus Wörtern wie „if“, „int“ oder „while“. Eine Sprache auf anderer sprachlicher Grundlage öffnet das Programmieren für deutlich mehr Menschen weltweit.

  2. Schnell

    Qi nutzt einen Compiler mit einem einzigen Durchlauf, der zu effizientem Bytecode übersetzt und dicht an der Maschine läuft. Zusammen mit Optimierungen wie NaN Boxing und Hash-Table-Probing kann sich das Tempo mit konkurrierenden dynamischen Sprachen messen.

  3. Leicht

    Weniger als 5000 Zeilen Code: Das gesamte Projekt lässt sich an einem Tag lesen. Kurz heißt hier nicht unordentlich — der Code ist durchgehend sauber formatiert und leicht nachvollziehbar. Die fertige ausführbare Datei wiegt nur etwa 140 kb und läuft damit auf nahezu jedem denkbaren Gerät.

  4. Objektorientiert

    Klassen stehen im Zentrum. Objektorientierte Programmierung liefert eine klare, modulare Struktur, die Komplexität dank Abstraktion und Kapselung deutlich besser bändigt als ein rein funktionaler Aufbau.

04 — Unter der Haube

Der Weg vom Zeichen zum Bytecode

Implementierung
C — der Interpreter samt Laufzeit liegt vollständig im Ordner /src.
Übersetzung
Einzeldurchlauf-Compiler: Der Quelltext wird in einem Durchgang zu Bytecode, ohne Zwischenbaum als Umweg.
Ausführung
Effizienter Bytecode, der bewusst dicht an der Hardware bleibt.
Wertdarstellung
NaN Boxing — Werte reisen kompakt in Gleitkommazahlen mit.
Nachschlagen
Hash-Tabellen mit Probing für Variablen, Felder und Methoden.
Umfang
Unter 5000 Zeilen Code, Endgröße der Binärdatei etwa 140 kb.
Lizenz
MIT, siehe LICENSE.txt im Repository.

05 — Messungen

Benchmarks, mit Augenmaß gelesen

Ein paar Benchmarks sind kein guter Richter über die Leistung einer Sprache — anschauen lohnt sich trotzdem. Jeder Durchlauf wurde fünfmal ausgeführt und pro Sprache der Mittelwert genommen.

Gemessen wurde auf einem MacBook Air 2017 mit Dual-Core-i5 und 8 GB RAM. Wer die Zahlen selbst nachstellen will, findet den vollständigen Code der Messläufe im Repository.

Nachrechnen

Die Benchmark-Programme liegen im Ordner test/benchmark.

Messläufe im Repository ansehen

06 — Loslegen

In vier Schritten zum eigenen Interpreter

Gebraucht wird nur make. Unter Linux ist es in der Regel bereits Teil des Systems, sonst genügt ein Aufruf des Paketmanagers.

macOS

brew install make

Windows

choco install make
  1. Repository holen. Das Git-Repository klonen oder das ZIP-Archiv herunterladen.
  2. Terminal öffnen. Mit cd in den Ordner /src/cmake-build-release wechseln.
  3. Bauen. make aufrufen.
  4. Fertig. Der Interpreter ist einsatzbereit.

07 — Testsuite

274 Tests halten die Sprache zusammen

Für eine Programmiersprache ist Testen besonders wichtig, deshalb liegt eine vollständige Qi-Testsuite bei: Sie prüft, dass jeder Teil des Interpreters wirklich das tut, was er tun soll. Die Testprogramme stehen im Verzeichnis /test.

Die Automatisierung übernimmt das Go-Programm /utils/test.go. Es führt jedes Testprogramm mit dem übergebenen Interpreter aus, fängt die Ausgabe ab und vergleicht sie mit der Erwartung. Dafür muss Go auf dem System installiert sein.

go run test.go -interpreter=PATH_TO_INTERPRETER_HERE

Fehlt etwa der Negations-Operator, meldet sich die Suite mit Zeile und Erwartungswert:

$ go run test.go -interpreter=PATH
FAIL ../test/array/indexing.qi
     Expected output '假' on line 7 and got 'b'.
FAIL ../test/for/scope.qi
     Expected output '-1' on line 10 and got '1'.
FAIL ../test/operator/negate.qi
     Expected output '-3' on line 1 and got '3'.
268 tests passed. 6 tests failed.
exit status 1

Läuft alles durch, bleibt eine einzige Zeile übrig:

$ go run test.go -interpreter=PATH
All 274 tests passed (641 expectations).

08 — Sprachumfang

Was in Qi bereits eingebaut ist

Codebeispiele für all das stehen als lauffähige Programme in den Tests.

09 — Mitmachen

Beiträge machen Open Source erst aus

Beiträge sind das, was die Open-Source-Gemeinschaft zu einem so großartigen Ort zum Lernen, Anregen und Erschaffen macht — jeder Beitrag wird sehr geschätzt. Wer eine Idee zur Verbesserung hat, forkt das Repository und öffnet einen Pull Request. Genauso willkommen: ein Issue mit dem Label „enhancement“. Und ein Stern für das Projekt schadet nie.

  1. Projekt forken
  2. Feature-Branch anlegen: git checkout -b feature/AmazingFeature
  3. Änderungen festschreiben: git commit -m 'Add some AmazingFeature'
  4. Branch pushen: git push origin feature/AmazingFeature
  5. Pull Request öffnen

Hinter dem Projekt

Andrew Yang — @anonymousaaardvark

Dank an

Crafting Interpreters, Gravity und Loxido — die Vorbilder, an denen sich Qi orientiert hat.

Mitwirken am Repository