Insertion de parenthèses

Les blocs impliquent des parenthèses. Par exemple, lorsque vous voyez les blocs suivants, vous supposez qu'il s'agit de -(5 + 2) et non de -5 + 2, car 5 et 2 font partie d'un seul bloc, et - fait partie d'un autre bloc.

blocs représentant -(5 + 2)

Toutefois, si vous placez des parenthèses autour de chaque bloc, le code sera beaucoup moins lisible. Comparez (((5) * (2)) + (3)) avec 5 * 2 + 3. Ces deux expressions renvoient à la même chose (13), mais la deuxième est beaucoup plus facile à lire.

Les règles de priorité des opérateurs de Blockly vous aident à générer du code avec le nombre minimal de parenthèses, pour une lisibilité optimale.

Générer une sortie "correcte"

Si vous n'avez pas besoin que le code généré soit lisible par l'humain, il n'est pas nécessaire de réduire les parenthèses. Encapsuler chaque bloc est une bonne approche, et garantit que votre code généré est toujours évalué correctement.

Pour garantir l'exactitude, transmettez toujours Order.ATOMIC aux appels valueToCode et renvoyez toujours Order.NONE à partir de votre générateur de code de bloc.

Générer des parenthèses optimales

Les parenthèses ne doivent être insérées que si le code généré est incorrect sans elles. Cela se produit lorsque la priorité d'un opérateur dans le bloc externe est plus importante que celle d'un opérateur dans le bloc interne.

Par exemple, dans les blocs suivants, il y a un opérateur de négation unaire et un opérateur d'addition. La négation unaire a une priorité plus élevée que l'opérateur d'addition.

exclure-et-ajouter

Ainsi, si vous n'ajoutez pas de parenthèses, vous obtenez -5 + 2, et - est évalué avant +, qui ne correspond pas aux blocs.

Vous pouvez indiquer au générateur quand insérer des parenthèses en lui indiquant la force de vos différents opérateurs. S'il constate que l'opérateur externe est plus fort que l'opérateur interne, il insère des parenthèses pour protéger l'opérateur interne.

valueToCode prévaut sur l'opérateur externe et le tuple de retour spécifie la priorité de l'opérateur interne.

Voici un exemple de bloc qui comprend deux opérateurs:

Un bloc avec un opérateur de négation unaire, un opérateur d'addition et un bloc enfant.

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];
}

Priorité valueToCode

Lorsque vous appelez valueToCode pour générer le code d'un bloc interne, vous lui transmettez la priorité de l'opérateur le plus puissant agissant sur le code du bloc interne. Il s'agit de l'opérateur contre lequel le code du bloc interne doit être protégé.

Par exemple, dans les blocs suivants, l'opérateur de négation unaire et l'opérateur d'addition agissent sur le code du bloc interne. La négation unaire est plus forte. C'est donc la priorité que vous devez transmettre à valueToCode.

Un bloc avec un opérateur de négation unaire, un opérateur d'addition et un bloc enfant.

// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;

Priorité de retour

Lorsque vous renvoyez une priorité depuis votre générateur de code en bloc, renvoyez la priorité de l'opérateur le plus faible dans le code du bloc. C'est l'opérateur à protéger.

Par exemple, le bloc suivant contient à la fois un opérateur de négation unaire et un opérateur d'addition. L'ajout est plus faible, c'est donc la priorité que vous devez renvoyer à partir du générateur de code de bloc.

Bloc avec un opérateur de négation unaire et un opérateur d'addition, et aucun bloc enfant

const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];

Énumération dans l'ordre

Chaque module de générateur de langage définit une énumération Order qui inclut toutes les priorités de ce langage.

Les priorités plus élevées ont des valeurs de support inférieures, et les priorités plus faibles ont des valeurs de support plus élevées. On peut considérer que les priorités fortes sont "classées plus haut" en force, et les priorités plus faibles comme un "classement inférieur", comme s'il s'agissait de combattants de compétition.

Voici où vous pouvez trouver les énumérations Order pour toutes les langues intégrées:

Priorités spéciales

La plupart des priorités dans les énumérations Order des générateurs correspondent à celles définies par leurs langues textuelles respectives. Toutefois, il existe deux précédents spéciaux : Order.ATOMIC et Order.NONE.

Order.ATOMIC est la priorité la plus élevée. Elle est utilisée dans les cas suivants:

Order.NONE est la priorité la plus faible. Elle est utilisée dans les cas suivants: