यदि () का आलसी मूल्यांकन कैसे लागू किया जाए


10

मैं वर्तमान में निम्नलिखित के आधार पर एक अभिव्यक्ति मूल्यांकक (एकल पंक्ति अभिव्यक्ति, जैसे सूत्र) लागू कर रहा हूं:

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

मेरा मूल्यांकनकर्ता अच्छी तरह से काम कर रहा है, लेकिन मुझे अभी भी याद नहीं है if()और मैं सोच रहा हूं कि कैसे आगे बढ़ना है।

मेरे शंटिंग-यार्ड के बाद उपसर्ग और स्टैक आधारित मूल्यांकन के साथ, यदि मैं if()एक और फ़ंक्शन को सच्चे और झूठे भागों के साथ जोड़ता हूं, तो एक एकल if(true, msgbox("ok"), msgbox("not ok"))दोनों संदेश दिखाएगा जबकि मैं केवल एक दिखाना चाहूंगा। ऐसा इसलिए है क्योंकि जब मुझे किसी फ़ंक्शन का मूल्यांकन करने की आवश्यकता होती है, तो इसके सभी तर्कों का पहले ही मूल्यांकन किया गया है और स्टैक पर रखा गया है।

क्या आप मुझे if()आलसी तरीके से लागू करने के लिए कोई रास्ता दे सकते हैं ?

हालांकि मैं इन्हें एक प्रकार के मैक्रो के रूप में संसाधित करने के बारे में हूं, लेकिन शुरुआती समय में मैंने अभी तक स्थिति मूल्यांकन नहीं किया है। शायद यह कि मुझे एक अलग तरह की संरचना का उपयोग करने के लिए एक कतार से अलग स्थिति और सही / गलत भाव रखने की आवश्यकता है? अभी के लिए मूल्यांकन से पहले अभिव्यक्ति को पार्स किया गया है, लेकिन मैं भविष्य के मूल्यांकन के लिए पूर्वनिर्धारित अभिव्यक्ति के रूप में मध्यवर्ती प्रतिनिधित्व को संग्रहीत करने की योजना भी बना रहा हूं।

संपादित करें : समस्या पर कुछ के बाद, मुझे लगता है कि मैं अपनी अभिव्यक्ति (एक रैखिक टोकन स्ट्रीम के बजाय एएसटी) का एक पेड़ प्रतिनिधित्व बना सकता हूं, जिससे मैं आसानी से अपनी एक या किसी अन्य शाखा को अनदेखा कर सकता हूं if()

जवाबों:


9

यहां दो विकल्प हैं।

1) ifएक समारोह के रूप में लागू नहीं है। विशेष शब्दार्थ के साथ इसे एक भाषा सुविधा बनाएं। करने में आसान, लेकिन कम "शुद्ध" यदि आप चाहते हैं कि सब कुछ एक फ़ंक्शन हो।

2) "कॉल बाय नाम" शब्दार्थ, जो बहुत अधिक जटिल है, लेकिन संकलक जादू को ifभाषा तत्व के बजाय एक फ़ंक्शन के रूप में रखते हुए आलसी मूल्यांकन समस्या की देखभाल करने की अनुमति देता है । यह इस प्रकार चलता है:

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


मुझे यकीन नहीं है, लेकिन "बंद" "ठग" होना चाहिए? हम्म, शायद नहीं; बस विकिपीडिया पृष्ठ पर देखा गया: "एक ठग एक पैरामीटर रहित बंद है"।

जब आप कहते हैं "कॉल बाय नेम" क्या आप विश्व स्तर पर संदर्भित कर रहे हैं? वैकल्पिक रूप से ग्लोबल कॉल-बाय-नाम बस एक क्लोजर प्रकार को लागू कर रहा है, तो यदि फ़ंक्शन सिर्फ 3 क्लोजर लेता है और दो (स्थिति और फिर या फिर) का मूल्यांकन करता है, लेकिन सभी चीजों को एक क्लोजर के रूप में मान्यता प्राप्त करने की आवश्यकता नहीं है जैसे कि पूर्ण कॉल-बाय- नाम शब्दार्थ
जिमी हॉफ

@ मैट: "थंक" शब्द का अर्थ प्रोग्रामिंग के संदर्भ में कई अन्य चीजें हो सकती हैं, और "पैरामीटरलेस क्लोजर" यह पहली बार नहीं है जब मैं इसे सुनता हूं। "बंद होना" बहुत अधिक असंदिग्ध है।
मेसन व्हीलर

1
@ जिमीहॉफ: जब मैं कहता हूं कि "नाम से पुकारें", तो मैं फ़ंक्शन तर्क को स्थापित करने की एक विशिष्ट शैली की बात कर रहा हूं, जो वैकल्पिक होनी चाहिए। बहुत सी मौजूदा भाषाओं की तरह आप एक पैरामीटर को मान या उप-संदर्भ पास करने के लिए चुन सकते हैं, इस परिदृश्य के लिए आपको उप-नाम पास करने के लिए विकल्प की आवश्यकता होती है।
मेसन व्हीलर

जबकि "नाम से पुकारें" शब्दार्थ के बारे में आपके सुझाव ने मुझे कुछ दिलचस्प बाते बताईं, यह मेरे मूल्यांकनकर्ता के लिए थोड़ा अधिक कठिन है जो कि पूर्ण संकलक नहीं है, क्योंकि मेरे फ़ंक्शन कॉल सिंगल-लाइन हैं (एमएस-एक्सेल फॉर्मूलों के बारे में सोचें)। मैं सोच रहा हूं कि कॉलिंग ट्री को हटाने के लिए स्टैक के छद्म मूल्यांकन करके टोकन की कतार के बाद मैं एक कदम जोड़ सकता हूं। पेड़ से शाखाओं को छोड़ने के लिए यह जानना आसान होना चाहिए।
सेकी

3

हस्ताक्षर वाले फ़ंक्शन के बजाय:

object if(bool, object, object)

इसे हस्ताक्षर दें:

object if(bool, object function(), object function())

फिर आपका ifफ़ंक्शन स्थिति के आधार पर उपयुक्त फ़ंक्शन को कॉल करेगा, केवल उनमें से एक का मूल्यांकन करेगा।


1

यह काफी आसान है, यदि आप सब कुछ आलसी रूप से संकलित करते हैं। आपके पास यह देखने के लिए कुछ साधन होने चाहिए कि क्या किसी मूल्य का पहले से ही मूल्यांकन किया गया है, या यदि उसे अधिक निकासी की आवश्यकता है।

फिर आप निम्न कार्य कर सकते हैं: यदि यह एक शाब्दिक या चर है (क्या आपके पास वे हैं ?, अर्थात कार्यों के नाम?), इसे स्टैक पर धकेलें। यदि यह किसी फ़ंक्शन का अनुप्रयोग है, तो इसे अलग से संकलित करें, और स्टैक पर प्रवेश बिंदु को धक्का दें।

एक कार्यक्रम का निष्पादन, तब तक केवल लूपिंग होता है जब तक कि स्टैक के शीर्ष का मूल्यांकन नहीं किया जाता है और फ़ंक्शन नहीं होता है। यदि इसका मूल्यांकन या कार्य नहीं किया जाता है, तो कोड को स्टैक पॉइंट के शीर्ष पर कॉल करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.