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.
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.
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:
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
.
// 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.
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:
- Vous souhaitez vous assurer que le code est toujours entre parenthèses. Vous le transmettez donc à
valueToCode
. - Votre bloc n'inclut aucun opérateur. Vous le renvoyez donc à partir de votre générateur de code de bloc.
Order.NONE
est la priorité la plus faible. Il est utilisé dans les cas suivants:
- Vous voulez vous assurer que le code est toujours entre parenthèses. Vous le renvoyez donc à partir de votre générateur de code de bloc.
- Aucun opérateur n'agit sur un bloc interne. Vous le transmettez donc à
valueToCode
.