ブロックは括弧を意味します。たとえば、次のブロックを見ると、5
と 2
は 1 つのブロックの一部であり、-
は別のブロックの一部であるため、-5 + 2
ではなく -(5 + 2)
を意味すると想定されます。
ただし、すべてのブロックにかっこを付けると、コードの可読性が大幅に低下します。(((5) * (2)) + (3))
と 5 * 2 + 3
を比較します。どちらの式も同じ値(13
)に評価されますが、2 つ目の式のほうが読みやすくなります。
Blockly の演算子の優先度ルールを使用すると、最小限のかっこを使用してコードを生成できるため、読みやすさが最大限に高まります。
「正しい」出力を生成する
生成されたコードを人間が読み取れるようにする必要がない場合は、かっこを最小限に抑える必要はありません。すべてのブロックをラップすることは有効なアプローチであり、生成されたコードが常に正しく評価されるようにします。
正確性を確保するため、valueToCode
呼び出しには常に Order.ATOMIC
を渡し、ブロックコード生成ツールからは常に Order.NONE
を返します。
最適なかっこを生成する
括弧は、括弧がないと生成されるコードが正しくない場合にのみ挿入する必要があります。これは、外側のブロック内の演算子の優先度が内側のブロック内の演算子の優先度よりも高い場合に発生します。
たとえば、次のブロックには単項否定演算子と加算演算子があります。単項否定は加算演算子よりも優先度が高くなります。
したがって、かっこを付けないと -5 + 2
になり、-
は +
の前に評価されるため、ブロックと一致しません。
演算子の優先度を指定して、括弧を挿入するタイミングを生成ツールに指示できます。外側のオペレーターが内側のオペレーターよりも強力であると判断した場合は、内側のオペレーターを保護するためにかっこが挿入されます。
valueToCode
は外側の演算子の優先度を受け取り、戻りタプルは内部演算子の優先度を指定します。
2 つの演算子を含むブロックの例を次に示します。
import {javascriptGenerator, Order} from 'blockly/javascript';
javascriptGenerator.forBlock['negate_plus_two'] = function(block, generator) {
// valueToCode takes in the precedence of the outer operator.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
// The return tuple specifies the precedence of the inner operator.
return [code, Order.ADDITION];
}
valueToCode の優先度
valueToCode
を呼び出して内部ブロックのコードを生成するときに、内部ブロックのコードに作用する最強演算子の優先度を渡します。これは、内部ブロックのコードが保護される必要がある演算子です。
たとえば、次のブロックでは、単項否定演算子と加算演算子の両方が内部ブロックのコードに対して作用します。単項否定の方が優先度が高いため、valueToCode
に渡す優先度は単項否定です。
// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
戻り値の優先度
ブロックコード生成ツールから優先度を返す場合は、ブロックのコード内の最も優先度の低い演算子の優先度を返します。これは保護が必要な演算子です。
たとえば、次のブロックには単項否定演算子と加算演算子の両方が含まれています。加算は弱いため、ブロックコード生成ツールから返す優先度は加算です。
const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];
注文の列挙型
すべての言語生成モジュールは、その言語のすべての優先度を含む Order
列挙型を定義します。
優先度が高いほどバッキング値が低く、優先度が低いほどバッキング値が高くなります。優先度が高いものは強さで「上位」にランクされ、優先度が低いものは「下位」にランクされると考えることができます。これは、競技の選手をランク付けする場合と同じです。
組み込みのすべての言語の Order
列挙型は、次の場所にあります。
特別な優先順位
ジェネレータの Order
列挙型の優先順位のほとんどは、それぞれのテキストベースの言語で定義されている優先順位と一致します。ただし、Order.ATOMIC
と Order.NONE
の 2 つの特別な優先順位があります。
Order.ATOMIC
は優先度が最も高い値です。次のような場合に使用します。
- コードが常にかっこで囲まれるようにするため、
valueToCode
に渡します。 - ブロックに演算子が含まれていないため、ブロックコード生成ツールからブロックを返します。
Order.NONE
は優先度が最も低い値です。次のような場合に使用します。
- コードが常にかっこで囲まれるようにするため、ブロックコード生成ツールからコードを返します。
- 内部ブロックに作用する演算子がないため、
valueToCode
に渡します。