FPKPascal Programmierhandbuch

Florian Klämpfl 20. März 1995

Die momentane Version des Paketes ist eine Entwicklungsversion, d.h. der Compiler und die RTL sind noch nicht vollständig implementiert.

Alle in diesem Dokument genannten Warenzeichen werden anerkannt.

Turbo Pascal ist ein Warenzeichen von Borland International Inc. OS/2 ist ein Warenzeichen der International Bussiness Machines Corp. Windows NT ist ein Warenzeichen der Microsoft Corp. 386MAX ist ein Warenzeichen der Qualitas Inc.

Für Schäden die durch Programme des Pakets FPKPascal direkt oder indirekt entstanden sind wird keine Haftung übernommen.

Copyright (c) 1994,95 Florian Klämpfl

Inhaltsverzeichnis

1 Der Compiler 4 1.1 Interne Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 Grenzen des Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Das erzeugte Programm 7 2.1 Der Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2 Optimierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Die Sprache 8

3.1 Syntak und Semantik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

3.1.1 Kontrollstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2 Laufzeitbibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Units 10

4.1 Das Format der PPU-Dateien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.1.1 Der Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 4.1.2 Steurabschnitt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

4.2 Die Standardunits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5 Portierung 12

5.1 Kompatibilität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5.1.1 Turbo Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 5.1.2 ANSI-Pascal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

5.2 Unterstützung andere Betriebssystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 5.3 Portierung auf andere Prozessoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Das Programmierhandbuch enthält Informationen für fortgeschrittene Programmierer. Die Informationen sind vor allem von Nutzen, wenn der Compiler erweitertert werden soll oder eher exotische Programmieraufgaben zu lösen sind.

Kapitel 1

Der Compiler

1.1 Interne Details

Die untenstehende Graphik gibt einen Überblick über die Abhängigkeiten der verschiedenen Module des Compilers. Die Pfeile zeigen, welche anderen Module jeweils ein Modul verwendet. Es sind nicht alle Abhängigkeiten aufgezeichnet, das Modul PARSER verwendet z.B. auch SYMTABLE und GLOBALS, COBJECTS und ASMGEN werden von fast allen anderen Modulen verwendet.

[figure: PP; PARSER; ASMBL; ASMGEN; GLOBALS; COBJECTS; SCANNER; JUMPOPT; CODEGEN; SYMTABLE; TREE; TYPES; TEMPAD; Allg. Routinen; Ausgabe; Eingabezerlegung; Benutzerdialog; Codegeneration; Symbol- und Typverwaltung]

Nachfolgend werden kurz alle Module beschrieben

PARSER ist das eigentlich eines der zentralen Module, es führt das Auswerten der einzelnen Token und Zusammensetzten des Syntaxbaumes aus. Für einige Anwesiungen wird allerdings auch schon vom Parser Assembler erzeugt (Kontrollanweisungen).

PP Dieses Modul enthält das Hauptprogramm und ist im wesentlichen für den Benutzerdialog (Kommandozeilenauswertung) verantworlich.

SCANNER Dieses Modul zerlegt die Eingabe in die einzelnen Token und übernimmt die Funktion des Präprozessors

1.2 Grenzen des Compilers

In folgenden Bereichen könnten Sie an die Grenzen des Compilers stoßen in Klammern die Werte der 32-Bit Version:

Stringkonstanten sind auf eine Länge von 128 Zeichen beschränkt, die darauffolgenden Zeichen werden abgeschnitten.

Die Länge von PPU-Dateien ist auf 65000 Bytes beschränkt (32-Bit: 1 MB).

Unterprogramme dürfen in maximal 32 Ebenene geschachtelt werden (ENTER-Befehl).

Es können maximal 255 Units in ein Programm aufgenommen werden. Abhilfe: maxsymtables-Konstante in der Unit SYMTABLE erhöhen (32-Bit: 1024).

Es dürfen nicht mehr als 2^{16} − 1 Bytes große Parameterlisten an Unterprogramme übergeben werden (RET-Befehl). Ansonsten sind mir keine Einschränkungen bekannt, die nicht aus mangelndem Hauptspeicher oder überlaufendem Stack resultieren. Die sonstige Begrenzung ist der Wertebereich von LONGINT was die Zeilenanzahl in einem Modul etc betrifft. Wird eine dieser Grenzen überschritten bricht der Compiler meist mit einem Laufzeitfehler ab (203: Heapoverflow).

Das erzeugte Programm

2.1 Der Stack

Die Paramter an ein Unterprogramm werden immer über denn Stack übergeben. Die Parameter werden von rechts nach links auf den Stack kopiert, der in der Deklaration am weitestens links stehende Parameter hat die niedrigste Adresse (C-Konventionen). Das Abräumen des Stacks geschieht allerdings durch das aufgerufene Unterprogramm per RET xx-Befehl. Die Begrenzung auf 2^{16} − 1 Bytes Parametergröße hebt der Geschindigkeits- und Speicherplatzvorteil wohl auf, der in großen Programmen leicht 10kB ausmacht

Werden Exceptions verwendet, so legt der Compiler vor dem Aufruf noch eine Adresse auf den Stack, an die zurückgekehrt werden soll, wenn eine Exception auftritt.

Ist das aufgerufene Unterprogramm eine Funktion, die einen String-, Array-, Klassen- oder Recordtyp zurückgibt,

2.2 Optimierung

Die Codeoptimierung ist schwer von der einer kleveren Codeerzeugung abzugrenzen. Bösartig kann man wohl sagen, die Codeoptimierung des Compilers bügelt einen ineffizienten Programmierstil bzw die Mängel einer unzureichende Programmiersprache aus. In Pascal fehlt die Möglichkeit eine Variable explizit in ein Register zu laden, also muß der Compiler die Variablen selbstständig in Register laden.

Die Sprache

Der Sprachumfang orientiert sich an Pascal, ist aber erweitert worden. Zunächst sind praktisch alle Sprachkonstrukte, die mit TP 6.0 übersetzt werden können, implementiert (auch einige aus BP 7.0 z.B. INHERIED, BREAK, CONTINUE, CONST). Die Sprache wurde auch noch um einige in C++ mögliche Sprachkontrukte erweitert (z.B. PUBLIC, PROTECTED, PRIVATE, THROW, CATCH, TRY, überladene Funktionen, impliziter Konstruktor- und Destruktoraufruf...).

3.1 Syntak und Semantik

3.1.1 Kontrollstrukturen

FPKPascal unterstützt alle von ANSI-Pascal bekannten Kontrollstrukturen, darüberhinaus werden Exceptions unterstützt.

CASE-Anweisung

Bemerkung: FPKPascal entdeckt im Gegensatz zu Turbo Pascal doppelte case-Labels bzw Überschneidungen von Bereichen und weigert sich dann mit einer Fehlermeldung, solche Quelltexte zu übersetzten.

BREAK und CONTINUE

BREAK bricht eine Schleife ab (betrifft FOR, WHILE und REPEAT..UNTIL).

CONTINUE startet eine neuen Schleifendurchlauf (betrifft FOR, WHILE und REPEAT..UNTIL).

Bemerkung: Im Gegensatz zu Turbo Pascal sind BREAK und CONTINUE in FPKPascal Schlüsselwörter.

Unbedingte Sprünge

Der unbedingte Sprung per GOTO sollte eigentlich nicht mehr verwendet werden, da dies meist zu unübersichtlichen Programmen führt (im ganzen Quelltext des FPKPascal-Compilers werden nur in einem Unterprogramm unbedingte Sprünge durchgeführt, da dieses beim Verlassen einige Variablen restaurieren muß). Desweiteren kann FPKPascal nicht optimieren, wenn unbedingte Sprünge verwendet werden, da diese zu sogenannten nicht reduzierbaren Datenflußgraphen führen kann, welche nicht durch eine syntaxgesteuerte Datenflußanalyse, die FPKPascal durchführt, gelöst werden können.

Um GOTO verwenden zu können, muß der Compiler mit dem Kommandozeilenparameter -Sg aufgerufen werden.

Vorsicht: Label können durchaus global deklariert werden, und es kann nun von einem Unterprogramm in ein anderes gesprungen werden, dies führt jedoch meist zu einem Programmabsturz, der Compiler entdeckt diese Fehler nicht!

Empfehlung: Verwenden Sie GOTO und LABEL nicht.

3.2 Laufzeitbibliothek

siehe 4.2

Units

Units sind eine Übernahme aus Modula-2, finden sich aber auch in anderen Pascaldialekten.

4.1 Das Format der PPU-Dateien

Die PPU-Dateien lassen sich in vier Teile gliedern:

1. Header

2. Steuerabschnitt

3. Definitionsabschnitt

4. Symbolabschnitt

Die Größe des Header beträgt konstant 16 Bytes, die unten im einzelnen erklärt werden. Die letzteren drei Abschnitte lassen sich noch in einzelne Einträge einteilen, die jeweils mit einer 1 Byte großen Kennung eingeleitet werden. Die Kennung $FF gibt das Ende des Definitionsabschnittes und des Symbolabschnittes an, der Übergang zwischen Steuerabschnitt und Definitionsabschnitt ist gleitend.

Eine große Hilfe beim Verständnis der PPU-Dateien ist das Hilfsprogramm DUMPPPU, welches den Inhalt von PPU-Dateien anzeigt.

4.1.1 Der Header

Der Header wird mit der Dateikennung PPU006 eingeleitet. Darauf folgt in jeweils einem Byte die Versionsnummer und die Releasenummer des Compilers der die Unit erzeugt hat. Als nächstet folgt ein Byte, welches das Zielbetriebssystem angibt ($00 DOS; $01 OS/2) für das die Unit übersetzt wurde. Nun folgt ein Füllbyte. Als nächstes folgt eine 4 Byte große Prüfsumme, die nur für die Unitversionskontrolle verwendet wird. Die zwei letzten Bytes müssen auf $FF gesetzt sein.

4.1.2 Steurabschnitt

Im Steuerabschnitt ist angegeben, welche Units für die momentane Unit zu laden und zu initialisieren sind.

Tabelle 4.1: Headeraufbau

Byte Zweck
0-5 Kennung (PPU006)
6 Compilerversionsnummer
7 Compilerreleasenummer
8 Zielbetriebssystem
9 reserviert
10-13 Prüfsumme
14-15 reserviert

4.2 Die Standardunits

Folgenden Standardunits werden mit dem Compiler geliefert:

• Die Unit SYSTEM, sie wird automatisch vom Compiler geladen und enthält die elementaren Pascalroutinen

• Die Unit CRT und enthält Routinen um den Bildschirm zu löschen, die Textfarbe ändern, zur Cursorverwaltung etc im Textmodus. Durch das Einbinden dieser Unit wird außerdem die Geschwindigkeit der Bildschirmausgabe gesteigert.

• Die Unit STRINGS enthält Routinen um mit nullterminierten Strings wie unter C arbeiten zu können.

• Die Unit GRAPH ist für die Verwaltung des Graphikbildschirms zuständig und enthält Routinen um Linien zu zeichen, Schrift auszugeben etc

• Ein Interface zum Betriebssystem stellt die Unit DOS zur Verfügung, so kann die Systemzeit gesetzt und abgefragt werden, die DOS-Version, Dateiattribute bearbeitet etc

• Für die Arbeit mit dem Drucker stellt die Unit PRINTER eine Textdateivariable zur Verfügung, die mit dem Standarddrucker verbunden ist

Um Informationen über den genauen Leitungsumfang der Units zu erhalten verschaffen Sie sich am Besten einen Überblick mit Hilfe des Referenzhandbuches über die einzelnen Routinen der Units