Los bloques implican paréntesis. Por ejemplo, cuando ves los siguientes bloques, asumes que significa -(5 + 2)
, no -5 + 2
, porque 5
y 2
forman parte de un bloque, y -
forma parte de otro.
Sin embargo, si colocas paréntesis alrededor de cada bloque, el código se vuelve mucho menos leíble. Compara (((5) * (2)) + (3))
con 5 * 2 + 3
. Ambas expresiones se evalúan de la misma manera (13
), pero la segunda es mucho más fácil de leer.
Las reglas de precedencia del operador de Blockly te ayudan a generar código con la cantidad mínima de paréntesis para lograr la máxima legibilidad.
Genera un resultado "correcto"
Si no necesitas que el código generado sea legible por humanos, no te preocupes por minimizar los paréntesis. Unir todos los bloques es un buen enfoque y garantiza que el código generado siempre se evalúe correctamente.
Para garantizar la corrección, siempre pasa Order.ATOMIC
a las llamadas a valueToCode
y siempre muestra Order.NONE
desde tu generador de código de bloque.
Genera paréntesis óptimos
Los paréntesis solo se deben insertar si el código generado es incorrecto sin ellos. Esto sucede cuando la prioridad de un operador en el bloque externo es más fuerte que la prioridad de un operador en el bloque interno.
Por ejemplo, en los siguientes bloques, hay un operador de negación unaria y un operador de adición. La negación unaria tiene una prioridad más alta que el operador de adición.
Por lo tanto, si no agregas paréntesis, obtienes -5 + 2
, y -
se evalúa antes que +
, lo que no coincide con los bloques.
Puedes indicarle al generador cuándo insertar paréntesis diciéndole qué tan fuertes son tus diferentes operadores. Si ve que el operador externo es más fuerte que el operador interno, inserta paréntesis para protegerlo.
valueToCode
toma la prioridad del operador externo, y la tupla que se muestra especifica la prioridad del operador interno.
A continuación, se muestra un ejemplo de un bloque que incluye dos operadores:
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];
}
Prioridad de valueToCode
Cuando llamas a valueToCode
para generar el código de un bloque interno, le pasas la precedencia del operador más fuerte que actúa en el código del bloque interno. Este es el operador del que se debe proteger el código del bloque interno.
Por ejemplo, en los siguientes bloques, el operador de negación unaria y el operador de adición actúan sobre el código del bloque interno. La negación unaria es más fuerte, por lo que esa es la precedencia que debes pasar a valueToCode
.
// The - is the strongest operator acting on the inner code.
const innerCode = generator.valueToCode(block, 'INNER', Order.UNARY_NEGATION);
const code = `-${innerCode} + 2`;
Prioridad de devolución
Cuando devuelves una precedencia de tu generador de código de bloque, muestra la precedencia del operador más débil dentro del código del bloque. Este es el operador que se debe proteger.
Por ejemplo, el siguiente bloque contiene un operador de negación unaria y un operador de adición. La adición es más débil, por lo que esa es la prioridad que debes mostrar desde el generador de código de bloques.
const code = `-${innerCode} + 2`;
// The + is the weakest operator in the block.
return [code, Order.ADDITION];
Enum de orden
Cada módulo del generador de lenguaje define una enum Order
que incluye todas las prioridades de ese idioma.
Las precedencias más sólidas tienen valores de respaldo más bajos, y las más débiles tienen valores de respaldo más altos. Puedes pensar en las precedencias fuertes como “clasificadas más alto” en términos de fuerza y en las precedencias más débiles como “clasificadas más abajo”, como si fueran luchadores competitivos.
Aquí puedes encontrar las enums Order
para todos los idiomas integrados:
Prioridades especiales
La mayoría de las prioridades en las enums Order
de los generadores coinciden con las prioridades definidas por sus respectivos lenguajes basados en texto. Sin embargo, hay dos prioridades especiales, Order.ATOMIC
y Order.NONE
.
Order.ATOMIC
es la prioridad más alta. Se usa en los siguientes casos:
- Asegúrate de que el código siempre esté entre paréntesis para pasarlo a
valueToCode
. - Tu bloque no incluye ningún operador, por lo que lo devuelves desde tu generador de código de bloque.
Order.NONE
es la prioridad más débil. Se usa en los siguientes casos:
- Debes asegurarte de que el código siempre esté entre paréntesis para devolverlo desde tu generador de código de bloque.
- No hay operadores que actúen en un bloque interno, por lo que lo pasas a
valueToCode
.