Inserción de paréntesis

Los bloques implican paréntesis. Por ejemplo, cuando ves los siguientes bloques, supones que significa -(5 + 2) y no -5 + 2 porque 5 y 2 son parte de un bloque, y - es parte de otro.

bloques que representan -(5 + 2)

Sin embargo, si colocas paréntesis en cada bloque, el código será mucho menos legible. Compara (((5) * (2)) + (3)) con 5 * 2 + 3. Ambas expresiones se evalúan como algo (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 una máxima legibilidad.

Generar un resultado "correcto"

Si no necesitas que el código generado sea legible por humanos, no tienes que preocuparte por minimizar los paréntesis. Unir cada bloque es un enfoque adecuado y garantiza que el código generado siempre se evalúe de forma correcta.

Para garantizar la precisión, siempre pasa Order.ATOMIC a las llamadas valueToCode y muestra siempre Order.NONE desde tu generador de código de bloque.

Genera paréntesis óptimos

Los paréntesis solo deben insertarse 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 unario y un operador de adición. La negación unaria tiene mayor precedencia que el operador de adición.

nega y suma

Por lo tanto, si no agregas paréntesis, obtienes -5 + 2, y - se evalúa antes de +, que no coincide con los bloques.

Puedes indicarle al generador cuándo insertar paréntesis si le indicas la solidez de tus diferentes operadores. Si detecta que el operador externo es más fuerte que el interno, inserta paréntesis para proteger al operador interno.

valueToCode tiene prioridad del operador externo, y la tupla que se muestra especifica la prioridad del operador interno.

Este es un ejemplo de un bloque que incluye dos operadores:

Un bloque con un operador de negación unario, un operador de suma y un bloque secundario.

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 prioridad del operador más sólido que actúa sobre el código del bloque interno. Este es el operador del que se debe proteger el código del bloque interno.

Por ejemplo, en el siguiente bloque, el operador de negación unario 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 prioridad que debes pasar a valueToCode.

Un bloque con un operador de negación unario, un operador de suma y un bloque secundario.

// 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 muestres una prioridad desde el 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 necesita protección.

Por ejemplo, el siguiente bloque contiene un operador de negación unario y un operador de adición. La adición es más débil, por lo que es la prioridad que debes devolver del generador de código de bloque.

Un bloque con un operador de negación unario y un operador de suma, sin bloque secundario

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

Enumeración del pedido

Cada módulo generador de idiomas define una enumeración Order que incluye todas las prioridades de ese idioma.

Las precedencias más fuertes tienen valores de copia de seguridad más bajos y las más débiles tienen valores de copia de seguridad más altos. Puedes pensar en las precedencias fuertes como si tuvieran una “clasificación superior” en fuerza, y las precedencias más débiles como si fueran “clasificadas de baja”, como si fueran luchadores competitivos.

Aquí puedes encontrar las enumeraciones Order para todos los idiomas integrados:

Precedencias especiales

La mayoría de las prioridades de las enums Order de los generadores coinciden con las prioridades definidas por sus respectivos idiomas basados en texto. Sin embargo, hay dos precedentes especiales: Order.ATOMIC y Order.NONE.

Order.ATOMIC es la mayor prioridad. Se usa en los siguientes casos:

Order.NONE es la prioridad más baja. Se usa en los siguientes casos: