Questa documentazione è anche disponibile in Aseba Studio nell'item di menu Help->Language. Quando si utilizzano parole tecniche, queste sono collegate ai corrispondenti articoli di Wikipedia, in Italiano dove disponibili, oppure in Inglese. Si consiglia di leggere prima la pagina relativa ai concetti di base di Aseba. Questa documentazione presenta il linguaggio com'è fino alla versione 1.1 di Aseba, per versioni successive leggere questa pagina.
Il linguaggio di Aseba assomiglia a quello di Matlab (un linguaggio comune di programmazione scientifica); questa somiglianza consente agli sviluppatori con una conoscenza precedente di qualche linguaggio di scripting di trovarsi velocemente a proprio agio con Aseba e quindi abbassare la curva di apprendimento. Semanticamente, è un semplice linguaggio di programmazione imperativo con un singolo tipo di dato (intero a 16 bit con segno ) e arrays. Questa semplicità consente agli sviluppatori di programmare comportamenti senza una precedente conoscenza di un sistema dei tipi, essendo gli interi il più naturale tipo di variabile e molto indicato per programmare robot basati su microcontrollori.
Commenti
I commenti consento di aggiungere nel codice delle informazioni testuali che vengono ignorate dal compilatore. I commenti sono molto utili per annotare il codice con informazioni comprensibili dall'essere umano o per disabilitare temporaneamente dei pezzi di codice.I commenti iniziano con # e termiano alla fine della linea.
Esempio:
# questo è un commento
var b # un altro commento
Sono anche possibili commenti su più linee. Essi iniziano con #* e terminano con *#.
Esempio:
#*
Questo è un commento
su più linee
*#
var b # semplice commento
Variabili
Le variabili si riferiscono sia singoli valori scalari o array di valori scalari. I valori sono compresi tra -32768 e 32767, che è l'intervallo di validità per gli interi a 16 bit con segno. Gli array possono essere dichiarati usando le solite parentesi quadre []; L'indice di un array parte da zero. E' necessario dichiarare tutte le variabili definite dall'utente all'inizio dello script Aseba prima di fare qualsiasi operazione.
Esempio:
var a
var c[10]
var b = 0
var d[3] = 2, 3, 4
Eventi
Aseba ha una architettura basata su eventi, cioè gli eventi possono scatenare l'esecuzione di codice in maniera asincrona.
Gli eventi possono essere esterni, per esempio eventi definiti dall'utente in arrivo da altrun altro nodo Aseba, o interni, per esempio emessi da un sensore che fornisca un dato aggiornato.
Il ricevimento di una notifica di un evento fa eseguire, se definito, il blocco di codice che inizia con la parola chiave onevent seguita dal nome dell'evento.Il codice in cima al programma è eseguito quando il programma è avviato o riavviato.
Il programma può anche emettere un evento utilizzando la parola chiave emit, seguita dal nome dell'evento e dagli argomenti dell'evento stesso (se previsti). Se viene fornita una variabile questa deve avere una dimensione corrispondente a quella specificata negli argomenti dell'evento che deve essere emesso. Gli eventi consentono al programma di causare l'esecuzione di codice su un altro nodo o di comunicare con un programma esterno.
Per consentire l'esecuzione del codice relativo ad un nuovo evento gli script non devono bloccarsi e non devono contenere iterazioni ad anello infinite. Per esempio nel contesto della robotica spesso si ricorre ad una iterazione ad anello infinita all'interno della quale vengono eseguite tutte le elaborazioni legate ai valori dei sensori. Nel linguaggio Aseba invece il codice viene eseguito se specificato per un dato evento.
Esempio:
var run = 0
onevent start
run = 1
onevent stop
run = 0
onevent ir_sensors
if run == 1 then
emit sensors_values proximity_sensors_values
end
Espressioni e assegnazioni
Le espressioni consentono di effettuare calcoli matematici e sono scritte usando la normale notazione matematica infissa. Le assegnazioni utilizzano la parola chiave = e assegnano il risultato del calcolo di una espressione ad una variabilie scalare, un elemento di un array. Aseba fornisce vari operatori. Fare riferimento alla tabella seguente per una breve descrizione e per conoscere la precedenza di ciascun operatore. Per eseguire le espressioni in un ordine diverso da quello stabilito dalla precedenza degli operatori si possono usare le parentesi.
Precedenza | Operatore | Descrizione | Associatività | Numero argomenti |
---|---|---|---|---|
1 | () | raggruppa in sottoespressioni | unaria | |
2 | * / | moltiplicazione e divisione | binaria | |
% | Modulo | binaria | ||
3 | + - | Addizione, sottrazione | binaria | |
4 | << >> | scorrimento a destra, scorrimento a sinistra | binaria | |
5 | | | Or binaria | associativa a sinistra | binaria |
6 | ^ | or esclusiva binaria (xor) | associativa a sinistra | binaria |
7 | & | AND binaria | associativa a sinstra | binaria |
8 | - | meno unario | unaria | |
9 | ~ | NOT binario | unaria | |
10 | abs | valore assoluto | unaria | |
11 | = | Assegnazione | binaria | |
|= ^= &= | Assegnazione con or, xor, and | binaria | ||
*= /= | Assegnazione con prodotto e quoziente | binaria | ||
%= | Assegnazione con modulo | binaria | ||
+= -= | Assegnazione con somma e differenza | binaria | ||
<<= >>= | Assegnazione by left / right shift | binaria | ||
++ -- | incremento e decremento | unaria |
La versione con assegnazione dell'operatore binario funziona applicando l'operatore ad una variabile e memorizzando il risultato nella variabile stessa. Per esempio A *= 2 è equivalente a scrivere A = A * 2. Queste forme abbreviate hanno lo scopo di rendere il codice più leggibile.
Esempio:
a = 1 + 1
# Result: a = 2
a *= 3
# Result: a = 6
a++
# Result: a = 7
b = b + d[0]
b = (a - 7) % 5
c[a] = d[a]
Condizioni
Aseba fornisce due tipi di condizionali: if e when. Questi consistono nella verifica di una condizione e in un blocco di codice. Il test consiste in un confronti opzionalmente raggruppati usando and (congiunzione logica), or (disgiunzione logica), e not (negazione logica) operatori e parentesi.
Un confronto è fatto da un operatore e due operandi, e può essere vero o falso. Gli operandi possono essere espressioni arbitrarie. La seguente tabella elenca gli operatori di confronto.
Operatore | Funzione di verità |
---|---|
== | vero se i due operandi sono uguali |
!= | vero se i due operandi sono differenti |
> | vero se il priomo operando è strettamente maggiore del secondo |
>= | vero se il primo operando è maggiore o uguale al secondo |
< | vero se il primo operando è strettamente minore del secondo |
<= | vero se il primo operando è minore o uguale al secondo |
Sia if che when eseguono differenti blocchi di codice a seconda se la condizione è vera o falsa; ma when esegue il blocco corrispondente a vero solo se l'ultima valutazione del codice era falsa e quella corrente è vera. Questo consente l'esecuzione del codice solo quando qualcosa cambia. Il condizionale if esegue un primo blocco di codice se la condizione è vera. Si può aggiungere un secondo blocco di codice da eseguire quando la condizione è falsa tramite la parola chiave else. E' possibile concatenare ulterioni condizionali if usando la parola chiave elseif.
Esempio:
if a - b > c[0] then
c[0] = a
elseif a > 0 then
b = a
else
b = 0
end
if a < 2 and a > 2 then
b = 1
else
b = 0
end
when a > b do
leds[0] = 1
end
Il blocco when viene eseguito solo quando a diventa maggiore di b.
Loops
Due costrutti consentono la creazione di iterazioni ad anello (loop) while e for.
Una iterazione ad anello con while esegue ripetutamente un blocco di codice fintanto che la condizione specificata sia vera. La condizione è della stessa forma di quella usata da if.
Esempio:
while i < 10 do
v = v + i * i
i = i + 1
end
Una iterazione ad anello con for consente ad una variabile di iterare su un intervallo di interi, con una dimensione del passo di incremento specificabile.
esempio:
for i in 1:10 do
v = v + i * i
end
for i in 30:1 step -3 do
v = v - i * i
end
Subroutine
Quando volete eseguire la stessa sequenza di codice in due o tre posti nel programma, è possibile scrivere il codice in comune in un sottoprogramma e quindi richiamare questo sottoprogramma da posti diversi. E' possibile definire un sottoprogramma usando la parola chiave sub seguita dal nome del sottoprogramma. Potete chiamare il sottoprogramma usando la parola chiave callsub, seguita dal nome del sottoprogramma. I sottoprogrammi devono essere definiti prima di essere chiamati. I sottoprogrammi non possono avere argomenti né essere recursivi recursive, cioè non possono richiamare se stessi né direttamente, nè indirettamente .
I sottoprogrammi possono accedere a qualsiasi variabile (in Aseba tutte le variabili sono globali).
Example:
var v = 0
sub toto
v = 1
onevent test
callsub toto
Direttiva Return
E' possibile uscire da una subroutine e sospendere l'esecuzione di uno script attivato da un evento con la direttiva return.
Esempio:
var v = 0
sub toto
if v == 0 then
return
end
v = 1
onevent test
callsub toto
return
v = 2
Funzioni native
Il linguaggio di script Aseba è stato progettato per essere semplice e consentire una rapida comprensione anche per sviluppatori inesperti e per realizzare la macchina virtuale efficientemente su un micro-controller. Per eseguire calcoli complessi o che fanno uso intenso di risorse, forniamo funzioni native realizzate in codice nativo per maggior efficienza.
Per esempio una funzione nativa è il modo naturale di realizzare un prodotto scalare.
Le funzioni native sono sicure poiché specificano e verificano la dimensione dei loro argomenti, che possono essere costanti, variabili, celle di array, costruttori di array ed espressioni. Nel caso di array, potete accedere all'intero array, un singolo elemento, o un sotto-insieme dell'array. Le funzioni native accettano i loro argomenti per reference e possono modificare il loro contenuto, ma non restituiscono alcun valore. Si possono richiamare le funzioni native per mezzo della parola chiave call.
Esempio:
var a[3] = 1, 2, 3
var b[3] = 2, 3, 4
var c[5] = 5, 10, 15
var d
call math.dot(d, a, b, 3)
call math.dot(d, a, c[0:2], 3)
call math.dot(a[0], c[0:2], 3)