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.
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.
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:
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
.
// 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.
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:
- Vuoi verificare che il codice sia sempre racchiuso tra parentesi,
in modo da passarlo a
valueToCode
. - Il tuo blocco non include operatori, quindi lo restituisci dal generatore di codici a blocchi.
Order.NONE
è la precedenza più debole. Si utilizza quando:
- Vuoi assicurarti che il codice sia sempre racchiuso tra parentesi, in modo da restituirlo dal generatore di codici a blocchi.
- Non ci sono operatori che agiscono su un blocco interno, quindi lo passi a
valueToCode
.