Lua (Skriptsprache)
Inhaltsverzeichnis
Was ist Lua?
Definition
Lua (Bezeichnung aus dem Portugiesischen; lua bedeutet Mond) ist eine leichtgewichtige Multi-Paradigma-Programmiersprache, die hauptsächlich für eingebettete Anwendungen konzipiert ist. Lua ist plattformübergreifend, da der Dolmetscher in ANSI C geschrieben ist und eine relativ einfache C-API hat.
Die Skriptsprache Lua wurde ursprünglich 1993 als eine Sprache entwickelt, mit der Softwareanwendungen erweitert werden können, um den steigenden Bedarf an kundenspezifischer Anpassung zu erfüllen. Es stellte die grundlegenden Funktionen der meisten prozeduralen Programmiersprachen bereit, aber kompliziertere oder domänenspezifische Funktionen wurden nicht aufgenommen. Stattdessen wurden Mechanismen zur Spracherweiterung eingeführt, mit denen Programmierer solche Funktionen implementieren können.
Da Lua als allgemein einbettbare Erweiterungssprache gedacht war, konzentrierten sich die Designer von Lua darauf, Geschwindigkeit, Tragbarkeit, Erweiterbarkeit und Benutzerfreundlichkeit in der Entwicklung zu verbessern.
Geschichte
Lua wurde im Jahr 1993 von Roberto Ierusalimschy, Luiz Henrique de Figueiredo und Waldemar Celes, alle Mitglieder der Computer Graphics Technology Group (Tecgraf) an der Päpstlichen Katholischen Universität von Rio de Janeiro (Brasilien), gegründet.
Von 1977 bis 1992 verfolgte Brasilien starke Handelshemmnisse (sog. Marktreserve) für Computer-Hardware und -software. In dieser Atmosphäre konnten sich die Kunden von Tecgraf weder politisch noch finanziell leisten, kundenspezifische Software aus dem Ausland zu verkaufen. Diese Gründe führten dazu, dass Tecgraf die grundlegenden Tools und Werkzeuge implementierte, die er von Grund auf benötigte.
Die Vorgänger waren die Datenbeschreibungs-/Konfigurationssprachen SOL (Simple Object Language) und DEL (Dateneingabesprache). Sie wurden 1992 bis 1993 bei Tecgraf unabhängig voneinander entwickelt, um zwei verschiedenen Projekten Flexibilität zu verleihen (beide waren interaktive grafische Programme für technische Anwendungen bei Petrobras). In SOL und DEL mangelte es an Flusskontrollstrukturen und Petrobras empfand ein wachsendes Bedürfnis, ihnen volle Programmierkraft zu geben.
In Die Evolution von Lua schrieben die Autoren:
Der einzige und wirkliche Konkurrent war im Jahr 1993 Tcl, das explizit für die Einbettung in Anwendungen konzipiert wurde. Tcl hatte jedoch eine unbekannte Syntax, bot keine gute Unterstützung für die Datenbeschreibung und lief nur auf Unix-Plattformen. Wir haben LISP oder Scheme wegen ihrer unfreundlichen Syntax nicht berücksichtigt. Python steckte noch in den Kinderschuhen. In der freien Do-it-yourself-Atmosphäre, die damals in Tecgraf herrschte, war es selbstverständlich, dass wir versuchen sollten, eine eigene Skriptsprache zu entwickeln. Da viele potenzielle Benutzer der Sprache keine professionellen Programmierer waren, sollte die Sprache kryptisch sein. Die Implementierung der neuen Sprache sollte äußerst portabel sein, da die Kunden von Tecgraf über eine sehr vielfältige Sammlung von Computerplattformen verfügten. Da wir erwarteten, dass andere Tecgraf-Produkte auch eine Skriptsprache einbetten müssen, sollte die neue Sprache dem Beispiel von SOL folgen und als Bibliothek mit einer C-API bereitgestellt werden.
Die Version Lua 1.0 wurde so entworfen, dass die Objekt-Entwickler, die sich dann leicht vom aktuellen Licht- und flexiblen Stil unterscheiden, die Syntax der Datenbeschreibung von SOL enthalten (daher auch der Name SOL = “Sonne” aus dem Portugiesischen). Die Lua-Syntax für Kontrollstrukturen wurde größtenteils von Modula entlehnt, hatte jedoch auch Einfluss von CLU (Mehrfachzuweisungen und Mehrfachrückgaben von Funktionsaufrufen als einfachere Alternative zu Referenzparametern oder expliziten Zeigern), C ++, SNOBOL und AWK (assoziative Arrays).
In einem in Dr. Dobbs Journal veröffentlichten Artikel geben die Urheber von Lua an, dass LISP und Scheme mit ihrem einzigen, allgegenwärtigen Datenstrukturmechanismus (der Liste) einen wesentlichen Einfluss auf ihre Entscheidung hatten, die Tabelle als primäre Datenstruktur von Lua zu entwickeln.
Die Semantik wurde im Laufe der Zeit zunehmend von Scheme beeinflusst, insbesondere durch die Einführung anonymer Funktionen und das vollständige lexikalische Scoping. In neuen Versionen wurden mehrere Funktionen hinzugefügt.
Die Versionen vor der Version 5.0 wurden unter einer der BSD-Lizenz ähnlichen Lizenz veröffentlicht. Ab Version 5.0 wurde unter MIT-Lizenz lizenziert. Es handelt sich bei beiden um freie Softwarelizenzen und sind nahezu identisch.
Eigenschaften
Lua wird im Allgemeinen als sogenannte “Multi-Paradigma-Sprache” bezeichnet und bietet einen kleinen Satz allgemeiner Funktionen, die für verschiedene Problemtypen erweitert werden können. Es enthält keine explizite Unterstützung für die Vererbung, ermöglicht jedoch die Implementierung mit Metatabellen. In ähnlicher Weise ermöglicht Lua den Programmierern die Implementierung von Namespaces,
Klassen und anderen verwandten Funktionen mithilfe der Implementierung einer einzelnen Tabelle. Erstklassige Funktionen ermöglichen den Einsatz vieler Techniken aus der funktionalen Programmierung und der vollständige lexikalische Geltungsbereich ermöglicht es, dass feinkörnige Informationen versteckt werden, um das Prinzip des geringsten Privilegs durchzusetzen.
Im Allgemeinen bemüht sich Lua darum, einfache und flexible Meta-Features bereitzustellen, die nach Bedarf erweitert werden können, anstatt ein Feature-Set bereitzustellen, das für ein Programmierparadigma spezifisch ist. Infolgedessen ist die Basissprache leicht (der vollständige Referenz-Interpreter ist nur etwa 247 kB kompiliert) und lässt sich leicht an ein breites Anwendungsspektrum anpassen.
Lua ist zudem eine dynamisch typisierte Sprache, die als Erweiterungs- und Skriptsprache gedacht ist und kompakt genug ist, um auf eine Vielzahl von Host-Plattformen zu passen. Es unterstützt nur eine kleine Anzahl atomarer Datenstrukturen, wie z. B. boolesche Werte, Zahlen (Gleitkomma mit doppelter Genauigkeit und standardmäßig 64-Bit-Ganzzahlen) und Strings. Typische Datenstrukturen wie Arrays, Sets, Listen und Datensätze können mit der einzigen nativen Datenstruktur von Lua dargestellt werden, der Tabelle, die im Wesentlichen ein heterogenes assoziatives Array ist.
Es implementiert eine Reihe von erweiterten Funktionen wie erstklassige Funktionen, Garbage Collection, Closures, korrekte Tail Calls, Zwang (automatische Konvertierung zwischen String- und Zahlenwerten zur Laufzeit), Coroutines (kooperatives Multitasking) und dynamisches Laden von Modulen.
Syntax
Ein Kommentar in Lua beginnt mit einem doppelten Bindestrich und endet am Ende der Zeile, ähnlich wie bei Ada, Eiffel, Haskell, SQL und VHDL. Mehrzeilige Zeichenketten und Kommentare sind mit doppelten eckigen Klammern versehen.
Tabellen
Tabellen sind die wichtigsten Datenstrukturen (und der einzige eingebaute zusammengesetzte Datentyp) und die Grundlage aller vom Benutzer erstellten Typen. Sie sind konzeptionell ähnlich wie assoziative Arrays in PHP, Wörterbücher in Python und Hashes in Ruby oder Perl.
Eine Tabelle ist die Sammlung von Schlüssel- und Datenpaaren, bei denen die Daten per Schlüssel referenziert werden. Es handelt sich also um ein Hash-heterogenes assoziatives Array.
Tabellen werden mit der Konstruktions-Syntax {} erstellt. Sie werden immer als Referenz übergeben; ein Schlüssel (Index) kann ein beliebiger Wert sein, mit Ausnahme von “nil” und “NaN”, einschließlich Funktionen.
Häufig wird eine Tabelle als Struktur (oder Datensatz) verwendet, indem Strings als Schlüssel verwendet werden. Da diese Verwendung sehr häufig ist, bietet Lua eine spezielle Syntax für die Zugriffe auf solche Felder. Durch die Verwendung einer Tabelle zum Speichern verwandter Funktionen werden automatisch numerische Schlüssel zugewiesen, sodass sie als Array-Datentyp genutzt werden können. Der erste automatische Index ist 1 und nicht 0, wie in vielen anderen Programmiersprachen (obwohl ein expliziter Index von 0 zulässig ist). Eine numerische Taste 1 unterscheidet sich von einer Zeichenfolge “1”.
Die Länge einer Tabelle t ist als ein beliebiger ganzzahliger Index n definiert, sodass t [n] nicht gleich Null ist und t [n+1] gleich null ist. Wenn darüber hinaus t [1] Null ist, kann n Null sein. Für ein reguläres Array mit Nicht-Null-Werten von 1 bis zu einem gegebenen n ist seine Länge genau das n, der Index des letzten Wertes. Wenn das Array “Löcher” hat (d. h. Nullwerte zwischen anderen Nicht-Null-Werten), kann #t jeder der Indizes sein, die einem Nullwert direkt vorangehen (d. h., er kann jeden solchen Nullwert als Ende betrachten).
Implementierung
Lua-Programme werden nicht direkt aus der Text-Lua-Datei interpretiert, sondern in Bytecode kompiliert, der dann auf der virtuellen Lua-Maschine ausgeführt wird. Der Kompilierungsprozess ist normalerweise für den Benutzer unsichtbar und wird zur Laufzeit ausgeführt. Er kann jedoch offline ausgeführt werden, um die Ladeleistung zu erhöhen oder den Speicherbedarf der Host-Umgebung zu verringern, indem der Compiler weggelassen wird. Lua-Bytecode kann auch mithilfe der dump-Funktion aus der String-Bibliothek und den Funktionen “load/loadstring/loadfile” erstellt und ausgeführt werden. Die Version 5.3.4 ist in ungefähr 24.000 Zeilen C-Code implementiert.
Wie bei den meisten CPUs und im Gegensatz zu den meisten virtuellen Maschinen (die auf Stapeln basieren) ist die VM auf Registerbasis und ähnelt daher einem tatsächlichen Hardwaredesign. Die Registerarchitektur vermeidet sowohl das übermäßige Kopieren von Werten als auch die Anzahl der Anweisungen pro Funktion. Die virtuelle Maschine von Lua 5 ist eine der ersten rezeptbasierten reinen VMs, die weit verbreitet ist.
Sie haben noch Fragen?