2009-10-24 16 views
5

Sto cercando di scrivere il mio giocattolo My Toy Language -> compilatore MSIL per avere una migliore comprensione di come funzionano i compilatori. Ho ottenuto l'analisi e il lexing funzionante, ho creato gli alberi delle espressioni e utilizzando l'API dell'albero delle espressioni System.Linq.Expressions, ho un interprete funzionante. Ora vorrei emettere alcuni veri assembly MSIL.Collegamento di un albero di espressioni .NET a un nuovo assieme

Il problema è che non riesco a capire come effettivamente costruire questi assembly. La classe MethodBuilder accetta solo corpi di metodo MSIL non elaborati, quindi devo ottenere il grezzo MSIL del mio albero di espressioni. Chiamando Expression.Compile() restituisce un delegato di lavoro ma non riesco a ottenere il suo MSIL sottostante. La chiamata a MethodInfo.GetMethodBody() genera un'eccezione InvalidOperationException poiché non è implementata in quella specifica classe figlio.

Come posso collegare il delegato a un nuovo assieme?

risposta

3

Appena trovato. La versione DLR di LambdaExpression espone un metodo CompileToMethod che fa esattamente ciò di cui ho bisogno.

lambdaExpression.CompileToMethod(myMethodBuilder); 
+0

Tenere presente che questo metodo presenta alcune limitazioni, ad esempio l'impossibilità di compilare metodi non statici. –

+0

@ 280Z28: Fortunatamente, My Toy Language non è orientato agli oggetti, quindi non sarà un problema. –

+0

Puoi spiegare come ottenere l'appropriato 'MethodBuilder' - Mi rendo conto che è stato tanto tempo fa :) –

0

Per emettere l'IL grezzo è necessario definire il proprio AST. È necessario ottenere AssemblyBuilder quindi ModuleBuilder e quindi è possibile definire il metodo a livello di modulo o ottenere nuovo TypeBuilder e ora MethodBuilder per definire il metodo a livello di classe.

Hai detto che hai già lexer e parser. questo significa che puoi costruire AST. Quindi basta camminare tra le espressioni analizzate ed emettere il tuo IL.

Anche se si ottiene codice generato da Compile, non sarà possibile eseguire operazioni utili poiché il codice generato dipende dall'infrastruttura. Ad esempio, se hai bisogno di compilare le chiusure, dovresti creare variabili lessicali lessicali o di classe e così via (come il trasferimento di controllo non lessicale che richiede l'uso di Eccezioni in .net)

+0

Sì, questo è quello che sto cercando di evitare. Il modello LINQ Expression Tree fa tutto questo per me, quindi mi piacerebbe usarlo invece di scrivere il mio emettitore MSIL. –

+0

ok, stai cercando di imparare la teoria del compilatore ma parser e lexer sono le parti minime del compilatore. Tutto il divertimento che abbiamo dentro AST e sezioni di ottimizzazione e in emitter di couse - solo cose che cerchi di evitare –

+0

C'è un libro davvero buono là fuori chiamato "Expert .NET 2.0 IL Assembler" di Serge Lidin, che ti darà una comprensione la struttura degli assiemi in MSIL. È molto facile da leggere se si comprendono i concetti di base dell'assemblatore. Vorrei anche suggerire di usare Mono.Cecil come libreria per emettere il tuo IL. Penso che troverai molto più facile lavorare con la libreria sotto lo spazio dei nomi Emit. Altrimenti, sono d'accordo con il poster di cui sopra. Se hai costruito l'AST, dovresti passare attraverso ogni affermazione ed emettere il tuo IL. –

Problemi correlati