Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

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

Ähnliche Präsentationen


Präsentation zum Thema: "Ruby-Compiler für.NET Tilman Giese Holger Just Murat Knecht Mark Liebetrau Ruby-Compiler für.NET | 12. Februar 2009."—  Präsentation transkript:

1 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, # ] def m(x, y); String; end class m(42, 9)::A; class << self; end; end # innerer Scope: [# ] Ruby-Compiler für.NET | 12. Februar 2009

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

7 Ruby-Konzepte.NET-Konzepte (1) Methodenaufruf Beispiel Ruby: m(5, 6) # implizit: self.m(5, 6) class RubyObject { public RubyObject Invoke(String method, RubyObject[] args, System.Ruby.Block blk); } 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) Ruby-Compiler für.NET | 12. Februar 2009 An assembly is one of the fundamental programming units in Phoenix. [PDOC]

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() RubyException s 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 [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 )http://social.msdn.microsoft.com/Forums/en- US/phoenix/thread/b72a2f6d-c3bf-488b-b27a-6cc14b9006aa/ 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 MethodInfo writeline = typeof(Console).getMethod("WriteLine", Type.EmptyTypes); Statements.Add( Expression.Call( writeline, Expression.Constant("Hello World") ) ); puts "Hello World" # Ruby print "Hello World" # Python

22 Einbettung in den rubyc Neuer Einstiegspunkt für den DLR Host: RubyLanguageContext Beschreibt Spracheigenschaften Diverse Einstiegspunkte für die DLR 1.Aufrufen des Parsers und Generieren des generischen ASTs Unverändert zu normalem Compiler 2.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 "Ruby-Compiler für.NET Tilman Giese Holger Just Murat Knecht Mark Liebetrau Ruby-Compiler für.NET | 12. Februar 2009."

Ähnliche Präsentationen


Google-Anzeigen