2009-10-24 14 views
5

मैं अपने खिलौने माई खिलौना भाषा -> एमएसआईएल कंपाइलर लिखने की कोशिश कर रहा हूं ताकि संकलक कैसे काम कर सकें। मुझे पार्सिंग और लेक्सिंग काम मिल गया है, मैंने अभिव्यक्ति के पेड़ों का निर्माण किया है और सिस्टम का उपयोग कर लिया है। लिंक्स.एक्सप्रेस एक्सप्रेशन ट्री एपीआई, मेरे पास एक वर्किंग दुभाषिया है। अब मैं कुछ असली एमएसआईएल असेंबली उत्सर्जित करना चाहता हूं।एक नई असेंबली में एक .NET अभिव्यक्ति वृक्ष को जोड़ना

समस्या यह है कि, मैं यह नहीं समझ सकता कि वास्तव में इन विधानसभाओं को कैसे बनाया जाए। MethodBuilder कक्षा केवल कच्चे एमएसआईएल विधि निकायों को स्वीकार करती है, इसलिए मुझे अपने अभिव्यक्ति पेड़ का कच्चा एमएसआईएल प्राप्त करना होगा। कॉलिंग Expression.Compile() एक कार्यकारी प्रतिनिधि को लौटाता है लेकिन मैं इसके अंतर्निहित एमएसआईएल प्राप्त करने में सक्षम नहीं हूं। कॉलिंग MethodInfo.GetMethodBody() एक अवैधऑपरेशन अपवाद फेंकता है क्योंकि यह उस विशिष्ट बाल वर्ग में लागू नहीं किया गया है।

मैं उस प्रतिनिधि को एक नई असेंबली में कैसे जोड़ सकता हूं?

उत्तर

3

बस इसे मिला। LambdaExpression का DLR संस्करण एक CompileToMethod विधि का खुलासा करता है जो मुझे वही करता है जो मुझे चाहिए।

lambdaExpression.CompileToMethod(myMethodBuilder); 
+0

ध्यान रखें कि इस विधि में कुछ सीमाएं हैं, जैसे गैर स्थैतिक तरीकों को संकलित करने में असमर्थता। –

+0

@ 280Z28: सौभाग्य से, मेरी खिलौना भाषा ऑब्जेक्ट उन्मुख नहीं है, इसलिए यह कोई समस्या नहीं होगी। –

+0

क्या आप उचित 'विधिबिल्डर' को कैसे प्राप्त कर सकते हैं - मुझे एहसास है कि यह बहुत समय पहले था :) –

0

कच्चे आईएल को उत्सर्जित करने के लिए आपको अपनी खुद की एएसटी परिभाषित करने की आवश्यकता है। आपको असेंबलीबिल्डर को मॉड्यूलबिल्डर प्राप्त करने की आवश्यकता है और फिर आप मॉड्यूल-स्तरीय विधि को परिभाषित कर सकते हैं या क्लास-स्तरीय विधि को परिभाषित करने के लिए नया टाइपबिल्डर और अब विधिबिल्डर प्राप्त कर सकते हैं।

आपने कहा कि आपके पास पहले से ही लेक्सर और पार्सर है। इसका मतलब है कि आप एएसटी बनाने में सक्षम हैं। तो बस पार्स किए गए अभिव्यक्तियों के माध्यम से चलें और अपने आईएल को छोड़ दें।

भले ही आप जेनरेट (संकलन द्वारा) कोड प्राप्त करते हैं, तब भी आप इसके साथ कुछ उपयोगी नहीं कर पाएंगे क्योंकि जेनरेट कोड आधारभूत संरचना पर निर्भर करता है। उदाहरण के लिए यदि आपको क्लोजर को संकलित करने की आवश्यकता है तो आपको क्लास या अन्य स्टोर को लेक्सिकल वैरिएबल और इसी तरह बनाना चाहिए (जैसे गैर अक्षीय नियंत्रण स्थानांतरण जो .NET में अपवादों का उपयोग करने की आवश्यकता है)

+0

हाँ, यही वह है जिसे मैं टालने की कोशिश कर रहा हूं। LINQ अभिव्यक्ति वृक्ष मॉडल मेरे लिए यह सब करता है, इसलिए मैं अपने स्वयं के एमएसआईएल उत्सर्जक लिखने के बजाय इसका उपयोग करना चाहता हूं। –

+0

ठीक है, आप कंपाइलर सिद्धांत सीखने की कोशिश कर रहे हैं लेकिन पार्सर और लेक्सर कंपाइलर के कम से कम हिस्से हैं। हमारे पास एएसटी और ऑप्टिमाइज़ेशन सेक्शन और कैस के एमिटर में सभी मज़े हैं - केवल –

+0

से बचने के लिए आप जो चीजें आजमाते हैं, वहां सर्ज लिडिन द्वारा 'विशेषज्ञ .NET 2.0 IL Assembler' नामक एक बहुत अच्छी किताब है, जो आपको समझने के बारे में समझ देगी एमएसआईएल में असेंबली की संरचना। जब तक आप मूल असेंबलर अवधारणाओं को समझते हैं तब तक पढ़ना बहुत आसान होता है। मैं आपके आईएल उत्सर्जित करने के लिए लाइब्रेरी के रूप में मोनो.सीसिल का उपयोग करने का भी सुझाव दूंगा। मुझे लगता है कि आपको एमिट नेमस्पेस के तहत लाइब्रेरी के साथ काम करना अधिक आसान लगेगा। अन्यथा, मैं उपर्युक्त पोस्टर से सहमत हूं। यदि आपके पास एएसटी बनाया गया है, तो आपको प्रत्येक कथन के माध्यम से चलना चाहिए और अपने आईएल को छोड़ देना चाहिए। –

संबंधित मुद्दे