Brainfuck ist eine esoterische Programmiersprache (Esolang), die der Schweizer Student Urban Müller 1993 mit dem Ziel entwickelte, den kleinstmöglichen Compiler zu schreiben. Sie besteht aus nur acht Befehlen, ist aber bei unbegrenztem Speicher Turing-vollständig — ein klassischer Turing-Tarpit: extrem minimal, aber theoretisch genauso mächtig wie jede andere Sprache.
Das Modell: Speicherband und Zeiger
Ein Brainfuck-Programm arbeitet auf einem Speicherband (Tape) aus Byte-Zellen, typischerweise 30.000 Zellen. Ein Datenzeiger zeigt auf die aktuelle Zelle, der Befehlszeiger auf den nächsten Befehl im Quelltext.
Die 8 Befehle
> Zeiger nach rechts (nächste Zelle)
< Zeiger nach links (vorherige Zelle)
+ aktuellen Wert um 1 erhöhen
- aktuellen Wert um 1 verringern
. aktuellen Wert als Zeichen ausgeben
, ein Zeichen einlesen
[ Sprung nach vorn, wenn aktueller Wert 0 ist
] Sprung zurück, wenn aktueller Wert nicht 0 ist
Die eckigen Klammern bilden eine Schleife: [ und ] funktionieren wie ein while-Konstrukt, das bei Wert 0 der aktuellen Zelle beendet wird. Ein kompakter Interpreter passt in weniger als 200 Bytes C — genau das war Müllers ursprüngliche Motivation.
Beispiel: Hello World
++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Der Code setzt zuerst den Zellenwert 10 (Zeilenumbruch-Zähler), nutzt dann die Schleife, um die ASCII-Werte für „Hello World!" aufzubauen und gibt sie mit . aus.
Praxis und Verwandtschaft
- Brainfuck-Interpreter gibt es für nahezu jede Plattform; viele sind als Python-Befehle-Skripte in wenigen Zeilen umgesetzt.
- Das Sprachmodell ähnelt einer Assembly-Befehle-Maschine: direkter Speicherzugriff, keine Typen, keine Abstraktion.
- Zusammen mit Befunge-Befehle und Whitespace-Befehle gehört Brainfuck zu den bekanntesten Esolangs der 1990er- und 2000er-Jahre.
- Der Name war als Scherz gewählt — Müller selbst betrachtete die Sprache nie als ernsthaft nutzbar.
Mehr zu verwandten Konzepten: C/C++-Befehle (kompakter Code) und JavaScript-Befehle (Browser-Interpreter).
Befunge ist eine esoterische, zweidimensionale und stackbasierte Programmiersprache, die Chris Pressey 1993 für den Amiga entwickelte. Das erklärte Ziel war, eine Sprache zu schaffen, die sich möglichst schwer kompilieren lässt: Der Quellcode ist kein linearer Text, sondern ein Raster, in dem sich der Befehlszeiger in alle vier Himmelsrichtungen bewegt.
Das 2D-Modell
Ein Befunge-Programm liegt auf einem Spielplan (Playfield) aus ASCII-Zeichen — bei Befunge-93 standardmäßig 80×25 Zellen. Ein Instruction Pointer (IP) startet oben links und wandert je nach Richtungsbefehlen durch das Raster; am Rand wickelt er bei Befunge-98 toroidal um (unten geht es oben weiter).
Die wichtigsten Befehle
0-9 Zahl auf den Stack legen
+ - * / % Arithmetik auf den Stack
! logisches NICHT, ` Vergleich (größer)
> < ^ v Richtung des IP ändern
? zufällige Richtung
_ | waagerechte / senkrechte Bedingung
" String-Modus (Zeichen bis zum nächsten ")
: obersten Stack-Wert duplizieren / tauschen
$ obersten Wert verwerfen
. Zahl ausgeben, , Zeichen ausgeben
& Zahl einlesen, ~ Zeichen einlesen
p Zeichen ins Playfield schreiben (put)
g Zeichen aus dem Playfield lesen (get)
# Trampolin: nächste Zelle überspringen
@ Programm beenden
Mit p und g kann ein Programm seinen eigenen Quellcode verändern — Befunge ist damit selbstmodifizierend, was Compiler vor echte Probleme stellt.
Beispiel: Hello World
"!dlroW olleH">:#,_@
Der String-Modus legt „!dlroW olleH" rückwärts auf den Stack; die Schleife :#,_ gibt Zeichen aus, bis der Stack leer ist, dann beendet @ das Programm.
Versionen und Verwandtschaft
- Befunge-93: 80×25-Grid, nicht ganz Turing-vollständig (endlicher Speicher).
- Funge-98: toroidales Grid, Fingerprint-Erweiterungen und dynamische Playfield-Größe — damit Turing-vollständig.
- Der „Funge"-Zweig umfasst weitere 2D-Sprachen wie Unefunge (eindimensional) und Trefunge (dreidimensional).
- Gemeinsam mit Brainfuck-Befehle und Whitespace-Befehle ist Befunge einer der Klassiker unter den Esolangs — alle drei gelten als Turing-Tarpits mit absichtlich widerspenstigem Quellcode.
Wer die Muster verstehen will, findet die Grundlagen der Datenhaltung in den Python-Befehle und der Stack-Logik in den PostScript-Befehle.
Whitespace ist eine esoterische Programmiersprache, die 2003 von Edwin Brady und Chris Morris an der University of Durham entwickelt und am 1. April 2003 veröffentlicht wurde. Ihre Besonderheit: Nur Leerzeichen, Tabulatoren und Zeilenumbrüche sind signifikant — alle anderen Zeichen werden als Kommentar ignoriert. Der Quellcode ist damit in einem normalen Editor praktisch unsichtbar.
Das Modell: Stack und Heap
Whitespace ist imperativ und stackbasiert. Jeder Befehl beginnt mit einer Befehlsfamilie (z. B. Space für Stack-Operationen), gefolgt von Parametern, die als Binärzahlen mit Space = 0 und Tab = 1 kodiert werden. Ein Heap erlaubt zusätzlich benannten Speicherzugriff.
Die Befehlsfamilien
[Space] Stack-Operationen: push, dup, swap, discard
[Tab][Space] Arithmetik: add, sub, mul, div, mod
[Tab][Tab] Heap: store (schreiben), retrieve (lesen)
[Tab][LF] Kontrollfluss: Labels, call, jump, ret
[LF] I/O: print/read char, print/read number
Konkret: [Space][Space] gefolgt von einer Binärzahl legt den Wert auf den Stack (push), [Tab][LF][Space][Space] gibt die oberste Zahl aus. Das Präfix [LF] kennzeichnet die I/O-Familie, [Space] beziehungsweise [Tab] die Ausgabe als Zeichen beziehungsweise Zahl.
Beispiel: Hello World
...
Jede Zeile beginnt mit [Space][Space] (push) und einer Binärzahl für den ASCII-Wert, gefolgt von [Tab][LF][Space][Space] (Zeichen ausgeben) — nur Leerzeichen, Tabs und Zeilenumbrüche, unsichtbar im Quelltext.
Praxis und Verwandtschaft
- Whitespace war ein Aprilscherz am 1. April 2003, wurde aber zu einer der bekanntesten Esolangs überhaupt.
- Die Entwickler schrieben später mit Kaya und Idris ernsthafte Sprachen — Whitespace blieb ein Experiment.
- Zusammen mit Brainfuck-Befehle und Befunge-Befehle bildet Whitespace das klassische Trio der Turing-Tarpits: minimalistische Esolangs, die nur durch ihre absichtliche Unlesbarkeit auffallen.
- Wer sich mit der Stack-Logik vertraut machen will, findet eine sanftere Einführung in den Python-Befehle und den Haskell-Befehle.
Die OpenGL Shading Language (GLSL) ist die Shader-Sprache der Grafik-API OpenGL. Sie wurde vom OpenGL ARB (Architecture Review Board) entworfen, hat eine C-ähnliche Syntax und läuft direkt auf der Grafikkarte (GPU). GLSL 1.10 erschien 2004 zusammen mit OpenGL 2.0; seit OpenGL 3.3 (2010) sind die Versionsnummern beider Spezifikationen synchronisiert, aktuell GLSL 4.60.
Shader-Stufen
Ein GLSL-Programm besteht aus mehreren getrennt kompilierten Shader-Stufen. Seit OpenGL 4.3 (GLSL 4.30) sind alle fünf klassischen Stufen verfügbar:
- Vertex-Shader (vert): verarbeitet jeden Eckpunkt, z. B. Transformation der Position
- Tessellation-Shader: Tessellation Control (tc) und Tessellation Evaluation (te) unterteilen Geometrie
- Geometry-Shader (geom): erzeugt oder verändert ganze Primitiven
- Fragment-Shader (frag): berechnet die Farbe jedes Pixels
- Compute-Shader (comp): allgemeine GPU-Berechnungen unabhängig vom Rendering
Grundgerüst
Die #version-Direktive steht immer in der ersten Zeile. Qualifier wie in, out und uniform legen fest, wie Daten zwischen Shader-Stufen und Anwendung fließen.
#version 330 core
in vec3 aPos;
uniform mat4 uMVP;
void main() {
gl_Position = uMVP * vec4(aPos, 1.0);
}
Wichtige Bausteine
- Vektoren und Matrizen:
vec2/vec3/vec4,mat3/mat4, Komponentenzugriff über.xyzoder.rgba - Texturen:
sampler2D, Abtastung mittexture(tex, uv) - Built-ins:
gl_Position(Vertex-Ausgabe),gl_FragCoord(Pixel-Koordinaten),gl_VertexID,gl_FragDepth; in älteren Versionengl_FragColor - Kontrollstrukturen wie in C:
if/else,for,while,switch,discardverwirft ein Fragment
GLSL ES
Für mobile Geräte und das Web gibt es die Variante GLSL ES, die Grundlage von WebGL 1/2 und WebGPU. Sie verzichtet auf einige Desktop-Funktionen und ist an die GPU-Hardware von Smartphones angepasst.
GLSL ist eng mit HLSL (DirectX) und Cg (Nvidia) verwandt, den Shader-Sprachen der konkurrierenden APIs. Grundlagen zu Grafikprozessoren liefert der Artikel GPU, für Nvidias Rechen-Plattform siehe CUDA.
Die High-Level Shading Language (HLSL) ist die Shader-Sprache von Microsoft für Direct3D. Sie entstand ab 2002 mit DirectX 9, als die feste Render-Pipeline durch programmierbare Shader ersetzt wurde, und wurde gemeinsam mit Nvidias Cg entwickelt — beide Sprachen sind C-ähnlich und teilen viele Konzepte. Seit Direct3D 10 ist HLSL die Pflicht-Sprache der einheitlichen Shader-Pipeline und wird bis heute in Direct3D 12 eingesetzt.
Shader-Modelle
HLSL-Features werden über Shader-Modelle (SM) gestuft, die an die DirectX-Version gekoppelt sind:
- SM 2.0/3.0: DirectX 9, erste voll programmierbare Pixel-/Vertex-Shader
- SM 5.0: DirectX 11, Tessellation und Compute-Shader
- SM 6.x: DirectX 12, u. a. SM 6.5 mit Raytracing (DXR) und Mesh-Shadern
Grundgerüst
HLSL arbeitet mit Semantics (z. B. POSITION, SV_Position, SV_Target), die Datenströme zwischen Pipeline-Stufen verbinden. Konstante Daten liegen in Constant Buffers.
cbuffer ConstantBuffer : register(b0) {
float4x4 WorldViewProjection;
};
struct VS_INPUT {
float3 pos : POSITION;
};
float4 main(VS_INPUT input) : SV_Position {
return mul(float4(input.pos, 1.0), WorldViewProjection);
}
Wichtige Bausteine
- Typen:
float2/float3/float4,float4x4,Texture2D,SamplerState - System-Values:
SV_VertexID,SV_InstanceID,SV_IsFrontFace,SV_Depth— erzeugt die Hardware selbst - Intrinsics:
mul,lerp,saturate,dot,normalize, Texturabtastung mitSample - Kontrollstrukturen wie in C:
if,for,while,switch,discard
Compiler
Der klassische Compiler fxc.exe erzeugt DXBC und unterstützt bis Shader Model 5.1. Der moderne Open-Source-Compiler DXC (DirectXShaderCompiler, LLVM-basiert) übersetzt HLSL nach DXIL und kann zusätzlich SPIR-V für Vulkan ausgeben.
HLSL ist das DirectX-Pendant zu GLSL (OpenGL) und teilt sich mit Cg (Nvidia) die C-ähnliche Basis. Was eine GPU dabei leistet und wie der Grafikspeicher VRAM genutzt wird, erklären die verlinkten Artikel.