2009-10-24 13 views
5

Próbuję napisać własną zabawkę Mój język zabawki -> kompilator MSIL, aby lepiej zrozumieć działanie kompilatorów. Mam do czynienia z analizą i leksem, zbudowałem drzewa ekspresji i używając API drzewa wyrażeń System.Linq.Expressions, mam działającego interpretera. Teraz chciałbym wyemitować niektóre prawdziwe zestawy MSIL.Łączenie drzewa wyrażenia .NET w nowy zespół

Problem polega na tym, że nie mogę wymyślić, jak faktycznie zbudować te zespoły. Klasa MethodBuilder akceptuje tylko surowe bryły metod MSIL, więc muszę uzyskać surowy MSIL mojego drzewa wyrażeń. Wywołanie Expression.Compile() zwraca delegowanego delegata, ale nie jestem w stanie uzyskać jego bazowego MSIL. Wywołanie MethodInfo.GetMethodBody() zgłasza wyjątek InvalidOperationException, ponieważ nie jest zaimplementowany w tej konkretnej klasie podrzędnej.

Jak mogę połączyć tego delegata z nowym zestawem?

Odpowiedz

3

Po prostu go znalazłem. Wersja DLR LambdaExpression udostępnia metodę CompileToMethod, która wykonuje dokładnie to, czego potrzebuję.

lambdaExpression.CompileToMethod(myMethodBuilder); 
+0

Należy pamiętać, że ta metoda ma pewne ograniczenia, takie jak niezdolność do kompilacji metod niestatycznych. –

+0

@ 280Z28: Na szczęście język My Toy Language nie jest zorientowany obiektowo, więc nie będzie problemu. –

+0

Czy możesz wyjaśnić, jak uzyskać odpowiedni "MethodBuilder" - zdaję sobie sprawę, że to było dawno temu :) –

0

W celu emisji surowego IL należy zdefiniować własną AST. Musisz pobrać AssemblyBuilder, a następnie ModuleBuilder, a następnie możesz zdefiniować metodę na poziomie modułu lub uzyskać nowy TypeBuilder, a teraz MethodBuilder, aby zdefiniować metodę na poziomie klasy.

Powiedziałeś, że masz już lexer i parser. to oznacza, że ​​jesteś w stanie zbudować AST. Po prostu przejrzyj analizowane wyrażenia i wyślij swoją IL.

Nawet jeśli otrzymasz kod generowany (przez kompilację), nie będziesz w stanie zrobić z nim nic użytecznego, ponieważ wygenerowany kod zależy od infrastruktury. Na przykład, jeśli potrzebujesz skompilować zamknięcia, powinieneś utworzyć klasę lub inny magazyn dla zmiennych leksykalnych i tak dalej (jak nie leksykalny transfer kontrolny, który wymaga użycia Wyjątków w .net)

+0

Tak właśnie staram się unikać. Model drzewa wyrażeń LINQ robi to wszystko dla mnie, więc chciałbym go użyć zamiast pisać własnego emulatora MSIL. –

+0

ok, próbujesz nauczyć się teorii kompilatora, ale parser i lexer to najmniejsza część kompilatora. Cała zabawa, którą mamy w sekcjach AST i optymalizacji oraz emiterach - tylko rzeczy, których starasz się unikać –

+0

Istnieje naprawdę dobra książka o nazwie "Expert .NET 2.0 IL Asembler" autorstwa Serge Lidin, która da ci zrozumienie struktura złożeń w MSIL. Jest bardzo łatwy do odczytania, o ile rozumiesz podstawowe pojęcia asemblera. Sugerowałbym również użycie Mono.Cecil jako biblioteki do Emitowania twojej IL. Myślę, że łatwiej będzie ci wtedy pracować niż w bibliotece w przestrzeni nazw Emit. W przeciwnym razie zgadzam się z powyższym plakatem. Jeśli masz zbudowany AST, powinieneś przechodzić przez każde stwierdzenie i emitować swoją IL. –

Powiązane problemy