Inserimento delle parentesi

I blocchi implicano le parentesi. Ad esempio, quando vedi i seguenti blocchi, supponiamo che significhi -(5 + 2) e non -5 + 2 perché 5 e 2 fanno parte di un blocco, mentre - fa parte di un altro.

blocchi che rappresentano -(5 + 2)

Ma se metti parentesi intorno a ogni blocco, il codice diventa molto meno leggibile. Confronta (((5) * (2)) + (3)) con 5 * 2 + 3. Entrambe queste espressioni restituiscono lo stesso valore (13), ma la seconda è molto più facile da leggere.

Le regole di precedenza degli operatori di Blockly consentono di generare codice con il numero minimo di parentesi, per la massima leggibilità.

Genera un output "corretto"

Se non hai bisogno che il codice generato sia leggibile da una persona, non c'è bisogno di ridurre al minimo le parentesi. L'aggregazione di ogni blocco è un approccio corretto e garantisce che il codice generato venga sempre valutato correttamente.

Per garantire la correttezza, passa sempre le chiamate da Order.ATOMIC a valueToCode e restituisci sempre Order.NONE dal tuo generatore di codici a blocchi.

Genera parentesi ottimali

Le parentesi devono essere inserite solo se il codice generato è errato senza di esse. Questo accade quando la precedenza di un operatore nel blocco esterno è maggiore di quella di un operatore nel blocco interno.

Ad esempio, nei blocchi seguenti sono presenti un operatore di negazione unario e un operatore di addizione. La negazione unaria ha una precedenza maggiore rispetto all'operatore di aggiunta.

negazione-e-aggiunta

Quindi, se non aggiungi parentesi, ottieni -5 + 2 e - viene valutato prima di +, che non corrisponde ai blocchi.

Puoi indicare al generatore quando inserire le parentesi comunicando l'efficacia dei diversi operatori. Se vede che l'operatore esterno è più forte dell'operatore interno, inserisce parentesi per proteggere l'operatore interno.

valueToCode ha la precedenza dell'operatore esterno, mentre la tuple di ritorno specifica la precedenza dell'operatore interno.

Ecco un esempio di blocco che include due operatori:

Un blocco con un operatore di negazione unario, un operatore di aggiunta e un blocco secondario.

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

Precedenza valueToCode

Quando chiami valueToCode per generare il codice di un blocco interno, gli invii la precedenza dell'operatore più forte che agisce sul codice del blocco interno. Si tratta dell'operatore da cui deve essere protetto il codice del blocco interno.

Ad esempio, nei blocchi seguenti sia l'operatore di negazione unaria sia l'operatore di addizione agiscono sul codice del blocco interno. La negazione unaria è più forte, quindi questa è la precedenza che dovresti passare a valueToCode.

Un blocco con un operatore di negazione unario, un operatore di aggiunta e un blocco secondario.

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

Precedenza al reso

Quando restituisci la precedenza dal generatore di codici a blocchi, restituisci la precedenza dell'operatore più debole all'interno del codice del blocco. Questo è l'operatore che deve essere protetto.

Ad esempio, il blocco seguente contiene sia un operatore di negazione unario sia un operatore di addizione. L'aggiunta è più debole, quindi è la precedenza che dovresti restituire dal generatore di codici a blocchi.

Un blocco con un operatore di negazione unario e un operatore di aggiunta e nessun blocco
secondario

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

Enum dell'ordine

Ogni modulo del generatore di linguaggi definisce un'enumerazione Order che include tutte le precedenza per quella lingua.

Le precedenza più forti hanno valori di supporto più bassi, mentre quelle più deboli hanno valori di supporto più elevati. Le priorità forti possono essere considerate come "classificate più in alto" in termini di forza e quelle più deboli come "ranking più basso", come se fossero combattenti competitivi.

Ecco dove puoi trovare le enumerazioni Order per tutte le lingue integrate:

Priorità speciali

La maggior parte delle precedenza nelle enumerazioni Order dei generatori corrisponde a quelle definite dalle rispettive lingue basate su testo. Esistono però due precedenti speciali: Order.ATOMIC e Order.NONE.

Order.ATOMIC è la precedenza massima. Si utilizza quando:

Order.NONE è la precedenza più debole. Si utilizza quando: