Funktionen können in Ausdrücken aufgerufen werden (Funktionsapplikation)
In Funktionen können weitere Funktionen ausgeführt werden (Funktionskomposition)
Funktionen (Prozeduren) können als Anweisung ausgeführt werden
In Lua kann eine Funktion auch ohne Namen anonym als Wert definiert werden!
Funktionen geben Werte durch die return v Anweisung zurück
Programmierung in Lua
Definition 2.(Definition und Applikation von Funktionen)
Programmierung in Lua
Tabellen
In Lua gibt es keine Unterscheidung zwischen Arrays, Datenstrukturen, und Objekten!
Es gibt nur Tabellen die aus key-value Paaren bestehen (Schlüssel und Wert) → Hashtabellen
Auf einen Tabelleneintrag kann mittes der Schlüsselreferenzierung t.key zugegriffen werden (in Ausdrücken lesend oder in datenanweisungen schreibend)
Die Definition von Records und Arrays ist sehr ähnlich
Bei Arrays ist der Schlüssel aber ein automatisch erzeugter Index 1,2,3, .. → Erstes Element hat immer den Index 1! → Die Länge eines Arrays kann über die #array Operation ermittelt werden
Da Records und Arrays tatsächlich Hashtabellen sind, und der Schlüssel immer eine Zeichenkette ist (auch Index 1!), sind folgende Schreibweisen isomorph: t.key == t["key"]
Programmierung in Lua
Definition 3.(Definition und Applikation von Tabellen)
Programmierung in Lua
Anweisungen
Programmanweisungen in Lua:
Datenanweisung (Wertzuweisung an Variablen)
Bedingte Verzweigung
Prozeduraufruf
Schleifen
Definition 4.(Datenanweisung)
Bedingte Verzweigungen
Definition 5.(Bedingte Verzweigung)
Programmierung in Lua
Definition 6.(Mehrfachauswahl (Extension, kein Standard))
Programmierung in Lua
Programmierung in Lua
Schleifen
Definition 7.(Zählschleife)
Definition 8.(Bedingte Schleifen)
Programmierung in Lua
Programmierung in Lua
Turtle Grafik
Um das Programmieren zu erlernen ist eine grafische Visualisierung von Programmabläufen und deren Ausgabe sinnvoll um Programmierkonzepte zu erlernen
Die Grafik ist das Rechenergebnis!
Die Turtle Grafik hat einfache Befehle, die eine symbolische Schildkröte als Dreieck benutzt um auf einer zweidimensionalen Fläche zu zeichnen.
Das Dreieck hat eine Ausrichtung die in Grad angegeben ist [0,360]
Dabei kann die Position des Dreiecks absolut (posn) oder relativ (jump,move) verändert werden.
Die relativen Verschiebungen des Dreiecks werden in der aktuellen Richtung des Dreiecks ausgeführt
Die Ausrichtung des Dreiecks kann relativ durch turn verändert werden
Programmierung in Lua
Definition 9.(Turtle Grafik)
Beispiel 1.(Iteratives Zeichnen einer Blume)
require "turtle"
for i=1,12 do
for j=1,12 do
move(50)
turn(30)
end
turn(30)
wait(0.1)
end
Programmierung in Lua
Objekte und Klassen
Beben der reinen prozeduralen Programmierung mit Funktionen und Records (Tables) kann in Lua auch auf einfache Weise objektorientiert programmiert werden
Dabei werden Tabellen wieder verwendet um Objekte und Klassen zu implementieren
Jedoch ist die Unterstützung von Lua nur gering → Verwendung der class Bibliothek, die in der pervasives Bibliothek enthalten ist (wird von lvm direkt geladen)
Bei der Instanziierung von Objekten werden i.A. Daten des Objekts mit Parameterwerten initialisiert → Definition einer Initialisierungsfunktion erforderlich!
Ein Objekt kann sich selbst mit self referenzieren
Programmierung in Lua
Definition 10.(Definition von Klassen und Instanziierung von Objekten)
Programmierung in Lua
Ein Objekt einer Klasse kann sich selber über die Variable self referenzieren.
Neben dem Punktoperator, mit dem allgemein ein Attribut eines Objektes ausgewählt werden kann, kann der Doppelpunktoperator verwendet werden, um Methodenaufrufe automatisch mit der Selbstreferenz auszuführen.
Bei der Verwendung des Punktoperators muss als erstes Argument immer das Objekt selber übergeben werden.
c.m(c,v1,v2,..)
-- Analog kurze Schreibweise
c:m(v1,v2,..)
Eine neue leere Klasse mit der class Funktion erzeugen
c = class()
Programmierung in Lua
Eine Initialisierungsfunktion für diese Klasse definieren. Die Initialisierungsfunktion wird bei jedem instanziierten Objekt einmalig aufgerufen.
function c:init (p1,p2,..) .. end
Weitere Methoden der Klasse definieren:
function c:m (p1,p2,..) .. end
Objekete mit der new Methode erzeugen
local o = c:new(v1,v2,..)
LUAOS
Konzept
LUAOS: Lua Operating System
LUAOS wird auf einem Rechner (Netzwerkknoten) durch eine Lua VM ausgeführt (lvm)
LUAOS bietet einen WEB basierten Zugriff auf Rechnerknoten
Skriptausführung über eine Shell mit Monitoring
LUAOS:
Ausführung von Skripten in einem Sandkasten
Scheduling und Multithreading
Einfache Sensor und Geräte API
Konzept
Ein Skript wird in einem eigenen gekapselten Thread ausgeführt (mit jeweils eigenen Ausführungszustand und VM)
Ein Skript kann weitere Fibers erzeugen
Ein Skript hat einem maximale durchgehende Laufzeit von einer Sekunde (danach wird das Skript abgebrochen)
Die Ausführung muss daher durch blockierende IO, der yield, oder der sleep Funktionen unterbrochen werden
WEB Interface
Das LUAOS ist über ein WEB Interface erreichbar
LUAOS Architektur
LUVM Architektur
Die LUAOS VM (LUVM) besteht aus:
LUA Parser → Skripttext wird direkt in Bytecode Instruktionen übersetzt (kein Parserbaum und AST)
LUA Bytecode Interpreter (BC Loop ist in Assembler programmiert!)
LUA JIT Compiler der zur Laufzeit BC in nativen Maschinencode übersetzt
LUA-C API für native Erweiterungen
Automatisches Speichermanagement mit Garabage Collector (Nicht inkrementeller Mark & Sweep Algorithmus)
Asynchrone IO mit einer UV Loop (libuv, wird auch in node.js verwendet)
function fiber.create (function(args…), args…) → fiber
Erzeugt einen neuen leichtgewichtigen Prozess. Der Prozess ist sofort ausführungsbereit.
function fiber:join()
Der aufrufende Prozess wird blockiert bis der Subprozess terminiert ist
Skript API
HTTP
HTTP Server und Klienten
function http:new() → http
Erzeugt eine neue HTTP Instanz
function http:get(url, function (data,error))
Ausführung einer HTTP GET Anfrage. Das Ergebnis (Fehler oder Daten) wird durch eine asynchrone Rückruffunktion bearbeitet.
function http:put(url, data, function (data,error))
Ausführung einer HTTP OUT Anfrage. Das Ergebnis (Fehler oder Daten) wird durch eine asynchrone Rückruffunktion bearbeitet.
function http:service(ipport, function (url,address,params,body) → string)
Installation eines HTTP Service (IP Port ipport). Eingehende GET/PUT Anfragen werden durch eine Rückruffunktion bearbeitet. Das Ergebnis der Anfrage wird von dieser Funktion als Text zurück gegeben.
Skript API
HTML
Ein HTML Text Formattierer
function html:new() → html
Erzeugt eine neue HTML Formattierungssnstanz
function html:html(head:html string,body: html string) → string
Erzeugt den Rahmen einer HTML Seite
function html:head() → string
Erzeugt den Kopf einer HTML Seite
function html:body(html string table) → string
Erzeugt den Inhalt einer HTML Seite
function html:table(head table, body table table) → string
Weitere Funktionen: h1, h2, h3, ol, ul, li, dl, dt, dd
Skript API
Timer
Intervalltimer die in Fibers und Skripten benutzt werden können um periodisch Tasks auszuführen
function timer:new() → timer
Erzeugt einen neuen Timer.
function timer:start(interval:number,period:number)
Startet den Timer mit dem angegebenen Intervall und der Periodenzeit (oder 0). Nach Ablauf des Intervalls wird ein Ereignis signalisiert, auf welches mit der await Operation gewartet werden kann.
function timer:stop()
Stoppt den Timer. Es werden keine weiteren Ereignisse mehr signalisiert.
function timer:wait()
Auf ein Timerereignis warten. Der aufrufende Prozess wird blockiert.
Skript API
Sensor
Zugriff auf und Implementierung von Sensoren
function sensor:all() → table
Gibt eine Liste alle verfügbaren Sensoren zurück (Liste der Namen)
function sensor:new(sensorclass:string,…) → sensor
Erzeugt eine neue Sensorinstanz vom Typ sensorclass. Mögliche Klassen sind: “temperature”, “cpu”.
function sensor:read() → number|string|table|nil
Gibt den aktuellen Sensorwert zurück.
function sensor:calibrate?(…)
Kalibriert den Sensor oder die Sensorfunktion.
Skript API
Actor
function actor:all() → table
Gibt eine Liste alle verfügbaren Aktuatoren zurück (Liste der Namen)
function actor:new(actorclass:string,…) → actor
Erzeugt eine neue Aktuatorinstanz vom Typ actorclass. Mögliche Klassen sind: “dotdisp”".
function actor:reset(…)
Setzt den Aktuator in einen definierten Anfangszustanf.
function actor:set(…)
Setzt eine Steuervariable mit einem neuen Aktuatorwert.
function actor:get?(string) → number|string|table|nil
Gibt den Wert einer Aktuatorvariable zurück.
function actor:control?(…)
Ausführung eines Steuerkommandos.
Skript API
Punktmatrix Ausgabegerät
8 rows and 8 cols LED matrix
Driven by HT16K33 chip
Access to I2C communication pins
Skript API
Beispiele
-- Actor DOTS Matrixlocal dot = actor:new('dots')
dot:reset()
-- dot:set(on,row,col)
dot:set(1,4,4)
sleep(1000)
dot:set(0,4,4)
-- Sensor CPU Temperatur
local s = sensor:new('temperature')
print(s:read())
Asynchrone Ereignisverarbeitung
Synchrone Verarbeitung
Die aufrufende Operation, z.B. das Lesen aus einer Datei, wird solange “blockiert”/wartet (genauer die Prozessausführung), bis das Ereignis eingetreten ist, d.h. im Beispiel die Daten gelesen wurde.
Eine synchrone Operation (Prozedur) gibt das Ergebnis der Operation direkt zurück
Asynchrone Verarbeitung
Die aufrufende Operation wartet nicht auf das Eintreten des Ereignisses (keine Blockierung), und der Prozesse fährt unmittelbar danach in der Ausführung folgender Operationen fort.
Jetzt wird eine Rückruffunktion verwendet, um beim Eintreten des Ereignisses die Daten (oder das Ereignis) verarbeiten zu können.
In JavaScript werden i.A. alle Ein- und Ausgabeoperation asynchron ausgeführt. In Lua gibt es eine ausgewogene Mischung, bzw. die synchrone Variante ist vorherrschend.
Die sleep Operation kann verwendet um den aktuellen Programmfluss für eine bestimmte Zeit (Millisekunden) anzuhalten
Beispiel 2.(Synchrone Verzögerung einer Serviceschleife)
Asynchrone Ereignisverarbeitung
Alternativ kann auch ein Timer erzeugt werden. Nach dem Start des Timers (mittels der start Methode und der Angabe des Zeitintervalls bis ein Timerereignis ausgelöst wird und dem Zeitintervall zwischen zwei Ereignissen) kann mittels der wait Methode der Prozessfluss angehalten werden bis ein Timerereignis eintritt
Beispiel 3.(Synchrone Verzögerung einer Serviceschleife mit einem Timer)
Asynchrone Ereignisverarbeitung
Beispiel 4.(Periodische asynchrone Ausführung einer Serviceschleife)
Beispiel 5.(Asynchrone Implementierung eines HTTP WEB Servers)
Asynchrone Ereignisverarbeitung
Aufgabe
Was ist der Nachteil bei der Verwendung eines Timers mit explizitem Warten auf das Ereignis im Vergleich zur sleep Operation oder der asynchronen Ausführung mittels setInterval?
Was sind Vorteile und Nachteile der synchronen gegenüber der asynchronen Ereignis- und Datenverarbeitung?