একটি ব্লক-কোড জেনারেটর হল একটি ফাংশন যা একটি ব্লকের জন্য কোড তৈরি করে এবং এটি একটি স্ট্রিং হিসাবে ফেরত দেয়। একটি ব্লক কি কোড তৈরি করে তার ধরনের উপর নির্ভর করে:
- মান ব্লক একটি আউটপুট সংযোগ আছে. এই ব্লকগুলি একটি পাঠ্য-ভিত্তিক ভাষায় অভিব্যক্তির মতো কাজ করে এবং অভিব্যক্তি ধারণ করে এমন স্ট্রিং তৈরি করে।
- বিবৃতি ব্লক একটি আউটপুট সংযোগ ছাড়া ব্লক. এই ব্লকগুলি একটি পাঠ্য-ভিত্তিক ভাষায় বিবৃতির মতো কাজ করে এবং বিবৃতি ধারণ করে এমন স্ট্রিং তৈরি করে।
কিভাবে একটি ব্লক-কোড জেনারেটর লিখতে হয়
আপনার তৈরি করা প্রতিটি কাস্টম ব্লকের জন্য, আপনি সমর্থন করতে চান এমন প্রতিটি ভাষার জন্য আপনাকে একটি ব্লক-কোড জেনারেটর লিখতে হবে। মনে রাখবেন যে সমস্ত ব্লক-কোড জেনারেটর জাভাস্ক্রিপ্টে লেখা হয়, এমনকি যদি তারা অন্য ভাষায় কোড তৈরি করে।
সমস্ত ব্লক-কোড জেনারেটর নিম্নলিখিত পদক্ষেপগুলি সম্পাদন করে:
- একটি ভাষা কোড জেনারেটর আমদানি করুন.
- প্রতিটি ক্ষেত্রের মান পান এবং এটিকে একটি কোড স্ট্রিংয়ে রূপান্তর করুন।
- অভ্যন্তরীণ ব্লক দ্বারা তৈরি কোড স্ট্রিংগুলি পান, যা মান এবং বিবৃতি ইনপুটগুলির সাথে সংযুক্ত ব্লক।
- ব্লকের কোড স্ট্রিং তৈরি করুন এবং ফেরত দিন।
উদাহরণ ব্লক
উদাহরণ হিসাবে, আমরা নিম্নলিখিত ব্লকগুলির জন্য জাভাস্ক্রিপ্ট কোড জেনারেটর লিখব।
custom_compare
হল একটি ভ্যালু ব্লক যাতেLEFT
নামে একটি মান ইনপুট,OPERATOR
নামে একটি ড্রপডাউন ক্ষেত্র এবংRIGHT
নামে একটি সংখ্যাসূচক ক্ষেত্র রয়েছে। এটি'0 = 0'
ফর্মের একটি এক্সপ্রেশন স্ট্রিং তৈরি করে।custom_if
হল একটি বিবৃতি ব্লক যাতেNOT
নামে একটি চেকবক্স ক্ষেত্র রয়েছে,CONDITION
নামে একটি মান ইনপুট এবংTHEN
নামে একটি বিবৃতি ইনপুট রয়েছে। এটি'if (...) {\n...\n};\n'
ফর্মের একটি বিবৃতি স্ট্রিং তৈরি করে।
এই নথিটি ধাপে ধাপে জেনারেটর তৈরি করে। আপনি এই নথির শেষে সম্পূর্ণ জেনারেটরগুলি খুঁজে পেতে পারেন।
মনে রাখবেন যে এই ব্লকগুলি শুধুমাত্র কোড জেনারেশন চিত্রিত করার উদ্দেশ্যে করা হয়েছে। একটি বাস্তব অ্যাপ্লিকেশনে, অন্তর্নির্মিত logic_compare
এবং controls_if
ব্লক ব্যবহার করুন।
একটি ভাষা কোড জেনারেটর আমদানি করুন
আপনি নিম্নলিখিত পদ্ধতিগুলির মধ্যে একটি ব্যবহার করে একটি ভাষা কোড জেনারেটর আমদানি করতে পারেন৷ forBlock
অবজেক্টে ব্লক-কোড জেনারেটর সংরক্ষণ করতে আমদানি করা জেনারেটর ব্যবহার করুন।
মডিউল
import {javascriptGenerator} from 'blockly/javascript';
import {pythonGenerator} from 'blockly/python';
import {phpGenerator} from 'blockly/php';
import {luaGenerator} from 'blockly/lua';
import {dartGenerator} from 'blockly/dart';
// Add block-code generators for the custom_if block.
javascriptGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
pythonGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
phpGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
luaGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
dartGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
আনপিকেজি
ব্লকলি অন্তর্ভুক্ত করার পরে আপনাকে অবশ্যই জেনারেটর অন্তর্ভুক্ত করতে হবে।
<script src="https://unpkg.com/blockly"></script>
<script src="https://unpkg.com/blockly/javascript_compressed"></script>
<script src="https://unpkg.com/blockly/python_compressed"></script>
<script src="https://unpkg.com/blockly/php_compressed"></script>
<script src="https://unpkg.com/blockly/lua_compressed"></script>
<script src="https://unpkg.com/blockly/dart_compressed"></script>
// Add block-code generators for the custom_if block.
javascript.javascriptGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
python.pythonGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
php.phpGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
lua.luaGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
dart.dartGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
স্থানীয় স্ক্রিপ্ট
ব্লকলি অন্তর্ভুক্ত করার পরে আপনাকে অবশ্যই জেনারেটর অন্তর্ভুক্ত করতে হবে।
<script src="blockly_compressed.js"></script>
<script src="javascript_compressed.js"></script>
<script src="python_compressed.js"></script>
<script src="php_compressed.js"></script>
<script src="lua_compressed.js"></script>
<script src="dart_compressed.js"></script>
// Add block-code generators for the custom_if block.
javascript.javascriptGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
python.pythonGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
php.phpGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
lua.luaGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
dart.dartGenerator.forBlock['custom_if'] = function (block, generator) { /* ... */ };
ক্ষেত্রের মান পান
ক্ষেত্রগুলি ব্যবহারকারীদের স্ট্রিং, সংখ্যা এবং রঙের মতো মান প্রবেশ করতে দেয়। একটি ক্ষেত্রের মান পেতে, getFieldValue
কল করুন। যা ফেরত দেওয়া হয় তা মাঠ ভেদে ভিন্ন। উদাহরণস্বরূপ, পাঠ্য ক্ষেত্রগুলি ব্যবহারকারীর দ্বারা প্রবেশ করা সঠিক পাঠ্য প্রদান করে, কিন্তু ড্রপডাউন ক্ষেত্রগুলি ব্যবহারকারীর নির্বাচিত আইটেমের সাথে যুক্ত একটি ভাষা-নিরপেক্ষ স্ট্রিং প্রদান করে। আরও তথ্যের জন্য, অন্তর্নির্মিত ক্ষেত্রগুলির জন্য ডকুমেন্টেশন দেখুন।
ক্ষেত্রের উপর নির্ভর করে, কোডে এটি ব্যবহার করার আগে আপনাকে প্রত্যাবর্তিত মানটিকে রূপান্তর করতে হতে পারে।
custom_compare
javascriptGenerator.forBlock['custom_compare'] = function (block, generator) {
// Use the value of the OPERATOR dropdown to look up the actual operator.
const OPERATORS = {
EQUALS: '==',
LESS: '<',
GREATER: '>',
};
const operator = OPERATORS[block.getFieldValue('OPERATOR')];
// The value of the RIGHT field is a number and can be used directly when
// building the block's code string.
const right = block.getFieldValue('RIGHT');
...
}
custom_if
javascriptGenerator.forBlock['custom_if'] = function (block, generator) {
// Use the value of the NOT field to get the negation operator (if any).
const checkbox = block.getFieldValue('NOT');
const negate = checkbox === 'TRUE' ? '!' : '';
...
}
আরও তথ্যের জন্য, রূপান্তর ক্ষেত্রের মান দেখুন।
ভিতরের ব্লক থেকে কোড পান
অভ্যন্তরীণ ব্লক হল ব্লকের মান এবং বিবৃতি ইনপুটগুলির সাথে সংযুক্ত ব্লকগুলি। উদাহরণ স্বরূপ, custom_if
ব্লকে if কন্ডিশনের জন্য একটি মান অভ্যন্তরীণ ব্লক রয়েছে এবং শর্তটি সত্য হলে কার্যকর করা কোডের জন্য বিবৃতি ভিতরের ব্লক রয়েছে।
ক্ষেত্রের মানগুলির বিপরীতে, অভ্যন্তরীণ ব্লকগুলি থেকে আপনি যে কোডটি পান তা যাওয়ার জন্য প্রস্তুত এবং রূপান্তরিত করার প্রয়োজন নেই৷
অভ্যন্তরীণ মান ব্লক
মান ইনপুটের সাথে সংযুক্ত একটি অভ্যন্তরীণ ব্লক থেকে কোড পেতে, valueToCode
এ কল করুন। এই পদ্ধতিটি ভিতরের ব্লকের কোড জেনারেটরকে কল করে।
custom_compare
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['custom_compare'] = function (block, generator) {
...
const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL;
const left = generator.valueToCode(block, 'LEFT', order);
...
}
custom_if
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['custom_if'] = function (block, generator) {
...
const order = checkbox === 'TRUE' ? Order.LOGICAL_NOT : Order.NONE;
const condition = generator.valueToCode(block, 'CONDITION', order) || 'false';
...
}
যখন আপনি valueToCode
কল করেন, তখন আপনাকে এটিকে আপনার কোডের সবচেয়ে শক্তিশালী অপারেটর সম্পর্কে বলতে হবে যা ভিতরের ব্লকের কোডে প্রযোজ্য হবে। এটি valueToCode
অভ্যন্তরীণ ব্লকের কোড বন্ধনীতে মোড়ানো প্রয়োজন কিনা তা নির্ধারণ করতে দেয়।
উদাহরণস্বরূপ, custom_if
এ NOT
বক্স চেক করা শর্তে একটি লজিক্যাল নট অপারেটর ( !
) প্রয়োগ করে। এই ক্ষেত্রে, আপনি নট অপারেটরের অগ্রাধিকারকে ( Order.LOGICAL_NOT
) valueToCode
পাস করেন এবং valueToCode
এটিকে ভিতরের ব্লকের দুর্বলতম অপারেটরের অগ্রাধিকারের সাথে তুলনা করে। এটি তারপর প্রয়োজন অনুযায়ী অভ্যন্তরীণ ব্লকের কোডটি মোড়ানো হয়:
- যদি
CONDITION
একটি পরিবর্তনশীল ব্লক হয়, তাহলেvalueToCode
বন্ধনী যোগ করে না কারণ নট অপারেটরটি একটি ভেরিয়েবল (!myBoolean
) এ সরাসরি প্রয়োগ করা যেতে পারে। - যদি
CONDITION
একটি তুলনামূলক ব্লক হয়, তাহলেvalueToCode
বন্ধনী যুক্ত করে যাতে নট অপারেটরটি বাম-হাতের মানের (!(a < b)
) পরিবর্তে সমগ্র তুলনা (!a < b
) ) তে প্রযোজ্য হয়।
আপনার আসলে জানার দরকার নেই যে valueToCode
বন্ধনী যুক্ত করেছে কিনা। আপনাকে যা করতে হবে তা হল valueToCode
অগ্রাধিকার পাস করা এবং আপনার কোড স্ট্রিংয়ে প্রত্যাবর্তিত কোডটি যোগ করা। আরও তথ্যের জন্য, valueToCode অগ্রাধিকার দেখুন।
অভ্যন্তরীণ বিবৃতি ব্লক
একটি বিবৃতি ইনপুটের সাথে সংযুক্ত একটি অভ্যন্তরীণ ব্লক থেকে কোড পেতে, statementToCode
এ কল করুন। এই পদ্ধতিটি ভিতরের ব্লকের কোড জেনারেটরকে কল করে এবং ইন্ডেন্টিং কোড পরিচালনা করে।
custom_compare
custom_compare
ব্লকে কোনো বিবৃতি ইনপুট নেই।
custom_if
javascriptGenerator.forBlock['custom_if'] = function (block, generator) {
...
const statements = generator.statementToCode(block, 'THEN');
...
}
একটি স্টেটমেন্ট ইনপুটের সাথে সরাসরি সংযুক্ত অভ্যন্তরীণ ব্লকের জন্য আপনাকে শুধুমাত্র statementToCode
কল করতে হবে। statementToCode
প্রথম ব্লকের সাথে সংযুক্ত যেকোনো অতিরিক্ত ব্লক পরিচালনা করে।
আপনার কোড স্ট্রিং তৈরি করুন এবং ফেরত দিন
আপনি ক্ষেত্র এবং অভ্যন্তরীণ ব্লকের জন্য কোড পাওয়ার পরে, আপনার ব্লকের জন্য কোড স্ট্রিং তৈরি করুন এবং ফেরত দিন। আপনি ঠিক কি ফেরত দেন তা আপনার ব্লকের প্রকারের উপর নির্ভর করে:
মান ব্লক: কোড স্ট্রিং এবং আপনার কোডে সবচেয়ে দুর্বল অপারেটরের অগ্রাধিকার ধারণকারী একটি অ্যারে ফেরত দিন।
valueToCode
এটি ব্যবহার করে সিদ্ধান্ত নিতে যে আপনার কোডটি বন্ধনীতে মোড়ানো প্রয়োজন কিনা যখন আপনার ব্লকটি একটি অভ্যন্তরীণ ব্লক হিসাবে ব্যবহৃত হয়। আরও তথ্যের জন্য, রিটার্ন অগ্রাধিকার দেখুন।স্টেটমেন্ট ব্লক: কোড স্ট্রিং রিটার্ন করুন।
custom_compare
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['custom_compare'] = function (block, generator) {
...
const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL;
...
const code = left + ' ' + operator + ' ' + right;
return [code, order];
}
custom_if
javascriptGenerator.forBlock['custom_if'] = function (block, generator) {
...
const code = 'if (' + negate + condition + ') {\n' + statements + '}\n';
return code;
}
আপনি যদি আপনার কোড স্ট্রিংয়ে একটি অভ্যন্তরীণ মানের ব্লকের কোড একাধিকবার ব্যবহার করেন, তাহলে সূক্ষ্ম বাগ এবং অবাঞ্ছিত পার্শ্বপ্রতিক্রিয়া এড়াতে আপনার সেই ব্লক থেকে কোডটি ক্যাশে করা উচিত।
সম্পূর্ণ কোড জেনারেটর
রেফারেন্সের জন্য, এখানে প্রতিটি ব্লকের জন্য সম্পূর্ণ কোড জেনারেটর রয়েছে:
custom_compare
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['custom_compare'] = function (block, generator) {
const OPERATORS = {
EQUALS: '==',
LESS: '<',
GREATER: '>',
};
const operator = OPERATORS[block.getFieldValue('OPERATOR')];
const order = operator === '==' ? Order.EQUALITY : Order.RELATIONAL;
const left = generator.valueToCode(block, 'LEFT', order);
const right = block.getFieldValue('RIGHT');
const code = left + ' ' + operator + ' ' + right;
return [code, order];
}
custom_if
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['custom_if'] = function (block, generator) {
const checkbox = block.getFieldValue('NOT');
const negate = checkbox === 'TRUE' ? '!' : '';
const order = checkbox === 'TRUE' ? Order.LOGICAL_NOT : Order.NONE;
const condition = generator.valueToCode(block, 'CONDITION', order) || 'false';
const statements = generator.statementToCode(block, 'THEN');
const code = 'if (' + negate + condition + ') {\n' + statements + '}\n';
return code;
}