17
Das MicroLisp Projekt Max Rottenkolber Sunday, 26 July 2015 Inhaltsverzeichnis 1 Ausgangssituation 1 1.1 Projektziele und Kundenwünsche .............. 1 1.2 Teilaufgaben des Projekts ................... 1 1.3 Projektumfeld und Schnittstellen ............... 3 2 Ressourcen- und Ablaufplanung 3 2.1 Ressourcenplanung ....................... 3 2.2 Ablaufplanung ......................... 4 3 Durchführung und Auftragsbearbeitung 5 3.1 Vorgehensweise & architektonische Entscheidungen .... 5 3.2 Qualitätssicherung ....................... 12 4 Projektergebnisse 14 4.1 Abnahme und Projektübergabe ................ 14 4.2 Fazit ................................ 14 5 Anhang 16 5.1 Anhang 1: Ablaufplan als Flussdiagramm .......... 16 1 Ausgangssituation 1.1 Projektziele und Kundenwünsche Im Rahmen des MicroLisp-Projekts soll eine Umgebung für die Ent- wicklung von Programmen für die MicroTouch-Plattform produziert werden. Die Entwicklungsumgebung soll sowohl einen Kompilierer als auch einen Emulator bereit stellen, die jeweils den entworfenen Lisp- Dialekt MicroLisp implementieren. Der Kunde will die Entwicklung von Anwendungen für die Micro- Touch-Plattform erleichtern und beschleunigen, indem er den direkten 1

Das MicroLisp Projekt · Tag 4 Testphase 1: Analysator-, Makro-, Emulationskompo-nente und Standardbibliothek Tag 6 Meilenstein 2: Lauffähige C-Programme können erzeugt werden Tag

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

  • Das MicroLisp ProjektMax Rottenkolber

    Sunday, 26 July 2015

    Inhaltsverzeichnis

    1 Ausgangssituation 11.1 Projektziele und Kundenwünsche . . . . . . . . . . . . . . 11.2 Teilaufgaben des Projekts . . . . . . . . . . . . . . . . . . . 11.3 Projektumfeld und Schnittstellen . . . . . . . . . . . . . . . 3

    2 Ressourcen- und Ablaufplanung 32.1 Ressourcenplanung . . . . . . . . . . . . . . . . . . . . . . . 32.2 Ablaufplanung . . . . . . . . . . . . . . . . . . . . . . . . . 4

    3 Durchführung und Auftragsbearbeitung 53.1 Vorgehensweise & architektonische Entscheidungen . . . . 53.2 Qualitätssicherung . . . . . . . . . . . . . . . . . . . . . . . 12

    4 Projektergebnisse 144.1 Abnahme und Projektübergabe . . . . . . . . . . . . . . . . 144.2 Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

    5 Anhang 165.1 Anhang 1: Ablaufplan als Flussdiagramm . . . . . . . . . . 16

    1 Ausgangssituation

    1.1 Projektziele und Kundenwünsche

    Im Rahmen des MicroLisp-Projekts soll eine Umgebung für die Ent-wicklung von Programmen für die MicroTouch-Plattform produziertwerden. Die Entwicklungsumgebung soll sowohl einen Kompilierer alsauch einen Emulator bereit stellen, die jeweils den entworfenen Lisp-Dialekt MicroLisp implementieren.

    Der Kunde will die Entwicklung von Anwendungen für die Micro-Touch-Plattform erleichtern und beschleunigen, indem er den direkten

    1

  • Kontakt mit gerätenahen Sprachen wie C und Assemblersprache vermei-det. Die MicroLisp-Sprache soll durch ihre Dynamik und Ausdrucks-stärke einen wesentlich unaufwendigeren Entwicklungsprozess ermög-lichen. Sie soll über eine automatisierte Speicherbereinigung verfügen,den Lambda-Calculus implementieren und plattformspeziefische Opera-tionen wie Ein- und Ausgabe unterstützen. Außerdem soll die Sprachedurch ein Makrosystem erweiterbar sein.

    Mit Beendigung des Projekts soll das Verhältnis zwischen Kostenund Nutzen abgewogen werden. Hierbei soll insbesondere überprüftwerden, ob die erwartete Produktivitätssteigerung erreicht wurde.

    1.2 Teilaufgaben des Projekts

    Der Entwicklung der benötigten Softwarekomponenten geht eine um-fangreiche Planung voraus. Die Planung beinhaltet alle Komponentenund ihre internen Schnittstellen im System. Zusätzlich muss die Inter-aktion mit Schnittstellen außerhalb des Systems geplant werden.

    Die Entwicklungsumgebung besteht aus mehreren Software-Komponenten die in Zusammenarbeit Programme für die zwei End-punkte, Kompilation und Emulation, generieren. Zusätzlich gibt es eineStandardbibliothek die die Sprache mit grundlegenden Prozeduren undMakros anreichert.

    Die Analysatorkomponente liest eine MicroLisp-Quelldatei und er-zeugt einen abstrakten Syntaxbaum. Die Makrokomponente transfor-miert den abstrakten Syntaxbaum mit Hilfe von Makroprozeduren, die un-ter anderem in einer Standardbibliothek definiert sind. Danach kann dasProgramm entweder durch die Emulationskomponente in der Entwick-lungsumgebung interaktiv ausgeführt oder durch die Kompilations-komponente in C-Quelltext umgewandelt werden. Das resultierende C-Programm greift auf die Laufzeitkomponente zurück, um erweiterteFunktionalitäten von MicroLisp zu ermöglichen. Die Entwicklung jederKomponente stellt eine Teilaufgabe dar. Die Komponenten müssen au-ßerdem auf Funktionalität und Korrektheit getestet werden.

    2

  • 1.1 Die Komponenten im Überblick.

    Abschließend soll angesichts einer Kosten-Nutzen-Analyse getestetwerden ob die MicroLisp-Entwicklungsumgebung die Projektziele er-füllt. Dazu wird eine Testanwendung mit MicroLisp und in ANSI C ent-wickelt und die Ergebnisse werden verglichen.

    1.3 Projektumfeld und Schnittstellen

    Die MicroLisp-Sprache ist ein Lisp-Dialekt. Eine detaillierte Definition derSprache kann in der MicroLisp-Bedienungsanleitung gefunden werden.

    MicroLisp-Programme sollen in ANSI C-Quelltext und von dort auswiederum in Maschinenanweisungen für Atmel AVR [Atmel AVR] Pro-zessoren kompiliert werden. Da die MicroTouch-Plattform sehr stark be-grenzte Hardware-Ressourcen bietet, sollen die resultierenden Program-me die Ressourcen des Geräts möglichst schonen.

    Der größte Teil der Komponenten soll in Common Lisp geschrie-ben werden, daher wird eine Schnittstelle die SBCL Common Lisp-Implementation sein. Sie wird die Plattform sein, auf der die Entwick-lungsumgebung ausgeführt wird. Eine weitere Schnittstelle des Systemswird die GNU Compiler Collection, die die generierten C-Programme inMaschinenanweisungen übersetzen soll.

    3

  • 1.2 Systemlandschaft im Überblick.

    2 Ressourcen- und Ablaufplanung

    2.1 Ressourcenplanung

    Die für das MicroLisp-Projekt benötigten materiellen Ressourcen bleibenaufgrund der Software-Lastigkeit des Projekts sehr überschaubar. Fürdie Planung, Entwicklung und Dokumentation der Komponenten wirdmindestens ein Software-Entwickler für die festgesetzte Dauer von 70Stunden benötigt.

    An Sachmitteln fällt ein Arbeitsplatz mit einem Desktop-Computeran. Dieser muss in der Lage sein, ein UNIX-artiges Betriebssystem aus-zuführen, welches wiederum die GNU Compiler Collection und die SBCLCommon Lisp-Implementation unterstützen muss.

    Bis auf die Personalkosten, den Desktop-Computer und den Arbeits-platz fallen keine Kosten an. Die benötigte Software ist Open Sourceund frei verfügbar. Als Betriebssystem kann eine frei erhältliche UN-IX-Variante wie BSD oder Linux verwendet werden.

    2.2 Ablaufplanung

    Zuerst muss das System und seine Architektur geplant werden. Dieals erstes zu programmierende Komponente ist der Analysator. Danachkönnen die Makro- und Emulatorkomponenten parallel programmiertwerden. Wenn die oben genannten Komponenten einsatzbereit sind,ist bereits eine repräsentative Ausführungsumgebung für die MicroLisp-Sprache implementiert. Somit kann die Programmierung der Standardbi-bliothek beginnen und eine Test-Suite für die Sprache geschrieben werden.

    4

  • Mit der Test-Suite müssen dann die primitiven Operatoren der Spra-che, sowie die Prozeduren und Makros der Standardbibliothek auf Kor-rektheit und Integrität getestet werden. Somit soll schon frühzeitig dieFunktionalität der Sprache sichergestellt werden können. Außerdem istes bereits möglich zu prüfen, ob die Sprache die Anforderungen an dieProduktivitätssteigerung beim Programmieren erfüllt.

    Wenn die Tests zeigen, dass ein zufriedenstellender Stand erreicht ist,kann mit der Programmierung der Laufzeitumgebung und der Kompila-tionskomponente begonnen werden. Wenn beide Komponenten funk-tionstüchtig sind, kann MicroLisp-Quelltext in lauffähigen C-Quellcodeübersetzt werden.

    Um die Integrität der Kompilationskomponente und die Korrekt-heit der Laufzeitumgebung zu gewährleisten, wird mithilfe der Test-Suitedie Funktionalität beider Komponenten getestet. Dabei wird besonde-rer Wert auf die Korrektheit interner Vorgänge der Laufzeitkomponentegelegt.

    Wenn die Tests ein überzeugendes Ergebnis liefern, kann die Kosten-Nutzen-Analyse durchgeführt werden. Dazu wird eine ausreichendkomplexe Testanwendung sowohl in MicroLisp als auch in C program-miert. Die resultierenden Anwendungen werden unter den Gesichts-punkten Quelltext-Komplexität, Performanz, Wartbarkeit und Erweiter-barkeit verglichen. Anhand dieses Vergleichs soll die Rentabilität desMicroLisp-Projekts beurteilt werden.

    In Anhang 1 (#section-5-1) wird der oben beschriebene Ablaufplandurch ein Flussdiagramm visuell dargestellt.

    Aus der Ablaufplanung lassen sich mehrere zentrale Termine ent-nehmen. Dazu gehören wichtige Meilensteine in der Programmierungder Komponenten sowie die drei Testphasen. In Abbildung 2.2 werdendie Termine tabellarisch zusammengefasst. Die Terminplanung berück-sichtigt einen Zeitraum von zehn Stunden für das Verfassen der Projekt-dokumentation.

    5

  • Tag Teilaufgabe

    Tag 2 Meilenstein 1: Erste repräsentativeAusführungsumgebung

    Tag 4 Testphase 1: Analysator-, Makro-, Emulationskompo-nente und Standardbibliothek

    Tag 6 Meilenstein 2: Lauffähige C-Programme können erzeugtwerden

    Tag 7 Testphase 2: Laufzeitumgebung undKompilationskomponente

    Tag 8 Testphase 3: Kosten-Nutzen-Analyse durchTestanwendung

    2.2 Termine aus der Ablaufplanung.

    3 Durchführung und Auftragsbearbeitung

    3.1 Vorgehensweise & architektonische Entscheidungen

    Die Projektdurchführung beginnt, wie in Abbildung 2.1 veranschaulichtwird, mit der Planung der Systemarchitektur. Ich entscheide mich, wiein Abbildung 1.1 dargestellt wird, für eine modulare Architektur. Diesetrennt Softwarekomponenten mit unabhängigen Funktionalitäten sau-ber von einander ab. Quelltext 3.1 veranschaulicht wie das System Sub-komponenten, ohne geteilten Status oder verknüpfter Semantik, in einerOberprozedur kombiniert.

    (defun evaluate (expression environment)

    "Evaluate MicroLisp EXPRESSION in ENVIRONMENT."

    (evaluate-expanded-expression

    (expand-expression expression *macros*)

    environment))

    3.1 Definition der Emulationsfunktion evaluate.

    Diese Art der Programmierung hat den Vorteil, dass ausgehend vomQuelltextbeispiel 3.1 die Prozedur evaluate-expanded-expression un-abhängig von der Prozedur expand-expression definiert werden kann.Gleichermaßen benötigt die Oberprozedur evaluate keine Informatio-nen über Implementationsdetails der anderen beiden Prozeduren, um

    6

  • sie anzuwenden. Diese Eigenschaften erleichtern nachträgliche Ände-rungen und Erweiterungen an Systemkomponenten und beschränkendie Komplexität des gesamten Systems.

    Die Analysatorkomponente kann mit geringem Aufwand entwickeltwerden, da die MicroLisp-Sprache und Common Lisp untereinander Syn-taxregeln teilen. Die benötigten Prozeduren zum Einlesen von MicroLisp-Quelldateien werden von Common Lisp zur Verfügung gestellt. Diese ge-nerieren einen abstrakten Syntaxbaum der als verschachtelte Listenstrukturrepräsentiert wird. Die in Abbildung 3.2 veranschaulichte Repräsentati-onsform, ermöglicht es MicroLisp-Quelltext mit geringem Aufwand zuverarbeiten.

    3.2 Interne Repräsentation des abstrakten Syntaxbaums. Dargestellt durch die sogenannte "Box and PointerNotation.

    Nun können Makrokomponente und Emulationskomponente paral-lel entwickelt werden. Weil ich alleine am MicroLisp-Projekt arbeite, ent-scheide ich mich dafür die Makrokomponente als erstes zu implementie-ren. Diese Komponente sucht in einem Abstrakten Syntaxbaum, ausgege-ben von der Analysatorkomponente, nach Ausdrücken, für die in einerMakrotabelle ein Makro definiert ist und dehnt die Ausdrücke mithilfe desMakros aus.

    (defun expand-expression (expression macros)

    "Expand MACROS in EXPRESSION and return expanded expression."

    [...])

    3.3 Signatur der Prozedur zum Suchen und Ausdehnen von Makroausdrücken.

    Ein Makro ist als eine Prozedur implementiert, die als Parameter dieArgumente eines Makroausdrucks annimmt und einen neuen Ausdruckals Rückgabewert hat. Quelltext 3.4 zeigt eine einfache Makroprozedur.

    7

  • (lambda (condition then else)

    `(cond (,condition ,then)

    (t ,else)))

    3.4 Makroprozedur die einen klassischen if-Ausdruck zu einem cond-Ausdruckausdehnt.

    Angenommen die Prozedur expand-expression aus Quelltext 3.3findet einen Ausdruck in der Form (if BEDINGUNG WAHR-AUSDRUCKFALSCH-AUSDRUCK), übergibt diesen Ausdruck an die Makroprozeduraus Quelltext 3.4 und ersetzt ihn mit dem Rückgabewert, dannlautet der ausgedehnte Ausdruck (cond (BEDINGUNG WAHR-AUSDRUCK)(t FALSCH-AUSDRUCK)). So wurde der MicroLisp-Sprache mithilfe desAxioms cond ein neues Kontrollkonstrukt if hinzugefügt.

    Die Entwicklung der Emulationskomponente birgt zwei Hauptpro-bleme: Die Umsetzung von Axiomen und die Implementation von Pro-zeduren. Die MicroLisp-Axiome und -Datentypen lassen sich mithilfevon Common Lisp mit wenig Aufwand umsetzten, weil beide Sprachenauf den gleichen Kernfunktionen aufbauen. Es müssen lediglich dieMicroLisp-Axiome und -Datentypen den entsprechenden Operatoren ausCommon Lisp zugeordnet werden.

    (add (+ (evaluate (first call-arguments) environment)

    (evaluate (second call-arguments) environment)))

    3.5 Ausschnitt aus der Emulationskomponente: Umsetzung des add-Axioms.

    Quelltext 3.5 zeigt eine Klausel aus einem case-Ausdruck. Jedes Axi-om wird in einer Klausel wie dieser implementiert. Das add-Axiom zumAddieren von Zahlen wird umgesetzt, indem die Argumente (MicroLisp-Ausdrücke) mit der Emulationskomponente rekursiv ausgewertet wer-den und mit dem Common Lisp Additionsoperator + summiert werden.

    MicroLisp-Prozeduren müssen einer essentiellen Anforderung ge-recht werden. Sie müssen den lexikalischen Sichtbarkeitsbereich von Be-zeichnern innerhalb ihres Körpers, genannt Funktionsabschluss, imple-mentieren. Dafür muss die Zuordnung von Bezeichnern und Werten,auch Environment genannt, zur Zeit der Prozedurdefinition konserviertwerden.

    8

  • (defun make-procedure (lambda-expression environment)

    "Return new procedure consisting of LAMBDA-EXPRESSION and

    ENVIRONMENT."

    (unless (lambda-p lambda-expression)

    (error "~a is not a valid lambda expression."

    lambda-expression))

    (list 'procedure

    lambda-expression

    environment))

    3.6 Konstruktor für eine Prozedur.

    Quelltext 3.6 zeigt wie der Konstruktor make-procedure ein Prozedu-robjekt instanziiert. Er übernimmt einen Lambda-Ausdruck und ein En-vironment als Parameter und gibt ein Objekt zurück, das den Lambda-Ausdruck mit dem Environment verknüpft. Wenn eine Prozedur aufge-rufen wird, werden die Bezeichner im Körper der Prozedur mithilfe deskonservierten Environments Werten zugeordnet.

    Die initiale Standardbibliothek beinhaltet Prozeduren und Makros, dieder Entwicklung der Test-Suite erleichtern. Die Implementation dieserist nicht zwangsweise trivial, jedoch spielt sie im Rahmen des Micro-Lisp-Projekts eine geringfügige Rolle und wird deswegen nicht genauererläutert.

    Als nächstes wird die wichtigste und komplexeste Komponente, dieLaufzeitumgebung entwickelt. Die Repräsentation von Werten stellt dieerste Herausforderung dar. Aufgrund der dynamischen Eigenschaftenvon MicroLisp muss die statische Typisierung von C umgangen werden.

    9

  • enum type { PROCEDURE, CELL, SYMBOL, NUMBER, CHARACTER };

    [...]

    typedef struct {

    enum type type;

    struct symbol *symbol;

    } symbol;

    [...]

    union value {

    enum type type;

    procedure procedure;

    cell cell;

    symbol symbol;

    number number;

    character character;

    };

    typedef union value value;

    3.7 Definition des value-Typs durch geschickte Ausnutzung von C struct- undunion-Ausdrücken.

    Quelltext 3.7 zeigt, wie die Typen der MicroLisp-Sprache zu einemTyp value zusammengefasst werden. Alle Typen sowie die value unionhaben ein Feld type. Dieses ermöglicht den speziellen Typ eines value-Objekts zu ermitteln. So können MicroLisp-Objekte innerhalb der Lauf-zeitumgebung einheitlich als value-Objekt herumgereicht werden. DieseTechnik impliziert, dass die primtiven Operatoren die Typen von Objek-ten zur Laufzeit überprüfen müssen, um Speicherzugriffsfehler zu vermei-den.

    Anders als bei der Emulationskomponente müssen die Axiome undDatentypen der Sprache von Hand implementiert werden. Beispielswei-se müssen in Symbole mit C Strukuren implementiert werden.

    10

  • /* symbol-structure: Symbol structure. */

    struct symbol {

    unsigned long identifier;

    char *name;

    };

    /* symbol: Constants and prototypes for symbol functions. */

    #define T new_symbol("T")

    #define NIL NULL

    symbol *new_symbol (char *);

    symbol *symbolic_equality (symbol *, symbol *);

    symbol *symbol_p (value *);

    3.8 Struktur und Schnittstelle des symbol-Typs.

    Quelltext 3.8 zeigt Details der internen Repräsentation von Symbo-len. Die Prozedur new_symbol wird verwendet um Symbole aus Literalenzu erzeugen. Sie nimmt einen Namen in Form einer Zeichenkette alsParameter und gibt das entsprechende Symbol zurück. Weil Symbole ein-zigartig sind und es aber mehrere Instanzen von einem Symbol gebenkann werden sie nicht im symbol-Objekt gespeichert. Stattdessen suchtnew_symbol in einer Tabelle nach einer symbol-Struktur mit gleichemNamen. Wenn keine passende Struktur gefunden wird, fügt new_symboleinen neuen Eintrag für ein Symbol mit dem Namen und einem eindeu-tigen Schlüssel in die Tabelle ein. Anschließend wird ein symbol-Objektmit einem Zeiger auf die entsprechende Struktur zurückgegeben.

    Es sind zwei spezielle Symbole T und NIL vordefiniert, konventionellindizieren sie die Wahrheitswerte. Die Prozedur symbolic_equality ent-spricht dem symbolic=-Axiom. Sie gibt NIL zurück, wenn die Schlüsselder übergebenen Symbole nicht gleich sind. Die Prozedur symbol_p ent-spricht dem symbol?-Axiom und gibt NIL zurück wenn das übergebeneObjekt nicht vom Typ symbol ist, wie sich durch das uniforme type-Felddes value-Typs feststellen lässt.

    Die Implementation des symbol-Typs ermöglicht den effizienten Ver-gleich von Symbolen anhand eines numerischen Schlüssels, anstatt zumBeispiel einer Zeichenkette. Weil Symbole primär als Schlüssel verwendetwerden, sind die Eigenschaften dieser Implementation essenziell für diePerformanz der Sprache.

    11

  • Die MicroLisp-Sprache soll automatisierte Speicherbereinigung imple-mentieren. Standardmäßig unterstützt C jedoch nur manuelle Speicher-verwaltung. Um diese Diskrepanz zu überwinden, wird ein schlankerReferenzzählender Garbage Collector mit folgender Schnittstelle implemen-tiert.

    void use (value *);

    void disuse (value *);

    void collect_garbage (void);

    3.9 Schnittstelle des Garbage Collectors.

    Die use-Prozedur inkrementiert den Referenzzähler eines Objekts. Die-ser Referenzzähler wird in einer Hashtabelle gespeichert, die die Speicher-adressen der Objekte als Schlüssel verwendet. Wenn ein Objekt noch kei-nen Eintrag in der Referenztabelle hat wird dieser von use eingefügt.Die disuse-Prozedur dekrementiert den Referenzzähler eines Objekts. Diecollect_garbage-Prozedur befreit den Speicherplatz, der von Speicher-adressen in der Referenztabelle referenziert wird, wenn der entsprechen-de Referenzzähler null ist.

    Die use- und disuse-Prozeduren werden von Prozeduren der Lauf-zeitumgebung aufgerufen, die Objekte binden. So bindet zum Bei-spiel die new_procedure-Prozedur, die eine MicroLisp-Prozedur instan-ziiert, die Objekte in ihrem Environment. Die Verwendung der use-und disuse-Prozeduren garantiert in diesem Fall das die Objekte ausdem Environment solange verfügbar sind wie sie benötigt werden. Diecollect_garbage-Prozedur wird periodisch von der Laufzeitumgebungaufgerufen, um den Speicher zu bereinigen.

    Es wurde die Referenzzählende Variante des Garbage Collectiors ge-wählt, weil sie vergleichsweise implementationsunaufwendig ist. Derimplementierte Garbage Collector kann die standard Speicherverwal-tungsprozeduren malloc und free verwenden und es muss kein spe-zieller Heap implementiert werden, wie zum Beispiel bei der Mark andSweep Variante.

    Als Letztes muss die Kompilationskomponente entwickelt werdenund dank der umfangreichen Laufzeitumgebung muss diese nur noch einProblem lösen. Die MicroLisp-Sprache behandelt Prozeduren als Objek-te erster Klasse. Dementsprechend können Prozeduren an jedem Ort imQuelltext definiert werden. C unterstützt allerdings nur Prozedurdefini-tonen auf oberster Ebene des Quelltextes.

    12

  • (defun nextract-procedures (expanded-expressions)

    "Extract procedures from EXPANDED-EXPRESSIONS, return procedures

    and expressions in which procedures are replaced with pointers

    (desctructively)."

    [...])

    3.10 Prozedursignatur aus der Kompilationskomponente zum Extrahieren vonProzedurdefinitionen.

    Quelltext 3.10 zeigt die Signatur der Prozedur zum Extrahieren vonProzedurdefinitionen. Die extrahierten Prozedurdefinitionen werdendann gesammelt am Anfang des resultierenden C-Programms als Proze-duren proc1 bis procN definiert und können aufgrund der vorhersehba-ren Namenskonvention von Aufrufen der new_procedure-Prozedur re-ferenziert werden.

    3.2 Qualitätssicherung

    Um die Qualität der Softwarekomponenten während der Entwicklungzu sichern, wird eine Test-Suite geschrieben die die Axiome der Sprachesowie die Prozeduren und Makros der Standardbibliothek abdeckt.

    (test (assert "T does not evaluate to itself."

    (symbolic= t (quote t)))

    [...])

    3.11 Ausschnitt aus der Test-Suite.

    Quelltext 3.11 zeigt einen Ausschnitt aus der Test-Suite. Die Test-Suitewird wie in der Ablaufplanung beschrieben Ausgewertet um die Funk-tionalität der Systemkomponenten zu verifizieren, wenn die Meilenstei-ne erreicht sind. Um die Laufzeitkomponente zusätzlich zu verifizierenwird ein C-Profiler verwendet. Die Internen Vorgänge der Laufzeitumge-bung werden Analysiert um subtile Fehler wie Speicherlecks aufzudecken.

    Abschließend wird eine Testanwendung sowohl in MicroLisp als auchin ANSI C entwickelt. Die Quelltexte der Testanwendungen units.mlund units-c.c sind unter dem Verzeichnis test/ hinterlegt. BeideAnwendungen sind vom Funktionsumfang her identisch. Sie interpre-tieren eine einfache Sprache zum Umwandeln von Längeneinheitenund berichten die Ergebnisse. Um beide Entwicklungsumgebungen zuvergleichen, werden relevante Merkmale von units und units-c ausEntwickler- und Benutzersicht gemessen.

    13

  • Laufzeit units 1x units-c 1x units 1000x units-c1000x

    real 0.008s 0.007s 7.373s 6.378s

    user 0.003s 0.000s 2.070s 0.540s

    sys 0.003s 0.000s 2.976s 1.193s

    3.12 Messergebnisse von time. real bezeichnet die Zeit zwischen Aufruf undBeendigung des Programs, user bezeichnet die Zeit die im Benutzermodus undsys die Zeit die im Kernelmodus verbracht wird.

    Weil der Funktionsumfang beider Anwendungen identisch ist kannaus Sicht des Benutzers nur die Performanz verglichen werden. Mitdem UNIX-Werkzeug time wird die Laufzeit beider Anwendungen ge-messen. Die Messergebnisse in Tabelle 3.12 zeigen, dass messbare Per-formanzunterschiede erst bei sehr langen Berechnungen auftreten. DerBenutzer kann den Performanzunterschied bei den Testanwendungennicht wahrnehmen.

    Aus Sicht des Entwicklers fällt nicht nur auf, dass die C-Anwendungfast doppelt so lang ist. Die Einheitentabelle kann in der MicroLisp-Anwendung mithilfe der primitiven Datentypen zentral und Leserlichdefiniert werden. In der C-Anwendung muss eine passende Datenstruk-tur erst geschaffen werden. Dabei kommen einige Implementationsfra-gen auf, wie zum Beispiel arbiträre Begrenzungen, die nicht relevant fürdie Logik der Anwendung sind. Um eine neue Längeneinheit zu defi-nieren müssen mehrere Stellen im Quelltext angepasst werden.

    Zusätzlich ermöglicht die MicroLisp-Sprache intensive Abstraktiondurch Prozeduren höherer Ordnung wie find und map. C erschwertdurch das statische Typsystem selbst die Abstraktion von generischenOperationen. Durch die verringerte Abstraktion muss der Entwicklerder C-Anwendung auf eine Vielzahl von unrelevanten Details achten.

    Der direkte Vergleich zeigt, dass die C-Anwendung nicht nur inder initialen Entwicklung wesentlich aufwendiger ist. Auch die Wart-und Erweiterbarkeit ist erschwert. Es wird sichtbar das die MicroLisp-Entwicklungsumgebung den Aufwand der Anwendungsentwicklunglangfristig stark mindert.

    14

  • 4 Projektergebnisse

    4.1 Abnahme und Projektübergabe

    In das Abnahmeprotokoll fließt eine Analyse von Stand und Funktiona-lität der Softwarekomponenten sowie die Kosten-Nutzen-Analyse ein.Tabelle 4.1 zeigt das Abnahmeprotokoll.

    Abnahmekriterium Ergebnis (Fehler-grad)

    Funktionalität durch Test-Suite bestätigt Ja

    Laufzeitkomponente ist Performanzoptimiert Nein (3)

    automatisierte Speicherbereinigung ist funktio-nal

    Ja

    Lambda-Calculus ist implementiert Ja

    Axiome für Ein- und Ausgabe vorhanden undfunktional

    Ja

    Ergebnisse der Kosten-Nutzen-Analyse zufrie-denstellend

    Ja

    Qualität der Dokumentation zufriedenstellend Ja

    4.1 Abnahmeprotokoll des MicroLisp-Projekts. Fehlergrad: 1 = hoch, 2 = mittel,3 = niedrig.

    Da das Abnahmeprotokoll keine wesentlichen Mängel aufweist, kanndas Projekt wie geplant übergeben werden. Die Laufzeitumgebung wirdden Anforderungen an Funktionalität zwar gerecht, ihre Performanz istallerdings verbesserungswürdig. Weitere Entwicklung im Umfang derSystemwartung soll die Performanz der Laufzeitumgebung optimierenund gegebenenfalls bisher unerkannte Fehler beheben.

    4.2 Fazit

    Im Rahmen des Projekts wurde eine umfangreiche Entwicklungsum-gebung für die MicroLisp-Sprache entwickelt. Die geforderten Kompo-nenten sind funktionstüchtig und werden den Kundenwünschen weit-gehend gerecht. Das resultierende Softwaresystem ist in der Lage, dieMicroLisp-Sprache zu emulieren und nach C zu kompilieren und bietetden gewünschten Makro-Mechanismus zur Erweiterung der Sprache.

    15

  • Der geplante Ablauf konnte eingehalten werden und die gewähl-ten Methoden haben sich bewährt. Allerdings muss angemerkt werden,dass die der Laufzeitumgebung inhärente Komplexität größer ist als ange-nommen wurde. Demnach konnte die Qualität der Laufzeitkomponentenur auf einen zufriedenstellenden aber verbesserungswürdigen Standgebracht werden.

    Vor Beginn des Projekts hätte der Aufwand für die Entwicklung dereinzelnen Softwarekomponenten intensiver evaluiert werden müssen.Eine detailliertere Abschätzung des Aufwands hätte zu dem Ergebnisgeführt, dass das System innerhalb der festgesetzten 70 Stunden zwarvollständig entwickelt werden kann, jedoch reicht die Zeit nicht aus umdie gewünschte Qualität aller Softwarekomponenten zu erreichen. DerProjektantrag hätte also spezifizieren müssen, dass das Ziel des Projektseine Vorabversion der Entwicklungsumgebung ist, die nachträglich ite-rativ weiterentwickelt werden soll.

    Als besonders positiv kann die Test-Suite bewertet werden. Sie stellteinen Qualitätssicherungsmechanismus für mehrere Komponenten desSystems dar, weil sie sowohl die Emulations- und Kompilations- sowieMakro- und Laufzeitkomponente testet. Es stellt sich außerdem heraus,dass der geplante Ablauf, in Form der Emulationskomponente, sehrschnell eine Implementation der konzipierten Sprache produziert. Dieinitiale Implementation ermöglicht schon früh das Testen der Spracheund stellt eine Referenz für weitere Entwicklungsschritte dar.

    Abschließend kann gesagt werden, dass die Entwicklung der Mi-croLisp-Entwicklungsumgebung noch nicht endgültig abgeschlossen ist.Im Rahmen des MicroLisp-Projekts wurde allerdings ein robustes underweiterbares System entwickelt, welches fast allen Anforderungen ge-recht wird und einen wichtigen Meilenstein darstellt. Somit wurde eineProduktionstaugliche Umgebung für die Entwicklung komplexer Soft-ware geschaffen. Dementsprechend ist das Projekt in seiner Gesamtheitals erfolgreich zu bewerten.

    16

  • 5 Anhang

    5.1 Anhang 1: Ablaufplan als Flussdiagramm

    7.1 Geplanter Ablauf im Flussdiagramm.

    17