Ajouter des 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 même bloc, tandis que - en fait partie d'un autre.

blocs représentant -(5 + 2)

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

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

Générer une sortie "correcte"

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

Pour vous assurer de la validité, 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 extérieur est plus forte que celle d'un opérateur dans le bloc intérieur.

Par exemple, dans les blocs suivants, il existe 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.

negate-and-addition

Par conséquent, si vous n'ajoutez pas de parenthèses, vous obtenez -5 + 2, et - est évalué avant +, ce 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 prend en compte la priorité de l'opérateur externe, et la tuple de retour spécifie la priorité de l'opérateur interne.

Voici un exemple de bloc incluant deux opérateurs:

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é de 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 fort 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.

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é des retours

Lorsque vous renvoyez une priorité à partir de votre générateur de code de bloc, renvoyez la priorité de l'opérateur le plus faible dans le code du bloc. Il s'agit de l'opérateur qui doit être protégé.

Par exemple, le bloc suivant contient à la fois un opérateur de négation unaire et un opérateur d'addition. L'addition 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, sans bloc enfant

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

Énumération des commandes

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

Les préséances plus fortes ont des valeurs de sauvegarde plus faibles, et les préséances plus faibles ont des valeurs de sauvegarde plus élevées. Vous pouvez considérer que les préséances fortes sont "classées plus haut" en termes de force, et que les préséances plus faibles sont "classées plus bas", comme s'il s'agissait de combattants compétitifs.

Vous trouverez ici les énumérations Order pour toutes les langues intégrées:

Priorités spéciales

La plupart des priorités des énumérations Order des générateurs correspondent aux priorités définies par leurs langues textuelles respectives. Toutefois, il existe deux priorités spéciales, Order.ATOMIC et Order.NONE.

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

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