AA Realizzare un interprete in OCaml
|
|
|
- Corrado Ferrero
- 9 anni fa
- Visualizzazioni
Transcript
1 AA Realizzare un interprete in OCaml 1
2 La stru/ura let x = 3 in x+x;; Parsing Programma (text-file) Rappresentazione Intermedia (IR) Let ( x, Num 3, B_op(Plus, Var x, Var x )) Num 6 Pre/y PrinOng Esecuzione (Interprete) 6 SemanOca del linguaggio guida la definizione di IR e dell esecuzione
3 La stru/ura nel de/aglio OCAML Type per descrivere la rappresentazione intermedia type variable = string type op = Plus Minus Times type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp type value = exp
4 La stru/ura nel de/aglio type variable = string type op = Plus Minus Times type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp type value = exp Rappresentazione di let e1 = Int_e 3 let e2 = Int_e 17 let e3 = Op_e (e1, Plus, e2)
5 let x = 30 in let y = (let z = 3 in z*4) in y+y;; Programma OCaml Exp Let_e( x, Int_e 30, Let_e( y, Let_e( z, Int_e 3, Op_e(Var_e z, Times, Int_e 4)), Op_e(Var_e y, Plus, Var_e y )
6 let x 30 let y let + AST z 3 * y y z 4
7 Variabili: dichiarazione e uso type variable = string type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp
8 Run Ome: operazione di supporto let is_value (e : exp) : bool = Int_e _ -> true ( Op_e _ Let_e _ Var_e _ ) -> false;; eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp
9 Variabili: dichiarazione e uso Type variable = string type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp Uso di una variabile
10 Variabili: dichiarazione e uso Type variable = string type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp Uso di una variabile Dichiarazione di variable
11 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Op_e(e1,op,e2) -> Let_e(x,e1,e2) ->
12 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Int_e i Op_e(e1,op,e2) -> Let_e(x,e1,e2) ->
13 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Int_e i Op_e(e1,op,e2) -> let v1 = eval e1 in let v2 = eval e2 in eval_op v1 op v2 Let_e(x,e1,e2) ->
14 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Int_e i Op_e(e1,op,e2) -> let v1 = eval e1 in let v2 = eval e2 in eval_op v1 op v2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2
15 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Int_e i Op_e(e1,op,e2) -> eval_op eval e1 op eval e2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2
16 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp Come avviene la valutazione? let rec eval (e : exp) : exp = Int_e i -> Int_e i Op_e(e1,op,e2) -> eval_op eval e1 op eval e2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2 Usare let per definirne l ordine
17 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Non dovremmo incontrare una variabile l avremmo già dovuta Int_e i -> Int_e i sosotuire con un valore!! Op_e(e1,op,e2) -> eval_op eval e1 op eval e2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2 Var_e x ->??? Questo è un errore di Spo
18 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp opson = Int_e i -> Some(Int_e i) Op_e(e1,op,e2) -> eval_op eval e1 op eval e2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2 Questo complica l interprete: Var_e x -> None matching sui risultao delle chiamate ricorsive di eval
19 L interprete RTS is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = Int_e i -> Int_e i Tali eccezioni fanno parte del RTS Op_e(e1,op,e2) -> eval_op eval e1 op eval e2 Let_e(x,e1,e2) -> let v1 = eval e1 in let e2 = subsstute v1 x e2 in eval e2 Var_e x -> raise (UnboundVariable x)
20 RTS: eval_op let eval_op (v1:exp) (op:operand) (v2:exp) : exp = match v1, op, v2 with Int_e i, Plus, Int_e j -> Int_e (i + j) Int_e i, Minus, Int_e j -> Int_e (i - j) Int_e i, Times, Int_e j -> Int_e (i * j) _, (Plus Minus Times), _ -> if is_value v1 && is_value v2 then raise TypeError else raise NotValue
21 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> Op_e(e1,op,e2) -> Var_e y ->... use x... Let_e (y,e1,e2) ->... use x... in subst e
22 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Var_e y ->... use x... Let_e (y,e1,e2) ->... use x... in subst e
23 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Op_e(subst e1,op,subst e2) Var_e y ->... use x... Let_e (y,e1,e2) ->... use x... in subst e x, v implici:
24 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Op_e(subst e1,op,subst e2) Var_e y -> if x = y then v else e Let_e (y,e1,e2) ->... use x... in subst e
25 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Op_e(subst e1,op,subst e2) Var_e y -> if x = y then v else e Let_e (y,e1,e2) -> Let_e (y,subst e1,subst e2) in subst e
26 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Op_e(subst e1,op,subst e2) Var_e y -> if x = y then v else e Let_e (y,e1,e2) -> Let_e (y,subst e1,subst e2) in subst e ERRORE
27 RTS: subsotuoon let subsotute (v:value) (x:variable) (e:exp) : exp = let rec subst (e:exp) : exp = Int_e _ -> e Op_e(e1,op,e2) -> Op_e(subst e1,op,subst e2) Var_e y -> if x = y then v else e Let_e (y,e1,e2) -> Let_e (y,subst e1, if x = y then e2 else subst e2) in subst e If x = y shadow scope!!
28 Funzioni
29 Sintassi type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp Fun_e of variable * exp FunCall_e of exp * exp
30 Sintassi type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp Fun_e of variable * exp FunCall_e of exp * exp La sintassi OCaml fun x e viene rappresentata come Fun_e(x, e) La chiamata fact 3 viene rappresentata come FunCall_e (Var_e fact, Int_e 3)
31 Estendiamo il RTS let is_value (e : exp) : bool = Int_e _ -> true Fun_e (_,_) -> true ( Op_e (_,_,_) Let_e (_,_,_) Var_e _ FunCall_e (_,_) ) -> false Le funzioni sono valori!!
32 Interprete ++ is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = : Var_e x -> raise (UnboundVariable x) Fun_e (x, e) -> Fun_e (x, e) FunCall_e (e1, e2) -> match eval e1, eval e2 with Fun_e (x, e), v2 -> eval (subsstute v2 x e) _ -> raise (TypeError)
33 Funzioni ricorsive type exp = Int_e of int Op_e of exp * op * exp Var_e of variable Let_e of variable * exp * exp Fun_e of variable * exp FunCall_e of exp * exp Rec_e of variable * variable * exp let g = rec f x -> f (x + 1) in g 3 Let_e ( g, Rec_e ( f, x, FunCall_e (Var_e f, Op_e (Var_e x, Plus, Int_e 1)) ), FunCall (Var_e g, Int_e 3) )
34 Le funzioni ricorsive sono valori let is_value (e : exp) : bool = Int_e _ -> true Fun_e (_,_) -> true Rec_e of (_,_,_) -> true ( Op_e (_,_,_) Let_e (_,_,_) Var_e _ FunCall_e (_,_) ) -> false
35 La nozione di sosotuzione SosOtuire il valore v al posto della variabile x nella espressione e: e [ v / x ] (x + y) [7/y] diventa (x + 7) (let x = 30 in let y = 40 in x + y) [7/y] diventa (let x = 30 in let y = 40 in x + y) (let y = y in let y = y in y + y) [7/y] diventa (let y = 7 in let y = y in y + y)
36 Come valutare le funzioni ricorsive IDEA (rec f x = body) arg --> body [arg/x] [rec f x = body/f] Passaggio parametri JIT compilason del body
37 let g = rec f x -> if x <= 0 then x else x + f (x - 1) in g 3 g 3 [rec f x -> if x <= 0 then x else x + f (x-1) / g] (rec f x -> if x <= 0 then x else x + f (x - 1)) 3 La dichiarazione La sosotuzione Risultato finale
38 (if x <= 0 then x else x + f (x - 1)) [ 3 / x ] [ rec f x -> if x <= 0 then x else x + f (x - 1) / f ] (if 3 <= 0 then 3 else 3 + (rec f x -> if x <= 0 then x else x + f (x - 1)) (3-1))
39 Interprete is_value : exp -> bool eval_op : value -> op -> value -> value subsstute : value -> variable -> exp -> exp let rec eval (e : exp) : exp = : FunCall_e (e1, e2) -> match eval e1 with Fun_e (x, e) -> let v = eval e2 in subsotute e x v (Rec_e (f, x, e)) as g -> let v = eval e2 in subsotute (subsotute e x v) f g
40 Cosa abbiamo imparato? OCaml può essere usato come linguaggio per la simulazione della semanoca operazionale di un linguaggio (incluso se stesso!) Vantaggio: simulazione dell implementazione Svantaggio: complicato per le operazioni da effe/uare con i Opi di Ocaml o Op_e(e1, Plus, e2) rispe/o a e1 + e2
Università Ca Foscari Dipartimento di informatica. Programmazione part-time. Esame Ocaml
Soluzione Università Ca Foscari Dipartimento di informatica Programmazione part-time Esame Ocaml Nome: Matricola: Samuel Rota Bulò, a.a. 2009/2010 Programmazione part-time a.a. 2009/2010 Esame Ocaml Nome:
Espressioni aritmetiche
Espressioni aritmetiche Consideriamo espressioni costruite a partire da variabili e costanti intere mediante applicazione delle operazioni di somma, sottrazione, prodotto e divisione (intera). Ad esempio:
Programmazione Funzionale
1/9 Programmazione Funzionale Esercizio sulle variabili locali Davide Mottin - Themis Palpanas March 12, 2014 OCaml Funzioni preparatorie Sommario 2/9 Funzioni preparatorie Costruire una funzione val even
Tecniche per risolvere problemi: riduzione a sottoproblemi più semplici. Ricorsione
Tecniche per risolvere problemi: riduzione a sottoproblemi più semplici Ricorsione 1 Tecniche per risolvere problemi: riduzione a sottoproblemi più semplici Problema: dati tre numeri interi, calcolarne
Definizioni ricorsive
Definizioni ricorsive Caso base : (* fact: int -> int *) let rec fact n = if n=0 then 1 else n * fact (n-1) n! = 1 2... n 1 n = (n 1)! n = n (n 1)! 0! = 1 Il fattoriale è definito in termini di se stesso,
Nomi, binding e regole di scope
Nomi, binding e regole di scope 1 Nomi Un nome in un linguaggio di programmazione è esa5amente quello che immaginate o la maggior parte dei nomi sono defini; dal programma (gli iden;ficatori) o ma anche
Programmazione Ricorsione in coda
Programmazione Ricorsione in coda Samuel Rota Bulò DAIS Università Ca Foscari di Venezia. Outline Ricorsione in coda Ricorsione in coda La ricorsione in coda (o tail-recursion) è un caso speciale di ricorsione
AA OCaml: un veloce ripasso
AA 2015-2016 17. OCaml: un veloce ripasso 1 Lo s,le funzionale In Java (ma anche in C) l effe@o osservabile di un programma è la modifica dello stato temp = pair.x; pair.x = pair.y; pair.y = temp; In Ocaml
Definizioni syntax-directed
Definizioni syntax-directed Esempio: Notazione infissa Notazione postfissa Produzioni E E 1 + T E E 1 T E T T 0 T 1 T 2... T 9 Regole semantiche E.t := E 1.t _T.t _ + E.t := E 1.t _T.t _ - E.t := T.t T.t
Elementi di Base. Introduzione a Python.
Elementi di Base Introduzione a Python http://www.dia.uniroma3.it/~roselli/ [email protected] Credits Materiale a cura del Prof. Franco Milicchio Panoramica Elementi di base della sintassi (struttura,
Elementi di semantica operazionale
Elementi di semantica operazionale 1 Contenuti sintassi astratta e domini sintattici un frammento di linguaggio imperativo semantica operazionale domini semantici: valori e stato relazioni di transizione
Programmazione 2. Introduzione al corso
Programmazione 2 Introduzione al corso Informazioni generali Sito del corso http://matematica.unipv.it/gualandi/programmazione2/ Orario lezioni: Martedi 9h00/11h00 Aula C8 o Lab. Mate Giovedi 14h00/15h00
1 Il Paradigma Imperativo
1 Il Paradigma Imperativo 1.1 Imp : un semplice linguaggio imperativo Abbiamo visto in Fun un meccanismo eager per la valutazione dei parametri di una funzione ed un meccanismo lazy. Una situazione analoga
Elementi di semantica denotazionale ed operazionale
Elementi di semantica denotazionale ed operazionale 1 Contenuti! sintassi astratta e domini sintattici " un frammento di linguaggio imperativo! semantica denotazionale " domini semantici: valori e stato
Linguaggi e Ambienti di Programmazione
Linguaggi e Ambienti di Programmazione Principi e tecniche diffuse che si incontrano spesso nelle applicazioni dell informatica. Compilatori Editor di struttura: riceve in input una sequenza di comandi
Lezione 6 Introduzione al C++ Mauro Piccolo
Lezione 6 Introduzione al C++ Mauro Piccolo [email protected] Linguaggi di programmazione Un linguaggio formale disegnato per descrivere la computazione Linguaggi ad alto livello C, C++, Pascal, Java,
OCAML un breve ripasso
OCAML un breve ripasso Value-oriented programming value-oriented programming : una espressione Ocaml denota un valore. L esecuzione di un programma OCaml puo essere vista come una sequenza di passi di
laboratorio di python
laboratorio di python definizioni di booleani, selezione ed uso degli input 13 Marzo 2019 1/32 Correzione esercizi per oggi esercizio 1 per casa Scrivere una funzione che non ha nessun parametro, non restituisce
Il linguaggio C. Notate che...
Il linguaggio C Notate che... 1 Il C è un linguaggio a blocchi int main (void) { blocco } 2 Il C è un linguaggio a blocchi (2) Non è possibile mischiare dichiarazioni e comandi! int main (void) { } Dichiarazione
Laboratorio di Python
, Input da tastiera, Iterazione incondizionata 7 marzo 2014 Sommario 1 2 3 Outline 1 2 3 Definizione di funzione import modulo Si importa il modulo specificato def nome_f(par 1,, par n ) : Si definiscono
AA Implementazione di un linguaggio impera4vo
AA 2015-2016 25. Implementazione di un linguaggio impera4vo 1 Cara,eris0che del linguaggio impera0vo Include totalmente il linguaggio funzionale o inclusi i costru@ Fun, Apply e Rec Le espressioni includono
Definizione di nuovi tipi
Definizione di nuovi tipi Un tipo è un insieme di valori. Per definire un nuovo tipo occorre specificare: 1 un nome per il tipo 2 come costruire i valori del tipo, cioè quali sono i costruttori del tipo.
LA LOGICA DI HOARE. Corso di Logica per la Programmazione A.A. 2010/11 Andrea Corradini, Paolo Mancarella
LA LOGICA DI HOARE Corso di Logica per la Programmazione A.A. 2010/11 Andrea Corradini, Paolo Mancarella INTRODUZIONE Dall inizio del corso ad ora abbiamo introdotto, un po alla volta, un linguaggio logico
Laboratorio di Python
Istruzione di condizione, Input da tastiera, Università di Bologna 6 e 8 marzo 2013 Sommario 1 Tipi di errore e Debugging 2 3 4 Outline Tipi di errore e Debugging 1 Tipi di errore e Debugging 2 3 4 Esercizio
Cognome e Nome : Corso e Anno di Immatricolazione: Modalità di Laboratorio (Progetto/Prova) :
PROGRAMMAZIONE (Corsi B e C) Pre-appello di Gennaio 2004 (A.A. 2003/2004) PROGRAMMAZIONE (B e C) S. Straordinaria - Appello di Gennaio (A.A. 2002/2003) 22 Gennaio 2004 ore 11 Aula II di Facoltà (Durata:
7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari
7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa
Informatica 1 Tipi e dichiarazioni in C++ C++ - Tipi e dichiarazioni 1
Informatica 1 Tipi e dichiarazioni in C++ C++ - Tipi e dichiarazioni 1 Cosa è il C++ E un linguaggio di programmazione derivato dal C Può essere usato per modificare il SO Unix e i suoi derivati (Linux)
