Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Tilman Giese Holger Just Murat Knecht Mark Liebetrau

Ähnliche Präsentationen


Präsentation zum Thema: "Tilman Giese Holger Just Murat Knecht Mark Liebetrau"—  Präsentation transkript:

1 Tilman Giese Holger Just Murat Knecht Mark Liebetrau
Ruby-Compiler für .NET Tilman Giese Holger Just Murat Knecht Mark Liebetrau Ruby-Compiler für .NET | 12. Februar 2009

2 Übersicht Ruby-Compiler für .NET | 12. Februar 2009

3 Ruby Dynamische Sprachen Die Sprache Ruby
Ruby-Compiler für .NET | 12. Februar 2009

4 Dynamische vs. Statische Sprachen
dynamische Semantik: Typüberprüfung und Namensauflösung werden erst zur Laufzeit durchgeführt Laufzeitumgebung für alle dynamische Aspekte der Sprache enge Verzahnung von Laufzeitumgebung und Klassenbibliothek Für Ruby (aber auch andere Sprachen) gilt insbesondere: Klassendefinitionen sind nicht abgeschlossen, sondern zu jedem Zeitpunkt an jeder Stelle des Programms änderbar eval: dynamische Auswertung beliebigen Codes innerhalb eines beliebigen Kontextes Ruby-Compiler für .NET | 12. Februar 2009

5 Die Sprache Ruby Namensauflösung für Methoden und für Konstanten (= Modul- oder Klassennamen) erfolgt nach unterschiedlichen Prinzipien Methoden: Vererbungs- und Mixin-Hierarchie Konstanten: Hierarchie der lexikalischen Scopes Dynamische Scopes: Erst zur Laufzeit stehen Scopes fest class A; class B; end; end # innerer Scope: [A, A::B] class A::B; end # innerer Scope: [A::B] class A; class << self; end; end # innerer Scope: [A, #<Class:A>] def m(x, y); String; end class m(42, 9)::A; class << self; end; end # innerer Scope: [#<Class:String::A>] Ruby-Compiler für .NET | 12. Februar 2009

6 Ausschnitt: Klassenhierarchie
RubyBasicObject RubyObject RubyModule RubyNumeric RubyString RubyClass RubyInteger RubyFixnum Ruby-Compiler für .NET | 12. Februar 2009

7 Ruby-Konzepte  .NET-Konzepte (1)
Methodenaufruf Beispiel class RubyObject { public RubyObject Invoke(String method, RubyObject[] args, System.Ruby.Block blk); } Ruby: m(5, 6) # implizit: self.m(5, 6) C#: scope.Self().Invoke(″m″, new RubyObject[] { RubyFixnum.Get(5), RubyFixnum.Get(6) }, null ); Ruby-Compiler für .NET | 12. Februar 2009

8 Ruby-Konzepte  .NET-Konzepte (2)
Methodendefinitionen Ruby: class A; def my(a, b); end; end C#: namespace __ruby { class __methods_A_0 { [Ruby.Method("my")] public static RubyObject __my(RubyObject self, RubyObject[] args, Ruby.Block blk); public static Ruby.Scope scope__my_0; } C#: scope.DefineMethod("my", typeof(__ruby.__methods_A_0).GetMethod("__my_0")); Ruby-Compiler für .NET | 12. Februar 2009

9 Absurdes Klassendefinition gibt etwas zurück ... und zwar nicht die Klasse Lokale Variable verhalten sich ... anders Modul- und Klassendefinitionen class A; 5 + 5; end.to_f #=> 10.0 def m; 42; end puts m #=> 42 (Methodenaufruf) if 1 == 2 then m = 6; end puts m #=> nil (lokale Variable) ary = [ { ′4′ => Object } ] class ary.first[′4′]::MyClass; end Ruby-Compiler für .NET | 12. Februar 2009

10 Klassenbibliothek rudimentäre Klassenbibliothek selbst implementiert
einfach um neue Methoden und Klassen erweiterbar /* * call-seq: * fix == other */ [Ruby.Method("==")] public RubyObject eq(RubyObject arg) { if (this == arg) return RubyObject.__true; if (arg is RubyFixnum) return RubyObject.__false; // some stuff omitted return RubyObject.__false; } Ruby-Compiler für .NET | 12. Februar 2009

11 Plattform-Unabhängigkeit (1)
“An assembly is one of the fundamental programming units in Phoenix.” [PDOC] Ruby-Compiler für .NET | 12. Februar 2009

12 Plattform-Unabhängigkeit (2)
OpCode Phx.Common vs. Phx.Targets.Architectures.Msil High-level vs. Low-level „ In general it's best to use HIR opcodes if possible; you should only need to resort to the LIR opcodes for the ldfld/ldsfld cases that came up in the other thread.” [PF1] Wir benutzen MSIL für: ldsfld, ldstr, ldtoken, newobj Plattformunabhängigkeit von Phoenix? Ruby-Compiler für .NET | 12. Februar 2009

13 API-Unarten Hinzufügen einer Anweisung
Append(), Insert(), InsertAfter(), InsertBefore(), InsertBranchAndLabelAfter() Zugriff auf Zieloperand DestinationOperand: = DestinationOperand1 DestinationOperand2 … DestinationOperands: Unterstützt Iteratorkonzept (foreach) DestinationOperandList Nicht etwa eine Liste Erstes Element der Kette, nächstes mit Operand.Next Ruby-Compiler für .NET | 12. Februar 2009

14 Ausführung einer Ruby EXE
main(): [RubyCoreLibrary]Runtime::Run() Laufzeitumgebung initialisieren Typsystem (Object, Class, …) Wurzel der Scope-Hierarchie Eingebaute Funktionalität Kernel Modul (puts, require) File Klasse „Main() Methode“ von Ruby suchen und rufen C# Reflection: __main.Run() RubyExceptions abfangen und ausgeben Ruby-Compiler für .NET | 12. Februar 2009

15 Instruktionen (1) Ganz allgemein Ziel := Operator ( Operanden )
Operator := Instruction + OpCode Instruction: Technische Aufteilung der Operatoren ValueInstruction: Evaluation Stack / Register CallInstruction: Funktionsruf, d.h. Callstack DataInstruction: ? Ruby-Compiler für .NET | 12. Februar 2009

16 Operanden Verschiedene Typen Für SourceOperand und DestinationOperand
VariableOperand, MemoryOperand, ImmediateOperand, … Optimierung? Beispiel: ldstr „Kuchen“ -> call Console.WriteLine VariableOperand + TemporaryVariable -> 2 lokale Variablen VariableOperand + LocalVariable -> immerhin nur 1 Ruby-Compiler für .NET | 12. Februar 2009

17 Ein Resümee Motivation für Phoenix
HIR bietet Unabhängigkeit zu Zielplattform Backend austauschbar Abstraktions-Level sind nicht sauber getrennt Konsequenz ist nicht nur uneinheitliches Coding Die versprochene Plattform-Unabhängigkeit fehlt. Ruby-Compiler für .NET | 12. Februar 2009

18 Quellen Ruby-Compiler für .NET | 12. Februar 2009
[PDOC] Phoenix Documentation, Microsoft Phoenix SDK June 2008 [PF1] „Error load float32“, Phoenix Forum, US/phoenix/thread/b72a2f6d-c3bf-488b-b27a-6cc14b9006aa/ (zuletzt abgerufen am ) Ruby-Compiler für .NET | 12. Februar 2009

19 Dynamic Language Runtime
Erlaubt die Implementierung von dynamischen Sprachen auf Basis der .NET CLR „pluggable language backends“ unterschiedliche dynamische Sprachen wie Python oder Ruby können einfach in ein .NET-Programm „geladen“ werden Durch gemeinsames Typsystem ist Interaktion zwischen den Sprachen sowie der Host-Applikation möglich Mögliche Anwendungsfälle Verwendung von Bibliotheken dynamischer Sprachen in .NET Scripting von Applikationen

20 Features der DLR Generische Features aller dynamischen Sprachen werden von der DLR selbst implementiert Gemeinsames Typsystem Namensauflösung von Methoden und Variablen Schleifen, Verzweigungen, … Ausnahmebehandlung Basisoperatoren Methodenaufrufe Scopes Codeblöcke (für Funktionen, Methoden, Lambdas, …) Implementierte Sprachen parsen ihren Code und erzeugen einen AST aus DLR-Expressions

21 Implementierung Unabhängig von der Eingabesprache…
… wird (naiv) der gleiche AST generiert puts "Hello World" # Ruby print "Hello World" # Python MethodInfo writeline = typeof(Console).getMethod("WriteLine", Type.EmptyTypes); Statements.Add( Expression.Call( writeline, Expression.Constant("Hello World") ) );

22 Einbettung in den rubyc
Neuer Einstiegspunkt für den DLR Host: RubyLanguageContext Beschreibt Spracheigenschaften Diverse Einstiegspunkte für die DLR Aufrufen des Parsers und Generieren des generischen ASTs Unverändert zu „normalem“ Compiler Ablaufen des AST und Generieren des DLR-AST Der Ablaufstruktur des Compilers wird gefolgt Es werden Objekte, Scopes, Module und Klassen aus der Ruby-Standardbibliothek erzeugt und verwendet

23 Fazit DLR Vorhandene Infrastruktur des Compilers und der Standardbibliothek wird weiterverwendet Interoperabilität mit anderen DLR-Sprachen ist dadurch eingeschränkt „Echte“ DLR-Implementierung müsste Vieles erneut implementieren Insgesamt wesentlich weniger Implementierungsaufwand als bei Phoenix DEMO Hello World!


Herunterladen ppt "Tilman Giese Holger Just Murat Knecht Mark Liebetrau"

Ähnliche Präsentationen


Google-Anzeigen