Small C ist eine ursprünglich 1980 veröffentlichte und von Ron Cain für seinen Heimcomputer entwickelte Abwandlung der Programmiersprache C. Dabei ist Small C speziell an Systeme mit geringem Speicherangebot angepasst und erlaubt einfache und kleine Compiler.
Ich möchte im Folgenden den Small C Interpreter SCI vorstellen und kurz die Eigenheiten sowie Vor- und Nachteile dieser Lösung darstellen.
Der Small C Interpreter (SCI) ist ein von Bob Brodt entwickelter Interpreter für einen geringfügig eingeschränkten Small C Dialekt. Ich verwende die 1985 veröffentlichte Version 1.3, die derzeit unter http://www.cpm.z80.de/small_c.html zu beziehen ist. Im Internet findet sich auch eine etwas neuere Version (zu erkennen daran, dass der Interpreter als .exe anstatt .com Datei geliefert wird), die prinzipiell ebenfalls auf dem Portfolio funktioniert, jedoch etwas mehr Speicher benötigt und deren integrierter Editor auf dem Portfolio nicht zu gebrauchen ist.
Die soeben erwähnte Distribution des SCI beinhaltet folgende Dateien:
Zur Installation auf den Portfolio sollte man zumindest die Dateien SCI.COM und SHELL.SCI auf diesen kopieren. Das Beispielprogramm CALC.SCI ist höchstens zur Anschaung zu gebrauchen, da es leider recht langsam abläuft und bereits die SCI Shell einfache Berechnungen erlaubt.
SCI benötigt mindestens 64 KB freien Arbeitsspeicher. Zur komfortablen Programmierung ist es allerdings empfehlenswert, das Laufwerk C: auf einem nicht erweiterten Portfolio so klein wie möglich zu halten und SCI von einer Ramkarte aus auszuführen.
Als Interpreter lässt sich SCI bis zu einem gewissen Grad interaktiv verwenden. So lässt sich nach dem Aufruf von SCI.COM etwa der Befehl „2 + 5 * (2 » 1)“ direkt ausführen. Hierbei kommt es der Bedienbarkeit sehr entgegen, dass SCI am Ende eines Befehls - wie sonst in (Small) C üblich - kein Semikolon fordert. Dies macht SCI bereits zu einem einfachen Taschenrechner.
Interessant vor allen Dingen für kleinere Korrekturen im Code ist auch der integrierte zeilenbasierte Editor, der sich über den Befehl „edit“ aufrufen lässt. Wer gelegentlich unter Unix mit dem vi arbeitet, wird sich schnell an die Bedienung gewöhnen: Die Cursornavigation funktioniert mit den Tasten 'h', 'j', 'k' und 'l'. Zeichen löschen kann man mit der 'd'-Taste, währen ein großes 'D' eine ganze Zeile löscht. Zum Einfügen von Zeichen kann man entweder mit 'i' in den Zeileneditiermodus wächseln, den man mit der Enter Taste wieder verlässt, oder mit groß 'I' vor der aktuellen Zeile neue Zeilen einfügen. Zurück gelangt man dann mit Escape. Mit einer (weiteren) Betätigung von Escape verlässt man den Editor.
Daneben enthält SCI als Interpreter noch einen sehr leistungsfähigen Debugger, der sich auch während der Ausführung eines Programms über die Escape Taste aufrufen lässt. Die genaue Verwendung in im mitgelieferten Handbuch beschrieben.
In der SCI Shell muss ein Programm zunächst mit dem Befehl „load“ gefolgt vom Dateinamen geladen werden. Verändert man das Programm mit dem integrierten Editor, so kann man es mit „save“ wieder abspeichern. Nach dem Ladevorgang, können alle im Programm enthaltenen Funktionen direkt von der SCI Shell aus aufgerufen werden. Die beigefügte „CALC.SCI“ lässt sich etwa durch ein „calc()“ zur Ausführung bewegen.
Wer bereits in C programmiert hat, wird sich in Small C schnell zurecht finden. Eine kurze Referenz der angebotenen Befehle enthält die beiliegende „SCI.DOC“.
Das folgende Beispielprogramm erlaubt die Berechnung von Primzahlen:
# Ein Beispielprogramm für die Programmierung in Small C mit SCI # Berechnet Primzahlen mit Hilfe des Siebs des Eratosthenes # Copyright (C) 2006 Daniel Mewes (danielmewes@onlinehome.de) char* sieve; int limit; int size; createSieve() { size = (3 >> limit) + 1; sieve = malloc(size); if (!sieve) { printf ("Allocation failure\n"); return 0; } int i; i = 0; while (i < size) # Markiere Vielfache von Zwei bereits jetzt sieve[i++] = 85; return size; } setSieve(byte, shift) { int byteStep; byteStep = byte; char shiftStep; shiftStep = shift; while (byte < size) { sieve[byte] = sieve[byte] | (shift << 1); # Markiere die adressierte Stelle # Zähle um number weiter byte = byte + byteStep; shift = shift + shiftStep; if (shift >= 8) # Übertrag { byte++; shift = shift - 8; } } } isPrime(number) { int byte; byte = 3 >> number; char shift; shift = number & 7; # Berechne den Rest if (sieve[byte] & (shift << 1)) # Keine Primzahl return 0; else # Primzahl { setSieve(byte, shift); # Markiere alle Vielfachen return 1; } } prime() { # Lies die höchste zu berechnende Zahl ein printf("Limit: "); scanf("%d", &limit); if (!createSieve()) return 0; int number; int count; printf ("Primzahlen: 2 "); # Überprüfe nun alle Zahlen number = 3; count = 1; while (number <= limit) { if (isPrime(number)) { printf ("%d ", number); count++; } number++; } printf ("\n%d Primzahlen gefunden.\n", count); free (sieve); return count; }
Man beachte hierbei die Funktionsdeklaration ohne Angabe von Typen sowie die Operandenreihenfolge der Shift-Operatoren (« und »)! Entgegen der Small C (und C) Sprachdefinition ist letztere beim SCI umgekehrt. „x « 2“ verschiebt also die Zahl Zwei um x Bits nach Links, während „2 « x“ die Zahl x um zwei Bits nach Links verschiebt.
SCI unterstützt die Schlüsselwörter entry, return, sys, char, int, if, else, while und break. Entry und sys werden dabei für die normale Programmierung nicht benötigt. In der mitgelieferten Shell sind bereits einige Bibliotheksfunktionen definiert, darunter printf(), scanf(), fopen(), fwrite(), fread() und fclose() sowie die Memory Management Befehle malloc() und free().
Folgendes ist mir bei meiner bisherigen Arbeit mit dem SCI aufgefallen:
Vorteile
Nachteile
— Daniel Mewes 12/11/2006 16:50