New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer...

25
Arbeitsgruppe Programmiersprachen und ¨ Ubersetzerkonstruktion Institut f¨ ur Informatik Christian-Albrechts-Universit¨ at zu Kiel Seminararbeit Lua 5.2 eine Multiparadigma Skriptsprache Niels Matthiessen WS 2012/2013 Betreuer: Fabian Reck

Transcript of New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer...

Page 1: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

Arbeitsgruppe Programmiersprachen und UbersetzerkonstruktionInstitut fur InformatikChristian-Albrechts-Universitat zu Kiel

Seminararbeit

Lua 5.2

eine Multiparadigma Skriptsprache

Niels Matthiessen

WS 2012/2013

Betreuer: Fabian Reck

Page 2: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

Inhaltsverzeichnis

1. Einfuhrung 11.1. Geschichte der Sprache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2. Entwicklung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3. Paradigma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2. Anwendungsgebiet 32.1. Wofur ist die Sprache beabsichtigt? . . . . . . . . . . . . . . . . . . . . . . 32.2. Wofur wird die Sprache genutzt? . . . . . . . . . . . . . . . . . . . . . . . 3

3. Konzepte und Struktur 53.1. Sprachbeschreibung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3.1.1. Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63.1.2. Tabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.1.3. Virtuelle Maschine . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.1.4. C API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83.1.5. Error handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93.1.6. Coroutinen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2. Konzepte anhand von Beispielen . . . . . . . . . . . . . . . . . . . . . . . 103.2.1. Umgebungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103.2.2. Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.2.3. Metatabellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133.2.4. Objektorientierte Programmierung . . . . . . . . . . . . . . . . . . 143.2.5. Lua als funktionale Sprache . . . . . . . . . . . . . . . . . . . . . . 153.2.6. C API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4. Technische Unterstutzung 184.1. Compiler, Interpreter, Entwicklungsumgebung . . . . . . . . . . . . . . . . 184.2. Werkzeuge und Bibliotheken . . . . . . . . . . . . . . . . . . . . . . . . . . 184.3. Portabilitat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

5. Diskussion und Zusammenfassung 205.1. Vergleichbare Sprachen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205.2. Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

A. Einfuhrung in die Syntax von Lua 21

ii

Page 3: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

1. Einfuhrung

Die Sprache Lua wird seit dem Jahr 1993 an der PUC-Rio, einer Universitat in Rio deJainero, Brasilien, entwickelt. Sie ist die einzige Programmiersprache aus einem Entwick-lungsland, die internationale Bedeutung erlangt hat [1, Kap. 1].

1.1. Geschichte der Sprache

Die Notwendigkeit, die Sprache Lua zu entwickeln enstand aus einer sehr restriktivenGesetzgebung in Brasilien, die den Import von Computerhardware und -software ein-schrankte, mit der Begrundung, dass das Land selbst dazu in der Lage sein musse undes auch sei, diese zu produzieren. Außerdem fanden die Entwickler zum damaligen Zeit-punkt keine Sprache, die ihren Anspruchen genugte.Lua bildet die Nachfolge der Konfigurationssprache SOL (Simple Object Language), diezur Erstellung von Berichten aus Analysedaten benutzt wurde, aber nicht mehr ausrei-chend fur sich andernde Anspruche der Benutzer war und erweitert werden musste.Daraufhin wurde das Lua-Team gegrundet, das sich seitdem mit der Entwicklung derSprache befasst. Dieses Team besteht aus den drei Mitgliedern Roberto Ierusalimschy,Luiz Henrique de Figueiredo und Waldemar Celes [1, Kap. 3]. Seit der Version 1.0 aus1993 hat sich vieles geandert, jedoch nimmt die Haufigkeit der Anderungen ab, mankann sagen, die Sprache hat ihre Kinderkrankheiten uberwunden, so wurde die Version5.0 bereits im Jahr 2003 veroffentlicht. Die aktuelle Version der Sprache ist 5.2.1, vom14. Juni 2012. Auch wenn sich das Aussehen der Sprache und ihre Anwendungsgebietenicht stark geandert haben so hat sich in ihrem Inneren viel verandert. Lua wurde mitjeder Veroffentlichung um mindestens ein Feature erweitert. Einige Konzepte wurdenvon einer Version zur nachsten komplett uberdacht und neuentwickelt [1, Kap. 5].

1.2. Entwicklung

Obwohl die Sprache OpenSource ist und frei verwendet werden kann, wird sie nicht wieoft ublich von einer Community entwickelt. Jede Anderung wird von den drei Entwick-lern ausgefuhrt. Das bedeutet aber nicht, dass Lua uber keine aktive Community verfugt,die die Entwicklung durch Wunsche und Anregungen vorantreibt, es wird dennoch keinCode aus der Community ubernommen, sondern jede Anderung vom Team selbst ge-schrieben. Viele Anforderungen an die Sprachen kommen auch direkt aus der Industrie,die Lua einsetzt. Durch diese Art der Entwicklung ist die Große der Sprache, sowohlanhand der Anzahl ihrer vorgefertigten Werkzeuge, als auch der Große des Codes, sehrklein geblieben. Aber ihre Werkzeuge sind machtig und wohldurchdacht.

1

Page 4: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

1. Einfuhrung

Eine Besonderheit von Lua ist, dass die einzelnen Versionen nicht zwingend abwartskom-patibel sind. Das gibt den Entwicklern die Moglichkeit trotz grundlegender Anderungendie Große der Sprache minimal zu halten [1, Kap. 5]. Bei der Entwicklung wird aufeinige Punkte sehr großen Wert gelegt. Mit der Einhaltung dieser selbst gesetzten Qua-litatsstandards wir oft auch der Erfolg der Sprache begrundet.

1. Effizienz : Die Sprache soll mit einer einfachen Syntax und einer geringen Menge vonProgrammstrukturen auskommen und dadurch eine moglichst schnelle Compilier-und Ausfuhrungsdauer erreichen.

2. Portabilitat : Lua soll auf jeglicher Art von Hard- und Software ohne Anpassungdes Codes lauffahig sein. Dies gilt sowohl fur Lua-Programme, als auch fur denLua-Interpreter.

3. Einbindbarkeit : Ein großes Ziel von Lua ist es, moglichst einfach in andere Pro-gramme integrierbar zu sein. Dafur muss die API (application programming inter-face) klar definiert sein und eine effiziente Kommunikation zwischen Lua und demHost-Programm ermoglichen.

Die Portabilitat wird dadurch erreicht, dass der Lua-Interpreter in striktem ANSI-Cprogrammiert ist. Dadurch ist gewahrleistet, dass dieser auf nahezu allen Plattformenohne Anpassung kompiliert. Da in der Regel fur neue Hardware C Compiler als erstesentwickelt werden, wird Lua auf dieser sehr fruh unterstutzt [2, Kap. 2].

1.3. Paradigma

Es ist nicht leicht Lua einem festen Programmierparadigma zuzuordnen. In der Literaturwird Lua oft als Multiparadigma Sprache bezeichnet [3], was aber keine sehr konkreteAussage ist, außerdem werden einige Paradigmen nicht direkt unterstutzt, sondern sindnur durch die Erweiterbarkeit der Sprache leicht zu implementieren. Diese Paradigmenwerden Lua aber im Allgemeinen ebenfalls zugeschrieben.Lua ist primar eine prozedurale Programmiersprache und wird auch uberwiegend alssolche genutzt. Sie erfullt aber auch alle Kriterien der funktionalen Programmierung.Desweiteren ist sie eine Scriptsprache, kann aber auch mit einem Compiler zu Objekt-Code compiliert werden. Die zentrale Datenstruktur in Lua ist ein assoziatives Array,die sogenannte table, uber die weitere Paradigmen leicht zu realisieren sind. So werdenModule in der Regel uber eine Verschachtelung dieser Tabellen dargestellt, woruberauf die Modulfunktionen zugegriffen werden kann. Auch Klassen und Objekte konnenuber Tabellen dargestellt werden, womit es moglich ist, Vererbung per Delegation undUberladung von Funktionen und Variablen zu realisieren.

2

Page 5: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

2. Anwendungsgebiet

Die Sprache Lua wird in allen erdenklichen Anwendungen fur Skriptsprachen benutzt.Die Nutzung beginnt als einfache Konfigurationsdatei, ahnlich wie .ini Dateien abermit erweiterten Moglichkeiten, die auch der Verhaltenssteuerung in der Robotik, oderin der Webentwicklung als CGI-Skript genugen. Es gibt ebenfalls ganze Programme wieWebserver oder Texteditoren, die in Lua geschrieben sind. Besondere Beliebtheit hat dieSprache in der Spieleentwicklung gewonnen, wo sie zu der meistbenutzten Skriptsprachegeworden ist [4].

2.1. Wofur ist die Sprache beabsichtigt?

Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die ander PUC genutzt wurden. Die erste Sprache DEL (data-entry language) wurde dazubenutzt, Eingabedateien fur andere Programme zu erzeugen. DEL war als sehr einfache,deklarative Sprache konzipiert. Mit Lua war es moglich, Kontrollstrukturen zu benutzen,was die Komplexitat der erzeugten Eingabedateien und damit deren Moglichkeiten starkerhohte. Die zweite Sprache ist die bereits angesprochene SOL. Dieser fehlte es an Un-terstutzung fur prozedurale Programmierung, die fur Erweiterungen von zu erstellendenBerichtdateien benotigt wurde.Bereits am Anfang der Entwicklung von Lua war klar, dass diese Sprache mehr Potentialhaben sollte, als SOL und DEL zu ersetzen. Es wurde immer mit dem Blick auf Por-tabilitat, Erweiterbarkeit, kleine Programmgroße und Effizienz entwickelt. Damit solltesichergestellt werden, dass Lua auch fur spatere Projekte ausreichend ist [1, Kap. 3].Von Beginn der Entwicklung wurde auf einige Punkte besonderer Wert gelegt. Luasollte grundlegend einfach zu programmieren sein, denn da sie zuerst vor allem alsKonfigurationssprache gedacht war, sollte sie auch von Personen genutzt werden konnen,die keine Erfahrung im Programmieren haben. Außerdem sollte auch die Umgewohnungvon anderen Sprachen moglichst einfach sein, so kann man unter anderem einen Aus-druck mit einem Semikolon abschließen, wie es beispielsweise in C notwendig ist, musses aber nicht, wie es unter anderem in Fortran gemacht wird [5, Kap. 1.1].

2.2. Wofur wird die Sprache genutzt?

Dem Potential, das Lua letztendlich entwickelte, war sich 1993 keiner der Entwicklerbewusst. Lua wird innerhalb der PUC heute noch fur die Zwecke genutzt, fur die sieanfangs entwickelt wurde. Abgesehen davon ist sie fester Bestandteil in großen interna-tionalen Projekten geworden. Durch die Lizenzierung der Sprache mit der MIT-Lizenz

3

Page 6: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

2. Anwendungsgebiet

ist es moglich, sie auch in kommerziellen Projekten zu verwenden.Beispiele:

1. In Adobe Photoshop Lightroom wird Lua zur Bildbearbeitung und fur add-inseingesetzt. Dadurch ist es dem Benutzer moglich, Skripte zu schreiben und damitdas Programm den eigenen speziellen Bedurfnissen anzupassen.

2. Die CryEngine 3 vom deutschen Spielehersteller Crytec benutzt Lua als Skrip-sprache zur Steuerung der KI und zur Erzeugung von Ereignissen innerhalb desSpielgeschehens.

3. In dem Computerspiel World of Warcraft wird ebenfalls Lua als Skriptspracheverwendet. Damit wird es dem Benutzer ermoglicht, sein User Interface frei nachseinen Vorstellungen anzupassen.

4. Xavante ist ein Webserver fur HTTP 1.1 der komplett in Lua geschrieben unddamit sehr leicht portabel ist, er kann auch als Bibliothek in andere Luaprogrammeeingebunden werden.

5. Aber auch die Schadsoftware Flame, die 2012 von Kaspersky Lab auf Rechnernmehrerer Staaten in Nahost entdeckt wurde, benutzt Lua, um unkompliziert effek-tive Angriffe auszufuhren[6].

4

Page 7: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Im Anhang befindet sich eine kurze Einfuhrung in die Syntax von Lua. Diese ist lediglichals Zusammenfassung gedacht und ihr Inhalt wird in diesem Kapitel nicht vorrausgesetzt.Innerhalb des Beispielcodes sind Kommentare, wie in Lua ublich, mit -- gekennzeichnet.Mit --> sind die Ausgaben der Programmzeile gemeint.

3.1. Sprachbeschreibung

Lua besitzt die acht verschiedene Datentypen nil, boolean, number, table, string,function, thread und userdata. Dabei ist Lua eine dynamisch getypte Sprache, dasbedeutet, dass nicht die Variablen Typen haben, sondern nur die Werte. Der Typ nil

besitz nur den Wert nil und ist vergleichbar mit dem Nullpointer in C, er zeigt an, dasskeine Daten vorliegen.Als boolean gibt es true und false, wobei in boolschen Ausdrucken nil aquivalent zufalse und alles andere aquivalent zu true ist.Zahlen (number) werden als 64 Bit Fließkommazahlen abgespeichert, einen Datentypvergleichbar zu integer gibt es nicht. Bei der Nutzung von Lua wird ein integer Typauch nicht benotigt, denn es konnen alle ganzen Zahlen bis ±253 als number exakt dar-gestellt werden. Die meisten heutigen Systeme bieten eine Hardware Floatingpoint Un-terstutzung, sodass das Rechnen mit diese genauso schnell ablauft wie mit integern.Der zentrale Datentyp in Lua in die table. Diese ist ein Assoziatives Array, uber dassich alle herkommlichen Datentypen, wie Listen, Objekte, Module oder Strukturen dar-stellen lassen.Anders als in C ist ein string kein Array von characters, sondern ein abstrakter Daten-typ, auf den nur uber entsprechende String-Funktionen zugegriffen wird. Beim Bearbei-ten eines strings wird ein neuer Wert mit entsprechendem Inhalt erstellt. Ein string

darf anders als in vielen Sprachen beliebige Bytes enthalten. Ein Null-Byte beispielsweisegibt nicht das Ende des strings an, sondern darf im Text vorkommen.Da Funktionen auch Werte erster Klasse sind und in Variablen gespeichert werden, gibtes auch den Datentyp function, den man mit einer Liste von Argumenten aufrufen kannund entsprechende Ruckgabewerte erhalt.Zur parallelen Ausfuhrung von Programmcode verfugt Lua uber threads. Dabei han-delt es sich aber um eine Lua-eigene Implementierung von Nebenlaufigkeit und nicht umThreads des Betriebssystems.Fur vorerst unbekannte Daten, wie structs aus C, die von Lua verarbeitet werden sol-len, gibt es den Datentyp userdata dessen Inhalt nicht spezifiziert ist.In Lua gibt es keine explizite Deklaration von Variablen. Um eine Variable nutzen zu

5

Page 8: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

konnen, muss man ihr lediglich einen Wert zuweisen, die Speicherallozierung wird auto-matisch durchgefuhrt. Variablennamen durfen aus Buchstaben, Ziffern und Unterstrichenbestehen, wobei das erste Zeichen keine Ziffer sein darf. Wird eine Variable genutzt, be-vor ihr ein Wert zugewiesen wurde, hat sie den Wert nil. Zuweisungen werden mit dem= Operator durchgefuhrt. In Lua sind auch Mehrfachzuweisungen moglich, außerdemkonnen Funktionen mehrere Ruckgabewerte haben.

a = 1

a, b = 1, 2 -- a = 1 und b = 2

a, b = b, a -- tauschen der Werte von a und b

a, b = 1 -- a = 1 und b uninitalisiert

a, b = 1, 2, 3 -- a = 1, b = 2 und die 3 geht verloren

-- Funktion mit mehreren Ruckgabewerten, a = 3 und b = 4

a, b = (function () return 3, 4 end)()

Variablen die mit zwei Unterstrichen oder einem Unterstrich und einem Großbuchstabenbeginnen, sind von Lua fur bestimmte Zwecke reserviert und sollten nicht anderweitiggenutzt werden. Ein Beispiel dafur ist die Tabelle G, in ihr sind alle globalen Variablenhinterlegt. Beim Uberschreiben von G wird also der Zugriff auf alle globalen Varia-blen, also auch die Standardbibliotheken unmoglich. Um nicht mehr referenzierte Datenkummert sich Lua selbst mit einer Garbage Collection. Es ist nicht moglich, Speichermanuell wieder freizugeben, jedoch kann man Einfluss auf die Ausfuhrung der GarbageCollection nehmen. [7]

3.1.1. Funktionen

Eine Funktion wird durch den Funktionskonstruktor erstellt und die erstellte Funktionwird von diesem zuruckgegeben. Es ist auch moglich, Funktionen so zu definieren, wieman es aus anderen Sprachen wie Java oder C gewohnt ist.

function() end -- einfacher Funktionskonstruktor

add1 = function(value) -- normale Funktionsdefinition

return value + 1

end

function add1(value) -- aquavalent zur vorherigen Definition

return value + 1

end

Funktionen in Lua erinnern sehr stark an Funktionen aus der funktionalen Programmie-rung. Da die Funktionsnamen Variablen sind, kann man Funktionen auch als Parameteroder Ruckgabewert ubergeben. Dadurch ist es auch insbesondere moglich Funktionen zuuberschreiben. Wir konnen beispielsweise die standard print Funktion durch eine selbsterstellte ersetzen.

print = function(str)

print("Lua says: ", str)

end

6

Page 9: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Funktionen konnen auch wahrend der Programmausfuhrung erzeugt werden, dabei wer-den closures genutzt. Das bedeutet, dass der Wert lokaler Variablen aus dem Kontextder Funtionserstellung ubernommen wird, auch wenn diese zum Zeitpunkt der Funk-tionsausfuhrung nicht mehr existieren. Diese Prizip ist auch unter dem Begriff lexicalscoping bekannt.Beim Aufruf einer Funktion muss die Anzahl der Parameter nicht mit denen in der Funk-tionsdefinition ubereinstimmen. Wird die Funktion mit zu wenig Parametern aufgerufen,werden die restlichen mit nil aufgefullt. Beim Aufruf mit zu vielen Parametern werdendie uberflussigen nicht beachtet. Die Ruckgabe einer Funktion ist nicht, wie bei vielenanderen Sprachen ublich, auf einen Wert beschrankt, sondern kann beliebig viele Wertebeinhalten. Dafur werden Zuweisungen mit mehreren Variablen unterstutzt.Lua unterstutzt ebenfalls proper tail calls. Das bewirkt, zum Beispiel bei einer Rekursion,wenn der Aufruf der nachsten Rekursionsebene die letzte Anweisung in der Funktion istund die Funktion das Ergebnis der weiteren Rekursion zuruckgibt, dass das Rekursions-ergebnis nicht durch alle Rekursionsebenen durchgereicht, sondern direkt zuruckgegebenwird.

3.1.2. Tabellen

Eine Tabelle ist in Lua ein assoziatives Array, das bedeutet, es besteht aus Schlussel-WertPaaren. Der Tabellenkonstruktor ist ein Paar geschweifter Klammern. In diesem konnenmit Kommas getrennte Schlussel-Wert Paare ubergeben werden. Es ist nicht notwendig,einen Schlussel anzugeben. Werte, die ohne Schlussel in eine Tabelle geschrieben werden,bekommen automatisch als Schlussel eine noch nicht vergebene naturliche Zahl, begon-nen mit eins, zugewiesen. Als Schlussel und Wert eines Eintrags sind alle Datentypenaußer nil erlaubt. Die Angabe der Schlussel innerhalb des Konstruktors und der Zugriffauf eine Tabelle erfolgen, wie man es aus anderen Sprachen von Arrays gewonht ist. EineBesonderheit gilt hier fur Schlussel, die den oben genannten Kriterien von Variablenna-men entsprechen. Auf diese kann auch per Punktnotation zugegriffen werden und imTabellenkonstruktor wird die Arrayschreibweise nicht benotig.

tabelle = {} -- leere Tabelle

tabelle = {key = "value", ["Schlussel"] = "Wert"}print(tabelle.key, tabelle["Schlussel"]) --> value Wert

tabelle = {"Montag", "Dienstag"}print(tabelle[0], tabelle[1], tabelle[2]) --> nil Montag Dienstag

Die table ist die zentrale und auch die einzige Datenstruktur in Lua, sie wird zu jeglicherStrukturierung der Programmdaten genutzt. Die interne Implementierung von tables

passt die Art der Speicherung an die Daten an, die in der Tabelle liegen. Nutzt man dieTabelle lediglich als Array, so werden die Daten intern so abgelegt, dass die Zugriffszeit,wie bei einem Array, konstant ist. Bei der Nutzung von Strings als Schlussel, erfolgt derinterne Zugriff auf die Werte uber Hashtables, sodass die Zugriffszeit ebenfalls geringgehalten wird. Mit Tabellen sind beispielsweise die Module in Lua realisiert. So greiftder Befehl io.write("Hello World!") auf die Funktion write() uber die Tabelle io

7

Page 10: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

zu, in welcher sich das Modul fur die System Ein- und Ausgaben befindet.

3.1.3. Virtuelle Maschine

Die Ausfuhrung von Lua erfolgt auf einer virtuellen Maschine. Daten, welche die LuaVirtual Machine verarbeitet, werden chunks genannt. Ein chunk ist eine Menge vonAnweisungen, die auf einmal eingelesen werden. Wird eine Datei mit Lua Sourcecode inein Lua Programm geladen, so handelt es sich bei dem Inhalt der Datei um einen chunk.Ebenso ist eine Zeile, die man in den Standalone-Interpreter eingibt ein chunk.Zur Verabeitung der chunks werden zuerst die Anweisungen in opcode fur die virtuelleMaschine ubersetzt und anschließend werden diese ausgefuhrt. Der opcode ist eine eigeneSprache die sich durch einen Assemblercode darstellen lassen kann. Es gibt 35 Befehle,an die jeweils noch Registeradressen angefugt werden, sodass ein opcode Befehl immer32 Bit lang ist. Die virtuelle Maschine von Lua ist registerbasiert, im Gegensatz zu denvirtuellen Maschinen der meisten anderen Sprachen, die stackbasiert arbeiten.Bei einer stackbasierten virtuellen Maschine werden fur die Ausfuhrung eines Befehlsalle benotigten Parameter auf den Stack gelegt, dann wird der Befehl ausgefuhrt, derdie Argumente vom Stack liest und das Ergebnis ebenfalls wieder auf den Stack legt.So werden bei einer stackbasierten virtuellen Maschine fur eine Addition drei Befehlebenotig, zwei um die Werte auf den Stack zu legen und einen um die Addition aus-zufuhren. Eine registerbasierte virtuellen Maschine arbeitet anstatt mit dem Stack mitRegistern. Dadurch werden theoretisch anstatt der drei Befehle nur einer benotig umzwei Zahlen zu addieren. Nur theoretisch deshalb, weil die Werte naturlich auch zuerstin die Register geschrieben werden mussen. Es wird jedoch davon ausgegangen, dassmit einem Wert mehr als eine Operation stattfindet, sodass das Laden in das Registervernachlassigt werden kann. Die Vorteile einer registerbasierten virtuellen Maschine er-geben sich daraus, dass durch die geringere Anzahl an Befehlen, die Große des opcodessinkt und die Geschwindigkeit der Ausfuhrung steigt. Diese Vorteile sind aber stark um-stritten, da bei stackbasierten virtuellen Maschine die Große der Befehle meist nur 16oder 8 Bit betragt und die Dauer der Ausfuhrung eines registerbasierten Befehls unterUmstanden langer dauert, als die eines stackbasierten Befehls. Somit ist der Vorteil derRegister anwendungsabhangig und kann nicht pauschal als dem Stack uberlegen bewer-tet werden.Lua arbeitete vor der Version 5.0 selbst auch mit einer stackbasierten virtuellen Ma-schine. Im dierekten Vergleich uberzeugte die Entwickler dann aber die registerbasiertevirtuellen Maschine mit der sie bei einigen Tests die Laufzeit auf bis zu 44% verringernkonnten. [2]

3.1.4. C API

Auch wenn man Lua Skripte im Standaloneinterpreter ausfuhren kann, ist Lua vor al-lem dafur konzipiert, als embedded language genutzt zu werden. Dafur ist die Spra-che in C geschrieben und kann als Bibliotek in ein C-Programm eingebunden werden.

8

Page 11: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Zum Ausfuhren von Lua Code muss ein lua State erstellt werden, innerhalb dessen dieAusfuhrung von Lua stattfindet. Um die Ausfuhrung von Lua Code zu starten kann manbeispielsweise diese Funktion nutzen:

int luaL dostring(lua State *L, const char *str);

Sie interpretiert den String str als Lua Code und fuhrt ihn in dem lua State L aus.In dem lua State ist der Zustand der Ausfuhrung, also alle Variablen, Funktionen, etc.gespeichert.Zur Kommunikation zwischen dem C Teil und dem Lua Teil des Programms gibt esdie C API. Diese ermoglicht es vom C Programm auf einen lua State zuzugreifen. ZurKommunikation zwischen den beiden Teilen wird ein virtueller Stack genutzt. Von Caus ist es moglich Daten auf den Stack zu legen, Daten vom Stack und Variablen ausLua auszulesen und Funktionen aus Lua auszufuhren. Auf dem Stack kann C alles ab-legen, womit es arbeiten kann, so konnen auch Funktionen an Lua ubergeben werden.Durch diese Funktionen ist es dann ebenfalls moglich von Lua aus auf den C Teil desProgramms zuzugreifen. Fur Daten mit denen Lua selbst nichts anfangen kann, wie einin C selbst erstelltes struct, gibt es in Lua den Datentyp userdata. Dahinter konnensich beliebige Daten befinden. Um mit Lua auf diesen Daten arbeiten zu konnen, mussendie entsprechenden Bearbeitungsfunktionen von C aus bereitgestellt werden.Es ist beispielsweise leicht moglich mit diesen Verfahren Lua zur Erstellung von Pluginszu nutzen. Angenommen wir programmieren in C einen Texteditor, den wir mit Luaerweiterbar machen mochten. Es soll mit Lua im speziellen moglich sein, dem Texteditoreine Tastenkombination hinzuzufugen, mit der in einem markierten Text alle Großbuch-staben in Kleinbuchstaben geandert werden. Im C Teil des Programms benotigen wirdafur drei Funktionen, die von Lua aus aufgerufen werden konnen. Die ersten beidenFunktionen mussen es ermoglichen den Inhalt des im Editor markierten Textes zu lesenund zu schreiben. Mit der dritten Funktion muss es moglich sein auf das Event einerTastenkombination, die Ausfuhrung einer Lua Funktion zu registrieren. In der Lua Dateiwird eine Funktion benotig, die uber die C Funktionen den Inhalt des markierten Textesliest, die Anderung durchfuhrt und den geanderten String zuruck schreibt. Außerdembenotigen wir von Lua aus einen Aufruf der dritten C Funktion, der die Lua Funktionauf die gewunschte Tastenkombination registriert. Nach dem Ausfuhren der Lua Dateivon C aus ist es sofort moglich die Tastenkombination zu benutzen.

3.1.5. Error handling

In Lua ist es moglich, beim Auftreten eines Laufzeitfehlers eine Exception zu werfen.Diese bewirkt, dass die Ausfuhrung des chunk unterbrochen wird und in das Host-programm zuruckgesprungen wird. Dann gibt die luaL dostring() Funktion, mit derder chunk aufgerufen wurde, false zuruck und auf dem Stack der C API liegt derErrorstring der Exception. Die entsprechende Fehlerbehandlung muss dann vom Host-programm durchgefuhrt werden. Bei einem Großteil der auftretenden Fehler ist es abergar nicht erwunscht dass die Ausfuhrung komplett unterbrochen wird, sondern es sollinnerhalb von Lua auf die Exception reagiert werden. Dafur steht die pcall() Funktion

9

Page 12: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

zur Verfugung. Mit ihr kann eine Funktion im protected mode ausgefuhrt werden und siefangt alle bei der Ausfuhrung entstandenen Exceptions, ohne die Ausfuhrung von Luazu unterbrechen. Obwohl es die pcall() Funktion gibt, werden in der Praxis Excepti-ons oft nur dafur eingesetzt, die Ausfuhrung zu beenden. Wenn ein Fehler aufgetretenist, auf den innerhalb von Lua reagiert werden soll, wird in der Regel die Funktion,in der der Fehler entstanden ist, uber das return einen Errorcode zuruckgeben, zumBeispiel als ersten Ruckgabewert nil und als weitere Ruckgabewerte einen Errorstring,oder eine Tabelle mit weiteren Informationen uber den aufgetretenen Fehler, auf den dieaufrufende Funktion entsprechend reagieren kann.

3.1.6. Coroutinen

In Lua wird kein echtes Multitasking, also das gleichzeitige Ausfuhren von Anweisungen,unterstutzt. Das liegt ganz einfach daran, dass dieses von ANSI-C nicht zur Verfugunggestellt wird. Die Datenstruktur thread steht fur einen Ausfuhrungsfaden, wie man esauch von POSIX threads gewohnt ist. Dazu verfugt jeder thread uber einen eigenen Pro-gram Counter. Der Programmablauf mit Coroutinen funktioniert ahnlich zu dem Prinzipdes Monitors. Es gibt nur einen thread der zur Zeit ausfuhren darf, alle anderen threads

warten darauf, dass ihnen signalisiert wird, dass sie ausfuhren durfen. Jedoch erfolgt dasWarten und Signalisieren anders als im Monitor. Es gibt keine Warteschlangen, sondernder aktuelle thread entscheidet, welcher thread als nachstes ausfuhren darf. Dazu stehendie Funktionen coroutine.yield(...) zum Warten und coroutine.resume(thread,

...) zum Aufwecken eines threads zur Verfugung. Dabei ist es moglich uber dieseFunktionen auch Werte an die aufgerufene, oder aufrufende Funktion zu senden. Dasyield() gibt die Parameter des resume() zuruck und andersherum.Echtes Multitasking muss vom Hostprogramm bereitgestellt werden. Dazu muss dasHostprogramm uber mehrere lua States verfugen und diese jeweils in einem eigenenPOSIX thread laufen lassen. Diese Situation ist dann vergleichbar mit UNIX Prozessen.Sie haben die Moglichkeit, gleichzeitig zu laufen und arbeiten jeweis auf ihrem eige-nen Speicher. Fur die Kommunikation zwischen den lua States ist das Hostprogrammzustandig, das entsprechende Funktionen zu Verfugung stellen muss, die von Lua aus ge-nutzt werden konnen. Beim Arbeiten mit mehreren POSIX threads muss darauf geachtetwerden, dass nicht von mehreren gleichzeitig auf einen lua State zugegriffen wird. Daim lua State unter anderem der aktuelle Program Counter und die Position der Regis-ter im Arbeitsspeicher gespeichert sind, wurde das Ausfuhren mehrerer Funktionen, diegleichzeitig auf diesen zugreifen, zu undefiniertem Verhalten fuhren.

3.2. Konzepte anhand von Beispielen

3.2.1. Umgebungen

In Lua werden drei Arten von Variablen unterschieden. Diese sind globale, lokale undnicht-lokale Variablen. Bei der Definition von Variablen muss man darauf achten, dassalle Variablen, die nicht anders gekennzeichnet werden, global definiert sind. Jedoch be-

10

Page 13: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

deutet in Lua global etwas anderes, als man es aus anderen Sprachen gewohnt ist. Fangenwir damit an, was nicht-globale Variablen sind. Lokale Variablen sind, wie gewohnlich,nur lokal sichtbar, also innerhalb der Funktion, Schleife oder dem Ausdruck in dem siedefiniert sind. Dabei haben lokale Variablen die hochste Prioritat beim Zugriff. Existie-ren also lokale und globale Variablen mit dem selben Namen, wird immer auf die lokaleVariable zugegriffen. Zur Definition von lokalen Variablen steht das Schlusselwort localzur Verfugung, außerdem sind Funktionsargumente immer lokal definiert. Nicht-lokaleVariablen, oder auch upvalues genannt, sind Variablen, die in einem ubergeordnetenClosure als lokale Variablen definiert sind.

fun = function(a)

return function(b)

b = b + a -- b ist lokal, a ist upvalue

local a = 1 -- erstellen eines lokalen a

b = b + a -- b und a sind lokal

return b

end

end

print(fun(2)(3)) --> 6

Kommen wir nun zu den globalen Variablen. Am Anfang dieses Kapitels wurde ge-sagt, die globalen Variablen stehen in der Tabelle G. Das ist jedoch so nicht unbedingtkorrekt. Um das Ganze zu verstehen, betrachten wir an folgendem Beispiel, was beimInterpretieren von Lua Code mit globalen Variablen geschieht.

-- Ausgangsfunktion -- Funktion aus sicht des Interpreters

fun = function() -- fun = function()

a = b + 1 -- ENV[a] = ENV[b] + 1

end -- end

Es gibt also eine Variable ENV uber die auf globalen Variablen zugegriffen wird. Woherdiese Variable kommt und was sie mit der Tabelle G zu tun hat, sieht man, wenn man sichanguckt, was beim Laden eines chunks passiert. Dafur gehen wir davon aus, dass beimErstellen eines lua State in C, in Lua die Tabelle G erstellt wird. Aus dem folgendenCode der Datei example.lua wird beim Lades der Datei beispielsweise in C mit demBefehl lua loadfile() die folgende Lua Funktion erstellt.

11

Page 14: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

-- example.lua

a = 5

-- rest vom Code

funktion()

local ENV = G

-- example.lua

ENV[a] = 5

-- rest vom Code

end

Die vorhin bereits angesprochene Funktion luaL dostring ist eine Kombination auslua loadstring() (aquivalent zu lua loadfile() fur Strings) und dem ausfuhren derFunktion. In der Tabelle G werden also alle globalen Variablen eines lua State gespei-chert. Wir haben aber dadurch, dass der Zugriff auf G uber die Variable ENV lauft, dieMoglichkeit, eine neue globale Umgebung zu erstellen und sogar die globale Umgebungeiner Funktion an eine andere zu ubergeben.

3.2.2. Module

Ein Modul wird in Lua durch eine Tabelle reprasentiert, in der die Funktionen desModuls liegen. Um ein Modul in Lua zu laden gibt es die require Funktion. Diesefunktioniert ahnlich der dofile Funktion, das heißt, sie lad die Datei als chunk und fuhrtdiesen aus. Jedoch hat require Besonderheiten. Die Funktion speichert ein geladenesModul zwischen. Wenn also ein Modul mehrmals geladen wird, wird trotzdem nur einmalauf die Datei zugegriffen. Außerdem sucht die Funktion nach dem Modul nicht nur imaktuellen Verzeichnis, sondern sucht ebenfalls in den Standardbibliotheks Verzeichnissendes Betriebssystems. Die Standardmodule werden in der Regel beim Programmstartfolgendermaßen geladen

string = require("string")

io = require("io")

-- und so weiter

Beim Schreiben von Modulen erstellt man also eine Tabelle mit den Funktionen und gibtdiese aus dem chunk zuruck.

M = {}M.foo = function() return dosomething() end

return M

Das return außerhalb einer Funktion sieht auf den ersten Blick etwas ungewohnt aus,jedoch wird ein chunk beim Laden in Lua als Funktion dargestellt. Dadurch gibt dierequire Funktion beim Laden des Moduls die Tabelle M zuruck.

12

Page 15: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

3.2.3. Metatabellen

Eine besondere Anwendung der Tabelle ist die metatable. Diese ermoglicht es, ein be-stimmtes Verhalten zu erzeugen. Dazu kann man einem Wert eine metatable zuweisen.Dabei ist es nur bei den Datentypen table und userdata moglich, dass jeder Wert ei-ne eigene metatable besitzt, bei allen anderen Datentypen teilen sich diese jeweils alleWerte des Datentyps. In der metatable befinden sich Funktionen, die als metamethodsbezeichnet werden. Diese Funktionen sind dafur gedacht allgemeine Operationen auf denjeweiligen Daten durchzufuhren. Beispielweise kann man damit Operatoren uberladenoder tostring Methoden definieren. Der Operator + ist fur Tabellen nicht definiert. Wirkonnen mit einer passenden metatable den Operator so definieren, dass er zu jedem Ele-ment der Tabelle, das vom Typ number ist, einen bestimmten Wert hinzuaddiert. Dazuweisen wir dem Schlussel add der metatable eine Funktion zu, welche die Tabelle undden Wert ubergeben bekommt, und diesen auf jedes Element der Tabelle aufaddiert.

numbers = {1, "a", 2}meta = { add = function(tab, adder)

for k, v in pairs(tab) do

if tonumber(v) then tab[k] = v + adder end

end

return tab

end}-- mache meta zur metatable von numbers

setmetatable(numbers, meta)

n = numbers + 3 -- erhohe Zahlen in numbers um 3

print(numbers[1], numbers[2], numbers[3]) --> 4 a 5

Es ist nicht moglich, eigene Operatorzeichen zu definieren. Der Operator += der in demobigen Beispiel passender gewesen ware, um zu zeigen, dass die Operation Seiteneffekteerzeugt, ist in Lua nicht vorhanden und kann auch nicht definiert werden. Abgesehen vonden Operatoren, bieten die metatables noch mehr Moglichkeiten. Der index Schlusselder metatable beispielsweise, wird aufgerufen, wenn ein Zugriff auf einen nicht vorhande-nen Schlussel einer Tabelle stattfindet. Damit ist es zum Beispiel moglich einer Tabelleeinen Standardwert zu geben. Hinter dem index Schlussel muss keine Funktion liegen,sondern es kann auch eine Tabelle sein. Dann werden die entsprechenden Schlussel ausder hinterlegten Tabelle abgefragt.

t = {12} -- t[1] = 12

meta = { index = function(tab, key) return 0 end}setmetatable(t, meta) -- Funktion als Referenz

print(t[0], t[1], t[2]) --> 0 12 0

getmetatable(t). index = {1, 2} -- Tabelle als Referenz

print(t[0], t[1], t[2]) --> nil 12 2

13

Page 16: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

3.2.4. Objektorientierte Programmierung

Die wichtigsten Konzepte von objektorientierten Sprachen sind Klassen, Objekte undVererbung. Diese drei Konzepte stehen in Lua nicht zur Verfugung, sie konnen abersimuliert werden. Dazu benotigen wir metatables und den : Operator. Wir erstelleneine Klasse, indem wir deren Attribute und Methoden in eine Tabelle speichern. Daes sich bei einer so definierten Klasse genaugenommen selbst schon um eine Instanzhandelt, spricht man hier von prototypenbasierter Objektorientierung. Um ein Objektder Klasse zu erstellen erzeugen wir eine leere Tabelle mit einer metatable, deren Schlusselindex auf die Klasse verweist. Beim Zugriff auf die Methoden benotigen wir dann den

: Operator. Dieser bewirkt, dass das Objekt, aus dem die Methode aufgerufen wird, andie Methode ubergeben wird. So sind folgende Zeilen Aquivalent:

a.dosomething(a, args)

a:dosomething(args)

Wenn wir auf eine der Methoden, oder Attribute der Klasse zugreifen, die in der neu er-stellten Tabelle nicht existieren, so werden uber die metatable die entsprechenden Werteder Klasse abgefragt. Wenn wir ein Attribut uberschreiben, wird der neue Wert in demObjekt gespeichert. Da das Attribut in dem Objekt besteht, wird beim Zugriff auf dasAttribut nicht mehr der Wert aus der Klasse abgefragt. Ein einfaches Bankkonto lasstsich wie folgt Implementieren:

BankAccount = {balance = 0,

new = function(self) -- neues Konto erstellen

local object = {}setmetatable(object, { index = self})return object

end,

deposit = function(self, amount) -- Geld abheben/einzahlen

self.balance = self.balance + amount

end,

getbalance = function(self) -- Kontostand abfragen

return self.balance

end

}

Das Erstellen von und Arbeiten mit Objekten funktioniert dann ganz ahnlich, wie manes aus anderen objektorientierten Sprachen gewohnt ist.

acc1 = BankAccount:new()

acc2 = BankAccount:new()

print(acc1:getbalance(), acc2:getbalance()) --> 0 0

acc1:deposit(100)

print(acc1:getbalance(), acc2:getbalance()) --> 100 0

14

Page 17: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Eine Unterklasse zu erstellen, funktioniert aufgrund der prototypenbasierten Objekt-orientierung genauso, wie das Erstellen eines Objekts. Dadurch erbt die Unterklasseautomatisch alles der Elternklasse. Um Weitere Attribute und Methoden zu der Unter-klasse hinzuzufugen, mussen diese in der Tabelle der Unterklasse abgelegt werden, sokonnen auch Methoden einfach uberladen werden. Der hier erstellte SpecialAccount

erhoht den Kontostand bei jeder Uberweisung um 5, und bietet die Moglichkeit geklontzu werden.

SpecialAccount = BankAccount:new()

SpecialAccount.deposit = function(self, amount)

self.balance = self.balance + amount + 5

end

SpecialAccount.clone = function(self)

local clone = {balance = self:getbalance()}setmetatable(clone, getmetatable(self))

return clone

end

acc3 = SpecialAccount:new()

print(acc3:getbalance()) --> 0

acc3:deposit(100)

acc4 = acc3:clone()

print(acc3:getbalance(), acc4:getbalance()) --> 105 105

acc3:deposit(100)

print(acc3:getbalance(), acc4:getbalance()) --> 210 105

Auch Mehrfachvererbung lasst sich so realisieren indem man die Metatables der Eltern-klassen zu einer zusammenfugt. Dazu benotigt man allerdings noch eine Funktion, diebei Vorkommen der gleichen Attribute oder Methoden entscheidet, welche ausgewahltwerden soll.

3.2.5. Lua als funktionale Sprache

Eine funktionale Sprache kommt ohne Listen nicht aus, diese sind in Lua recht einfach zuerzeugen. Ein Listenelement wird durch eine Tabelle mit den Schlusseln value und rest

dargestellt. Um das Hinzufugen eines Elements zu einer Liste komfortabel zu gestalten,konnen wir mit Hilfe der metatables den .. Operator der standardmaßig nur fur dieStringkonkatenation genutzt wird, fur diesen Zweck uberladen. Der .. Operator wirduber den Schlussel concat angesporchen.

meta = { concat = function(elem, list)

result = {value = elem, rest = list}setmetatable(result, getmetatable(list))

return result

end}emptylist = {}setmetatable(emptylist, meta)

15

Page 18: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Da der Konkatenations-Operator von rechts nach links auswertet, funktioniert diesesauch mit Strings, obwohl der Operator auf diesen bereits definiert ist, ohne deren Funk-tionalitat zu verandern. Die folgenden beiden Anweisungen haben also unterschiedlicheBedeutung, da sie den Operator unterschiedlich nutzen.

list = "hello" .. "world" .. emptylist -- Liste mit zwei Elementen

list = ("hello" .. "world") .. emptylist -- Liste mit einem Element

Mit diesem recht einfachen Konstrukt kann gearbeitet werden, wie man es von funk-tionalen Sprachen gewohnt ist. Dabei wird allerding nicht die Komfortabilitat andererfunktionaler Sprachen, wie Haskell geboten, wo mit pattern matching oder unendlichenListen gerarbeitet werden kann. Eine einfache map Funktion lasst sich so implementieren.

map = function(list, func)

if list == emptylist then return emptylist

else return func(list.value) .. map(list.rest, func) end

end

list = 1 .. 5 .. emptylist

add1 = function(x) return x + 1 end

list = map(list, add1) -- list = 2 .. 6 .. emptylist

3.2.6. C API

Die C API ermoglicht es Lua in andere Programme einzubinden. Dazu benotigt maninnerhalb des C Programms nur die lua.h Header Datei. Sehr hilfreich sind außerdemdie Header Dateien lualib.h zum Laden der Standardbibliotheken und lauxlib.h furerweiterte Funktionen zur Arbeit mit Lua. Zur Kommunikation zwischen Lua und Cwird ein Stack verwendet. Dazu gibt es Funktionen, um von C aus auf diesen Stackzuzugreifen und ihn zu verandern. Diese Funktionen sind recht gewohnungsbedurftigund schwer zu lesen. Es gibt Funktionen, um etwas von C auf den Stack zu legen undFunktionen, um etwas von Lua auf den Stack zu legen. Genauso gibt es Funktionen,um Werte vom Stack in eine C Variable, oder eine Lua Variable zu schreiben. Von Caus kann auf beliebige Positionen im Stack zugegriffen werden. Der Zugriff erfolgt ubereinen ganzzahligen Index. Dabei geben positive Zahlen den Index gezahlt vom Bodendes Stacks und negative Zahlen den Index gezahlt von der Spitze des Stack an.Angenommen, wir mochten Lua zur Konfiguration eines Programms nutzen. Es sollmoglich gemacht werden, durch die Konfigurationsdatei eine Schriftgroße einzustellen.Dazu benotigen wir in der Lua Datei eine globale Variable mit fesgelegtem Namen (hierim Beispiel font size), in der die Schriftgroße gespeichert ist. Damit haben wir ge-genuber einer einfachen Textdatei als Konfigurationsdatei noch nichts gewonnen. DenVorteil von Lua finden wir, wenn wir das Szenario etwas erweitern. Angenommen, wirmochten die Schriftgroße von der Große des Fensters abhangig machen. Dazu konnenwir in C eine Funktion zur Verfugung stellen, mit der die Große des Fensters abgefragtwerden kann. In der Lua Datei kann dann die gewunschte Schriftgroße berechnet undin der Variablen hinterlegt werden. Von C aus kann dann auf diese Variable zugegriffenund die berechnete Schriftgroße ausgelesen werden.

16

Page 19: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

3. Konzepte und Struktur

Inhalt der Datei rc.lua:

font size = (get window size() / 20) - 0.5

C Code des Programms:

#include <lua.h>

#include <lauxlib.h>

int window heigth;

Die folgende Funktion soll von Lua aus Aufgerufen werden und die Fenstergroße zuruckgeben.

static int get window size(lua State *L) {/* Fenstergroße auf den Stack legen */

lua pushnumber(L, (double)window heigth);

return 1; /* Anzahl der return Werte auf dem Stack */

}

Diese Funktion lad die Variable font size aus Lua.

void run commands(lua State *L, double *font size) {luaL dofile("rc.lua"); /* Ausfuhren der Lua Datei */

/* Variable von Lua auf den Stack legen */

lua getglobal(L, "font size");

/* Variable vom Stack auslesen */

*font size = lua tonumber(L, -1);

}

In der main Funktion wird ein neuer lua State erstellt und die Funktion get window size

Lua zur Verfugung gestellt.

int main() {lua State *L = luaL newstate();

/* Funktion auf den Stack legen */

lua pushfunction(L, get window size);

/* Funktion in globaler Variable hinterlegen */

lua setglobal(L, "get window size");

double font size;

run commands(L, &font size);

/* Rest des Programms */

/* ... */

return 0;

}

17

Page 20: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

4. Technische Unterstutzung

4.1. Compiler, Interpreter, Entwicklungsumgebung

Lua wird auf der offiziellen Website lua.org als Sourcecode zur Verfugung gestellt. Dieaktuelle Version 5.2.1 umfasst entpackt 896 KiB und enthalt den Code fur die Biblio-thek, den Standalone Interpreter und Precompiler, sowie die zugehorigen man pages,und das Reference Manual in html. Fur diverse Linux Distributionen, und andere UNIXDerivate, sowie Windows gibt es auch vorkompilierte Versionen.Zusatzlich zum offiziellen Lua Paket gibt es auch noch weitere inoffizielle Compiler undInterpreter. Die meisten Compiler sind dafur programmiert worden, um Lua Code fureine andere virtuelle Maschine zu ubersetzen. Speziell zu erwahnen ist dabei LuaJIT,ein Just-in-Time Compiler fur Lua, der Lua Code direkt in Bytecode fur diverse Hardwa-rearchitekturen ubersetzt, sodass die Lua Virtual Machine nicht genutzt werden muss.Dadurch kann die Geschwindigkeit von vielen Lua Programmen um ein Vielfaches erhohtwerden.Lua kann man aufgrund seiner einfachen Struktur und Ubersichtlichkeit recht komforta-bel in einem Texteditor mit Syntax Highlighting schreiben. Es gibt aber auch IDEs diedas Programmieren durch Code completition und Anzeige einer Projektstruktur verein-fachen sollen. Jedoch ist deren Unterstutzung nicht so hilfreich, da in Lua, wie in anderenSkriptsprachen auch, zur Compilezeit nicht sehr viel uber den Zustand von Variablenund deren Werte ausgesagt werden kann. Der einzige große Vorteil einiger Entwicklungs-umgebungen ist ein Debuger. Allerdings konnen die IDEs den Einfluss des C Programmsnicht berucksichtigen, was sie fur die meisten Lua Programme ebenfalls uninteressantmacht. Die am weitesten verbreitete frei verfugbare IDE fur Lua ist Lua DevelopmentTools, ein Plugin fur Eclipse.

4.2. Werkzeuge und Bibliotheken

Lua enthalt sieben Standardbibliotheken, diese sind math fur mathematische Funktio-nen, bit32 fur bitwise Opearationen auf Zahlen, table zum erweiterten Arbeiten aufTabellen, string zur manipulation von Zeichenketten, io fur Ausgaben in Dateien oderStandardausgabe, os fur Datumsfunktionen und Umgabungsvariablen und debug zumerleichterten Analysieren des Programmablaufs.Zusatzlich zu den offiziellen Standardbibliotheken gibt es auch eine Menge an Bibliothe-ken aus der Lua Community. Beim Suchen nach Bibliotheken hilft das ModulverzeichnisLuaRocks, das außerdem ein Modulmanagement System zum Downloaden und auto-matischen Aktualisieren der Module bereitstellt. Dort stehen zur Zeit rund 300 Module

18

Page 21: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

4. Technische Unterstutzung

zur Verfugung. Ein sehr hilfreiches Werkzeug zum Dokumentieren von Lua Code istLuaDoc. Dieses erstellt, ahnlich wie Javadoc, automatisch aus speziellen Kommentarenein html Dokument. Ein LuaDoc Kommentar beginnt mit drei anstatt zwei Minuszei-chen. Zur beschreibung von Funktionen und Modulen stehen wie in Javadoc @param und@return und noch weitere tags zur Verfugung.

4.3. Portabilitat

Wie in der Einleitung bereits angesprochen, ist die Portabilitat eines der wichtigstenZiele von Lua. Damit gemeint ist die Moglichkeit, Lua Code auf moglichst allen Hard-und Softwaresystemen ausfuhren zu konnen. Jedoch gibt es auch noch eine Art der Por-tabilitat, die von Lua nicht so einfach unterstutzt wird. Das ist die Moglichkeit Lua auchin andere Programme als C einzubinden. Als einzige weitere Sprache wird C++ offiziellunterstutzt, da diese die C Bibliotheken ebenfalls nutzen kann[7]. Fur andere Sprachen,wie Java werden Erweiterungen der C Bibliotheken benotigt, die es ermoglichen diesezu nutzen. Da dies fur die meisten Sprachen recht schwer zu erreichen ist, gibts es vieleRewrites der Lua Virtual Machine in den entsprechenden Sprachen. Mit den Rewritesgibt es jedoch viele Probleme, so werden teilweise nicht alle Funktionalitaten von Luaunterstutzt, oder die Rewrites existieren nur fur alte Versionen von Lua.Ein sehr gutes Rewrite um Lua in Java nutzen zu konnen ist Luaj, dieses ubersetzt denLua Code in Java-Bytecode und stellt eine API in Java zur Verfugung, die der C APIrecht ahnlich ist.

19

Page 22: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

5. Diskussion und Zusammenfassung

5.1. Vergleichbare Sprachen

Es gibt viele Sprachen, die die gleichen oder ahnliche Konzepte wie Lua bieten. Diegroßte und bekannteste dieser Sprachen ist Python. Ware Python bereits zur Zeit, inder die Entwicklung von Lua beschlossen wurde, so ausgereift wie heutzutage, ware dieNotwendigkeit, Lua zu entwickeln, moglicherweise gar nicht entstanden[1, Kap. 4]. Auchwenn sich Python und Lua ahneln sind ihre Konzepte trotzdem recht unterschiedlich.Python bietet im Gegensatz zu Lua nicht nur eine Datenstruktur, sondern mehrere furunterschiedliche Anwendungen. Genauso verhalt es sich auch mit anderen Konzepten.Wo Lua eine Flexible und leicht annpassbare Moglichkeit bietet, gibt es bei Pythonunterschiedliche, spezialisierte Moglichkeiten. Das lasst sich vor allem in der Große derbeiden Programme erkennen. Warend der Source Code von Lua kleiner als ein Megabyteist, umfasst der von Python mehr als 60 Megabyte. Außerdem wirkt es sich auf die Art derNutzbarkeit aus, in Python gibt es fur viele Anwendungsszenarios Standardbibliotheken,in Lua gibt es so etwas nicht. Also muss man in Lua haufiger benotigte Bibliothekenselbst schreiben, die dann meistens auf ein spezielles Problem angepasst sind, was dieWiederverwendbarkeit des Codes verringert. [8]

5.2. Fazit

Zusammenfassend kann man sagen, dass Lua eine leicht einsetzbare Sprache, mit einfacherweiterbaren Konstrukten ist. Sie bietet Moglichkeiten in Projekten jeglicher Großegenutzt werden zu konnen. Im Vergleich zu anderen Sprachen steht immer die Fragedanach im Vordergrund, ob eine einfache leicht erweiterbare Sprache, oder eine großeSprache die etliche Erweiterungen bereits mitbringt, fur das Projekt die richtige Wahlist. In einigen Bereichen, wie in der Spielebranche, geht diese Entscheidung oft zugunstenvon Lua aus. Jedoch fuhrt sie im Allgemeinen ein Schattendasein neben den großerenbekannten Skriptsprachen. Und das wird vermutlich auch weiterhin so bleiben. Jedochhat Lua auch weitere Bereiche in denen sie uberzeugen kann. Durch die geringe Großeund hohe Portabilitat kann Lua sehr gut auf Geraten im Embeded Bereich eingesetztwerden, die nicht uber Standard-Hardware und nahezu unbegrenzte Ressourcen verfugen.Auch in der Einfachheit und Ausfuhrungsgeschwindigkeit hat Lua Vorteile gegenuberkomplexeren Sprachen.

20

Page 23: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

A. Einfuhrung in die Syntax von Lua

Innerhalb des Beispielcodes sind Kommentare, wie in Lua ublich, mit -- gekennzeichnet.Mit --> sind die Ausgaben der Programmzeile gemeint.Das Klassische Hello World Beispiel ist in Lua sehr schnell abgehandelt. Die Ausgabevon Hello World auf der Standardausgabe erfolgt durch diese Anweisung:

print("Hello World")

Variablennamen durfen aus Buchstaben, Ziffern und Unterstrichen bestehen, wobei daserste Zeichen keine Ziffer sein darf. Außerdem sind folgenden Namen reserviert:

and break do else elseif end

false for function goto if in

local nil not or repeat return

then true until while

Lua ist Case sensitiv, also sind die Variablen var und Var nicht indentisch. Zuweisun-gen werden mit dem = Operator durchgefuhrt. In Lua sind auch Mehrfachzuweisungenmoglich, außerdem konnen Funktionen mehrere Ruckgabewerte haben.

a = 1

a, b = 1, 2 -- a = 1 und b = 2

a, b = b, a -- tauschen der Werte von a und b

a, b = 1 -- a = 1 und b uninitalisiert

a, b = 1, 2, 3 -- a = 1, b = 2 und die 3 geht verloren

-- Funktion mit mehreren Ruckgabewerten, a = 3 und b = 4

a, b = (function () return 3, 4 end)()

Eine Funktion wird erstellt durch den Funktionskonstruktor. Die erstellte Funktion wirdvon diesem zuruckgegeben. Es ist auch moglich, Funktionen so zu definieren, wie manes aus anderen Sprachen wie Java oder C gewohnt ist.

function() end -- einfacher Funktionskonstruktor

add1 = function(value) -- normale Funktionsdefinition

return value + 1

end

function add1(value) -- aquavalent zur vorherigen Definition

return value + 1

end

Fur Tabellen und Strings gibt es ebenfalls Konstruktoren:

21

Page 24: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

A. Einfuhrung in die Syntax von Lua

t = {} -- leere Tabelle

s = "" -- leerer String

Auf den Inhalt von Strings kann man nur mit entsprechenden Funktionen zugreifen, einbyteweiser Zugriff, wie in C ist nicht moglich. Auf Tabellen kann man so zugreifen, wieman es aus anderen Sprachen von Arrays gewohnt ist. Als Index sind alle Variablentypen,abgesehen von nil erlaubt. Ist der Index ein String, der den oben genannten Kriterienvon Variablennamen entspricht, kann auf ihn auch per Punktnotation zugegriffen werden.

t[1] = 12; print(t[1]) --> 12

t["elem"] = "e"

print(t["elem"]) --> e

print(t.elem) --> e

Es gibt vier verschiedene Kotrollstrukturen. Die if then else Abfrage funktioniert folgen-dermaßen:

if a > b then r = 1

elseif a < b then r = -1

else r = 0

end

Dabei sind Angaben von elseif und else optional. Eine while Schleife sieht so aus:

while c do

c = checksomething()

end

Dabei muss in Lua bei den Bedingungen darauf geachtet werden, dass nur false undnil zum logischen Falsch ausgewertet werden. Alles andere, also auch 0 und der leereString, werden zu wahr ausgewertet. Die repeat until Schleife funktioniert fast analogzur while Schleife, jedoch lauft sie, solange die Abbruchbedingung zu falsch ausgewertetwird.

repeat

c = checksomething()

until c

Es gibt außerdem noch die for Schleife, diese kann man auf zwei verschiedene Artennutzen. Einerseits numerisch, also mit einer Zahlervariablen, die von einem Startwert biszu einem Abbruchwert um eine bestimmte Schrittlange hochgezahlt wird. Andererseitsgenerisch mit einer Zahlfunktion, die durch alle Elemente einer Liste durchiteriert.

for i = -10, 10, 2 do -- numerisches for mit Schrittweite 2

print(i, ",") --> -10 , -8 , -6 , ... , 8 , 10 ,

end

t = {1 = "a", elem = 20}for k, v in pairs(t) do -- generisches for

print(k, "=", v, ",") --> 1 = a , elem = 20 ,

end

22

Page 25: New Lua 5 - AG Programmiersprachen und Übersetzerbau · 2013. 2. 22. · Lua ersetzte nach ihrer Entwicklung vorerst zwei andere Programmiersprachen die an der PUC genutzt wurden.

Literaturverzeichnis

[1] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes, “The evolution of lua,” in Procee-dings of the third ACM SIGPLAN conference on History of programming languages,HOPL III, (New York, NY, USA), pp. 2–1–2–26, ACM, 2007.

[2] R. Ierusalimschy, L. H. de Figueiredo, and W. Celes, “The implementation of lua5.0,” vol. 11, pp. 1159–1176, jul 2005. http://www.jucs.org/jucs_11_7/the_

implementation_of_lua.

[3] J. Quigley, “A look at lua,” Linux J., vol. 2007, no. 158, 2007.

[4] M. DeLoura, “The engine survey: General results.” http://www.satori.org/2009/

03/the-engine-survey-general-results/, 2009.

[5] R. Ierusalimschy, Programming in Lua, Third Edition. Lua.Org, 2013.

[6] A. Gostev, “The flame: Questions and answers.” http://www.securelist.com/en/

blog/208193522/The_Flame_Questions_and_Answers, 2012.

[7] Lua.org, “Lua 5.2 reference manual.” http://www.lua.org/manual/5.2/, 2012.

[8] lua users.org, “Lua versus python.” http://lua-users.org/wiki/

LuaVersusPython.

23