Il progetto finale consiste nell'implementazione di un'estensione del linguaggio sviluppato durante gli ultimi laboratori Java; può quindi essere usata come base di partenza la soluzione proposta per l'ultimo laboratorio.
L'interfaccia da linea di comando per interagire con l'interprete è la stessa utilizzata nei laboratori finali:
- il programma da eseguire può essere letto da un file di testo
<filename>con l’opzione-i <filename>, altrimenti viene letto dallo standard input - l'output del programma in esecuzione può essere salvato su un file di testo
<filename>con l’opzione-o <filename>, altrimenti viene usato lo standard output - l’opzione
-ntc(abbreviazione di no-type-checking) permette di eseguire il programma senza effettuare prima il controllo di semantica statica del typechecker
Il linguaggio contiene le nuove parole chiave foreach e in e i nuovi simboli [ e ].
La sintassi del linguaggio è definita da questa grammatica in forma EBNF:
Prog ::= StmtSeq EOF
StmtSeq ::= Stmt (';' StmtSeq)?
Stmt ::= 'var'? IDENT '=' Exp | 'print' Exp | 'if' '(' Exp ')' Block ('else' Block)? | 'foreach' IDENT 'in' Exp Block
Block ::= '{' StmtSeq '}'
Exp ::= And (',' And)*
And ::= Eq ('&&' Eq)*
Eq ::= Add ('==' Add)*
Add ::= Mul ('+' Mul)*
Mul::= Atom ('*' Atom)*
Atom ::= 'fst' Atom | 'snd' Atom | '-' Atom | '!' Atom | BOOL | NUM | IDENT | '(' Exp ')' | '[' Exp ';' Exp ']'
La grammatica non richiede trasformazioni e può essere utilizzata così com'è per sviluppare un parser per il linguaggio con un solo token di lookahead.
Rispetto al linguaggio del laboratorio, sono stati aggiunti
- il literal di tipo vector
'[' Exp ';' Exp ']' - lo statement
'foreach' IDENT 'in' Exp Block
La semantica statica è definita in OCaml nella prima parte del file semantica.ml; è utile consultare anche gli esempi nel folder test. Il nuovo tipo vector corrisponde a vettori di interi costruiti a partire dai literal '[' Exp ';' Exp ']' e dagli operatori '+' e '*'.
- il literal
'[' Exp1 ';' Exp2 ']'è corretto e ha tipovectorseExp1eExp2hanno tipoint - l'espressione
Exp1 '+' Exp2è corretta e ha tipointseExp1eExp2hanno tipoint - l'espressione
Exp1 '+' Exp2è corretta e ha tipovectorseExp1eExp2hanno tipovector - l'espressione
Exp1 '*' Exp2è corretta e ha tipointseExp1eExp2hanno tipoint - l'espressione
Exp1 '*' Exp2è corretta e ha tipointseExp1eExp2hanno tipovector - l'espressione
Exp1 '*' Exp2è corretta e ha tipovectorseExp1ha tipointeExp2ha tipovectoroppureExp1ha tipovectoreExp2ha tipoint - lo statement
'foreach' IDENT 'in' Exp Blockè corretto seExpha tipovectorrispetto all'ambiente correnteenveBlockè corretto rispetto all'ambiente ottenuto aggiungendo aenvun nuovo scope annidato dove l'unica variabile dichiarata èIDENTdi tipoint.
La semantica dinamica è definita in OCaml nella seconda parte del file semantica.ml; è utile consultare anche gli esempi nel folder test.
- se
Exp1eExp2si valutano negli interiindedim, allora'[' Exp1 ';' Exp2 ']'si valuta nel vettore di dimensionedimche contiene 1 in corrispondenza dell'indiceinde 0 nelle altre posizioni. Gli indici iniziano da 0, viene sollevata un'eccezione sedimè negativo, oppureindnon è maggiore o uguale di 0 e minore didim.
Esempio
print [3;5]
stampa
[0;0;0;1;0]
- se
Exp1eExp2si valutano negli interii1ei2, alloraExp1'+'Exp2si valuta nell'interoi1+i2 - se
Exp1eExp2si valutano nei vettoriv1ev2, alloraExp1'+'Exp2si valuta nel vettorev1+v2; viene sollevata un'eccezione se i due vettori non hanno la stessa dimensione. La somma di vettori è definita da
[a_0;...;a_n]+[b_0;...;b_n]=[a_0+b_0;...;a_n+b_n]
- se
Exp1eExp2si valutano negli interii1ei2, alloraExp1'*'Exp2si valuta nell'interoi1*i2 - se
Exp1eExp2si valutano nei vettoriv1ev2, alloraExp1'*'Exp2si valuta nell'intero ottenuto dal prodotto scalare div1ev2; viene sollevata un'eccezione se i due vettori non hanno la stessa dimensione. Il prodotto scalare di vettori è definito da
[a_0;...;a_n]*[b_0;...;b_n]=a_0*b_0+...+a_n*b_n
- se
Exp1eExp2si valutano in un interoie in un vettorev, o viceversa, alloraExp1'*'Exp2si valuta nel vettore ottenuto dal prodotto misto traiev. Il prodotto misto tra un intero e un vettore è definito da
i*[a_0;...;a_n]=[a_0;...;a_n]*i= [i*a_0;...;i*a_n]
- l'esecuzione dello statement
'foreach' IDENT 'in' Exp Blockconsiste nella valutazione dell'espressioneExprispetto all'ambiente correnteenv; deve essere restituito un vettorevsui cui elementi viene iterata l'esecuzione diBlockrispetto a un ambiente ottenuto daenvaggiungendo uno scope annidato contenente la sola variabileIDENTalla quale viene assegnato a ogni iterazione un elemento divin ordine dall'indice minimo al massimo. Inizialmente la variabileIDENTviene inizializzata con un valore intero arbitrario.
Esempio:
foreach i in [0;3]+2*[1;3]+3*[2;3]{print i}
stampa
1
2
3
Importante:
- i valori di tipo vector sono stampabili e vengono visualizzati mediante la notazione [a_0;...;a_n]
- due vettori sono uguali se e solo se hanno la stessa dimensione e gli stessi elementi in corrispondenza degli stessi indici
[a_0;...;a_n]=[b_0;...;b_m] se e solo se n=m e a_i=b_i per ogni i=1..n
- per implementare l'esecuzione dello statement
foreachconviene usare il corrispondente statement Java evitando la ricorsione
semantica.ml: semantica statica e dinamica del linguaggio esteso, definita in OCamltests/success: test corretti anche senza l'opzione-ntctests/failure/syntax: test con errori di sintassitests/failure/static-semantics: test con errori statici senza l'opzione-ntced errori dinamici con l'opzione-ntctests/failure/static-semantics-only: test con errori statici senza l'opzione-ntce corretti con l'opzione-ntctests/failure/dynamic-semantics: test che generano errori dinamici con o senza l'opzione-ntc
- La consegna è valida solo se il progetto passa tutti i test contenuti nel folder
tests; la valutazione del progetto tiene conto dell'esecuzione di test aggiuntivi e della qualità del codice - Le scadenze dei turni di consegna coincidono con le date delle prove scritte; dopo ogni scadenza, vengono corretti tutti i progetti consegnati e pubblicati i relativi risultati prima che le consegne siano riaperte. Dopo la data dell'ultima prova scritta dell'appello invernale non è più possibile consegnare progetti validi per l'anno accademico in corso
- Il progetto può essere consegnato anche se l'esame scritto non è stato ancora superato
- Dopo il commit (e push) finale del progetto su GitHub, la consegna va segnalata da un singolo componente del gruppo utilizzando AulaWeb e indicando il numero del gruppo definito nell'elenco su AulaWeb
- Per ricevere supporto durante lo sviluppo del progetto è consigliabile tenere sempre aggiornato il codice del progetto sul repository GitHub
- Dopo che il progetto è stato valutato positivamente, il relativo colloquio individuale può essere sostenuto anche se l'esame scritto non è stato ancora superato; esso ha lo scopo di verificare che ogni componente del gruppo abbia compreso il funzionamento del codice e abbia contribuito attivamente al suo sviluppo
- Per ulteriori informazioni consultare la pagina AulaWeb sulle modalità di esame