Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
1
Elementi di semantica operazionale
2
Sintassi e semantica un linguaggio di programmazione, come ogni sistema formale, possiede una sintassi le formule ben formate del linguaggio (o programmi sintatticamente corretti) una semantica che assegna un significato alle formule ben formate dando un’interpretazione ai simboli in termini di entità (matematiche) note 2
3
Sintassi e semantica la teoria dei linguaggi formali fornisce i formalismi di specifica (e le tecniche di analisi) per trattare gli aspetti sintattici per la semantica esistono diverse teorie le più importanti sono la semantica denotazionale e la semantica operazionale la semantica formale viene di solito definita su una rappresentazione dei programmi in sintassi astratta invece che sulla reale rappresentazione sintattica concreta 3
4
Semantica operazionale
lo stile di definizione tradizionale è quello dei sistemi di transizione insieme di regole che definiscono attraverso un insieme di relazioni di transizione come lo stato cambia per effetto dell’esecuzione dei vari costrutti una tipica regola descrive la semantica di un costrutto sintattico c eseguito nello stato s, specificando il nuovo stato s’ e/o il valore calcolato v i domini semantici con cui rappresentiamo lo stato ed i valori dipendono dal linguaggio di programmazione 4
5
Linguaggio Didattico Semplice linguaggio imperativo (frammento di C), blocchi, puntatori, chiamata di funzione Rivediamo l’interprete presentato a Programmazione I
6
Sintassi concreta Programma::= int main() {StmtList}
StmtList ::= Stmt ; StmtList | e Stmt::=Decl | Com
7
Comandi Com::=Ide=Exp | Assegnamento
if (Exp) Com else Com | Condizionale while (Exp) Com | Iteratore {StmtList} | Blocco Ide(Exp) | Invocazione di fun return Exp Calcolo dei risultato di una fun
8
Espressioni Exp::= Ide | Identificatore Costante | Costante
Exp Op Exp | Operazioni Binarie Uop Exp | Operazioni Unarie Ide(Exp) | Chiamata di fun (Exp) Parentesi
9
Espressioni 2 Ide::= Lettera (Lettera | Cifra | Simbolo)*
Costante::= Numero | Carattere UnOp::= ! | * | Op::=+ | - | * |...& | > | < | ==.... Numero::=É
10
Puntatori ! si applica per semplicita’ ai soli identificatori. La locazione calcolata, in questo caso `e la locazione in cui `e memorizzato il valore dell’identificatore * che si applica ad una qualunque espressione, la calcola ottenendo un valore v che viene per`o trasformato in una locazione l. Il valore finale calcolato `e il valore v’ contenuto nella locazione l.
11
Dichiarazioni Decl ::= Type Ide [=Exp] | variabile FunctDec funzione
FunctDec::= Type Ide (Formal) {StmtList} Type::= int Formal::= Type Ide
12
Nota Per semplicita’ si considerano funzioni che hanno un solo parametro formale L’estensione a piu’ parametri e’ banale Ricordiamo che il passaggio dei parametri e’ per valore
13
Semantica Operazionale
Domini dei valori Componenti dello stato Regole di Transizione per ogni categoria sintattica (espressioni, dichiarazioni, comandi,programmi)
14
Domini semantici: lo stato
in un qualunque linguaggio ad alto livello, lo stato deve comprendere una componente chiamato ambiente (environment) per modellare l’associazione tra gli identificatori ed i valori che questi possono denotare (dval) il nostro frammento è imperativo ed ha la nozione di entità modificabile, cioè le variabili ed i puntatori (create con le dichiarazioni e modificate con l’assegnamento) è quindi necessario un secondo componente dello stato, chiamato memoria (store) per modellare l’associazione fra locazioni e valori che possono essere memorizzati (mval) 14
15
L’ambiente Per modellare i blocchi l’ambiente e’ una pila di Frames
La politica FIFO permette di catturare la dichiarazione piu’ recente di una variabile
16
Valori (memorizzabili)
Ide identificatori Val=Int + {omega}+{Undef} Loc le locazioni di memoria, possono essere rappresentati come numeri naturali. Nel seguito useremo la notazione 0L , 1L , 2L ...ecc, per indicare rispettivamente le locazioni di indirizzo 0, 1, 2 ecc
17
Memoria store: Loc ---> Val (si usa la metavariabile μ)
Nota: Val non contiene le locazioni. Nella semantica data, si usano meccanismi per trasformare locazioni in valori e viceversa. La seconda `e possibile ed anzi molto semplice perch`e le locazioni sono numeri naturali
18
Frame frame: Ide ---> Den (si usa la metavariabile φ) Den = Loc ∪ FunDecl ∪ Unbound. L’insieme delle denotazioni `e l’unione dell’insieme Loc degli indirizzi di memoria e dell’insieme FunDecl delle definizioni di funzione e della denotazione speciale Undef, che rappresenta una situazione di errore.
19
Funzioni FunDecl `e una tripla Ide × SList × Env
il nome del parametro formale il corpo della funzione l’ambiente di definizione (scoping statico)
20
Operazioni sui Frames EmptyFrame crea il frame ovunque indefinito
φ(x)=Unbound per ogni x
21
Modifica di un frame φ[d/x](y)= φ(y) se x e’ diverso da y d se x=y
La definizione cos`ı data risulta corretta anche nell’eventualit`a che un legame diverso da Unbound per x esista gia’ non e’ molto corretto solo per programmi sintatticamente corretti
22
Ambiente env=Stack(Frames) (si usa la metavariabile σ)
23
Operazioni sulla pila • EmptyStack crea la pila vuota
• top restituisce l’elemento in testa alla pila ovvero l’ultimo elemento inserito. Non modifica la pila. • pop restituisce l’elemento in testa alla pila. Modifica la pila, eliminando l’elemento in testa. • push inserisce un elemento in testa alla pila.
24
Operazioni sulla memoria
μ : Loc ---> Val Val=Int + {omega}+{Undef} Verrebbe da dare operazioni analoghe a quelle del frame....si tratta di una funzione parziale
25
Gestione della memoria
allocazione di memoria: l’inserzione di nuovi legami nella memoria corrisponde alla allocazione di memoria su una machina, e differisce dall’inserzione di un nuovo legame in un generico frame Deve esserci un meccanismo per assegnare una nuova locazione ancora libera Deve esserci un modo per distinguere una locazione assegnata con valore indefinito da una libera
26
Operazioni sulla Memoria
μ(l)=omega valore speciale μ(l)=Undef indefinita EmptyStore crea una memoria ovunque indefinita μ(x)=Undef per ogni x
27
Allocazione di Memoria
free: Store---> Loc *Store restitituisce una nuova locazione libera e la memoria modificata di conseguenza free(μ) = (μ’,l) dove μ’(l’)= μ(l’) per ogni l’!= l μ’(l)=omega se μ(l)=Undef
28
Modifica di Memoria μ[v/l](l’)= μ(l’) se l != l’ Undef se μ(l)=Undef
v altrimenti l’operazione di modifica non effettua l’inserzione del legame per l nel caso non ne esista alcuno ma in questo ultimo caso, lascia la memoria invariata (da un punto di vista matematico va bene....)
29
Le funzioni di valutazione semantica
per ogni dominio sintattico esiste una funzione di valutazione semantica E : EXPR * env * store (eval * store) C : COM * env * store store D : DEC * env * store (env * store) P : PROG * env * store store
30
Implementazione in OCaml
Vediamo i domini La Sintassi Astratta Le funzioni di valutazione semantica che assegnano un significato ai vari costrutti, con una definizione data sui casi della sintassi astratta Per semplicita’ nell’interprete si usano funzioni che restituiscono una coppia (ambiente, memoria) per ogni categoria sintattica
31
Programma PicoC http://www.di.unipi.it/~occhiuto/PicoC/
Generatore di programmi PicoC in sintassi astratta Alcuni esempi di programmi PicoC in sintassi astratta per testare l`interprete
32
Valori Val=Int + {omega}+{Undef} type value = Val of int | Omega |
33
Valori Denotabili Den = Loc ∪ FunDecl ∪ Unbound type denotation =
Loc of int | Funct of string * com * sigma ref | Unbound;; In FunDecl c’e’ il riferimento all’env (per trattare la ricorsione ..)
34
Frame frame: Ide ---> Den (si usa la metavariabile φ) type fi = Frame of (string * denotation) list;; Definizione molto a basso livello, una lista di coppie (identificatore, valore)
35
Ambiente type sigma = Stack of fi list;;
env=Stack(Frames) type sigma = Stack of fi list;; Definizione molto a basso livello, una lista di frames
36
Memoria μ : Loc ---> Val
type 'a mu = Mem of 'a list ;; Definizione molto a basso livello, una lista polimorfa Si usera’ per memorizzare coppie (identificatore, valore)
37
Espressioni type aop = Add | Sub | Mul | Div | And | Or | Ls | Gr | Eq ;; type unop = Neg | Amp | Star;; type aExp = Num of int | Exp of aExp * aop * aExp | Bracket of aExp | UnExp of unop * aExp | Var of string | Apply of string * aExp ;;
38
Comandi type com = Assign of string * aExp |
AssignDeRef of aExp * aExp | If of aExp * com * com | While of aExp * com | Block of (stmt list) | Return of aExp;;
39
Dichiarazioni type decl = Decl1 of espType * string |
Decl2 of espType * string * aExp | DeclFun of espType * string * espType * string * com;;
40
Programmi type stmt = StDec of decl | StCom of com;; type prog = Prog of (stmt list);; Un programma e’ una lista di statements (dichiarazioni, comandi)
41
Funzione main let valProg (Prog l)= let (sigma,mu)= valStmtL l (Stack[Frame[]],(Mem []))in (mu,sigma);; Il programma e’ valutato nello stato iniziale, lo stack contiene un frame vuoto e la memoria e’ vuota restituisce lo stato ottenuto
42
Per valutare una lista di statements
Funzione ricorsiva (valStmtL) Per ogni statement (comando o dichiarazione) chiama la funzione di valutazione corrispondente
43
Lista di Statements let valStmtL l (sigma, mu) = match l with|
st::stml -> (match st with | StDec d -> let (sigma1, mu1) = valDecl d (sigma,mu) in valStmtL stml (sigma1,mu1) | StCom c -> let (sigma1,mu1) = valCom c (sigma,mu) in valStmtL stml (sigma1,mu1));;
44
Dichiarazioni valDecl: Decl * (env*mem)---> (env*mem)
Funzione ricorsiva (valDecl) Usa valExp: Exp* (env*mem)---> (Val*env*mem)
45
Dichiarazioni Variabile senza inizializzazione
Variabile con inizializzazione Funzione
46
Sintassi Astratta type decl = Decl1 of espType * string |
Decl2 of espType * string * aExp | DeclFun of espType * string * espType * string * com;;
47
Funzioni Ausiliarie: memoria
free: Store---> Loc *Store restitituisce una nuova locazione libera e la memoria modificata di conseguenza (alla nuova locazione viene assegnato il valore omega) type 'a mu = Mem of 'a list ;;
48
Implementazione let free (Mem xm) = let loc = (length xm) in
((Loc loc), (Mem (append xm [((Loc loc),Omega)] )));; la lista e’ del tipo [(0,v1),(1,v20)...] la prima locazione libera e’ detreminata con length
49
Modifica della Memoria
Serve una operazione updateM:Store*Loc*Val---> Store Modifica la memoria rimpiazzando il valore associato alla locazione con il nuovo valore
50
Implementazione let rec updateM (Mem m) (x,y) = let def m x = foldr (or) false (map (compose ((=) x) (fst)) m) and modify m (x,y) = let f (x,y) b = if ((fst b)=x) then (x,y) else b in map (f(x,y)) m in if (not(def m x)) then (Mem m) else (Mem (modify m (x,y)));; Usa due funzioni ausiliarie def e modify per testare se la locazione x e’ definita e per modificarne il valore nella lista
51
Modifica dell’env let rec addBind sigma (x,y) = match sigma with | Stack [Frame[]] -> Stack [Frame[(x,y)]] | Stack ((Frame f)::fs) -> Stack ((Frame (append f [(x,y)])) ::fs);; inserisce il nuovo legame tra x ed y nell’env sigma (ovvero nel frame al top della pila, tramite append e’ una lista di coppie)
52
Dichiarazione di variabile semplice
let valDecl d (sigma,mu) = match d with Decl1 (t,i) -> let (l,mu1) = free mu in let sigma1= (addBind sigma (i, l)) in (sigma1, mu1) viene modificata la memoria (l e’ una locazione fresh, coniene valore indefinito) viene modificato l\’env inserendo l’associazione (i,l)
53
Dichiarazione di variabile con inizializzazione
let valDecl d (sigma,mu) = match d with Decl2 (t,i,e) -> let (v,(sigma1,mu1)) = (valExp e (sigma,mu)) in let (l,mu2) = free mu1 in let sigma2= (addBind sigma1 (i,l)) in let mu3 = updateM mu2 (l, v) in (sigma2, mu3) viene modificata la memoria (l e’ una locazione fresh coniene valore indefinito) viene modificato l ’env inserendo l’associazione (i,l) il contenuto della locazione l viene poi aggiornato con il valore calcolato per l’espressione e
54
Dichiarazione di Funzione
DeclFun (t,i,tp,ip, c) stiamo dichiarando una funzione di nome i,parametro ip, corpo c in (sigma,mu) dovremmo modificare l’env sigma inserendo l’associazione tra i e la sua descrizione (ip,c,sigma1) chi e’ sigma1? vediamo la regola formale
55
Problemi di Implementazione
bisogna implementarlo usando un puntatore all’env in FunDecl Funct of string * com * sigma ref | Unbound;;
56
Dichiarazione di Funzione
let valDecl d (sigma,mu) = match d with DeclFun (t,i,tp,ip, c) ->let rec sigma1=(addBind sigma (i, (Funct (ip,c, (ref sigma))))) in ((update i sigma1 sigma1),mu) in sigma1 la descrizione della funzione i contiene un riferimento a sigma (andrebbe bene se non fossero ricorsive nota che viene restituito come risultato update i sigma1 sigma1
57
Intuitivamente update i sigma1 sigma1
cerca la descrizione di funzione di i in sigma1 (p,c, sigma ref) la modifica assegnando sigma1 al posto di sigma
58
Funzione Ausiliaria let rec updateF i f sigma = match f with
(j, Funct(x,c,var))::fs when (i=j) -> var :=sigma; f | (_,_)::fs -> updateF i fs sigma;; let rec update i s sigma = match s with Stack [Frame[]]-> s | Stack ((Frame fs)::ss) -> (updateF i fs sigma); s;;
59
Comandi valCom: Com * (env*mem)---> (env*mem)
Funzione ricorsiva (valCom) Usa valExp: Exp* (env*mem)---> (Val*env*mem)
60
Comandi Condizionale While Assegnamento Blocco Return
61
Comandi type com = Assign of string * aExp |
AssignDeRef of aExp * aExp | If of aExp * com * com | While of aExp * com | Block of (stmt list) | Return of aExp;;
62
Funzioni Ausiliarie: env
lookup: Env * Ide---> Den Den = Loc ∪ FunDecl ∪ Unbound restitituisce il valore denotabile associato all’identificatore Env e’ uno Stack di Frames, in realta’ e’ una lista di frames la ricerca ricorsiva inizia dal frame al top, e.g. dal primo elemento della lista
63
Funzioni Ausiliarie: frame
look: Frame * Ide---> Den Den = Loc ∪ FunDecl ∪ Unbound restitituisce il valore denotabile associato all’identificatore Frame e’ una lista di coppie (identificatore, valore)
64
Implementazione let rec lookUp sigma y = match sigma with |
Stack [] -> Unbound | Stack (x :: xs) -> let b= (look x y) in if (not (b=Unbound)) then b else (lookUp (Stack xs) y);; let rec look fi y = match fi with | Frame [] -> Unbound | Frame ((i, d) :: xs) -> if (i=y) then d else (look (Frame xs) y);;
65
Condizionale viene calcolato il valore di e
let valCom c (sigma,mu) = match c with | If (e,c1,c2) -> let ((Val i),(sigma1,mu1)) = (valExp e (sigma,mu)) in if not (i=0) then valCom c1 (sigma,mu1) else valCom c2 (sigma,mu1) viene calcolato il valore di e se true esegue c1, altrimenti c2
66
While let valCom c (sigma,mu) = match c with | While (e,c) -> let ((Val i),(sigma1,mu1)) = (valExp e (sigma,mu)) in if not (i=0) then let (sigma2,mu2) = (valCom c (sigma1,mu1))in valCom (While (e,c)) (sigma2,mu2) else (sigma1, mu1) viene calcolato il valore di e, se false restituisce (sigma1,mu1) se true esegue While (e,c) nello stato modificato da c
67
Assegnamento let valCom c (sigma,mu) = match c with
| Assign (s,e) -> let (v,(sigma1,mu1)) = (valExp e (sigma,mu)) and (Loc l) = (lookUp sigma s) in (sigma1, updateM mu1 ((Loc l),v) viene calcolato il valore v di e e la locazione l legata alla variabile s in sigma viene modificato lo store assegnando alla locazione l il valore v
68
Blocco let valCom c (sigma,mu) = match c with | Block l ->
let (Stack (f::rl),mu1) = valStmtL l ((match sigma with Stack fl -> Stack (Frame[]::fl)) ,mu) in (Stack rl, mu1) valuta l nello stato in cui un frame vuoto Frame[] e’ stato messo al top della pila restituisce l’env da cui e’ stato fatto pop (le variabili del blocco sono locali)
69
Blocco: regola astratta
l’implementazione delle operazioni di pop() e push(frame) e’ parecchio complicata regola astratta
70
Return let valCom c (sigma,mu) = match c with | Return e ->
valCom (Assign ("retVal",e)) (sigma,mu)) assegna il valore di e ad una variabile speciale retval, valore di ritorno della funzione che e’ in esecuzione
71
Assegnamento Deferenziato
let valCom c (sigma,mu) = match c with | AssignDeRef (e,ev) -> let (v,(sigma1,mu1)) = (valExp ev (sigma,mu)) in let (v1,(sigma2,mu2)) = (valExp e (sigma1,mu1)) in let (Loc l) = (etaLoc v1) in (sigma2, updateM mu2 ((Loc l),v)) viene calcolato il valore v di e e il valore v1 di e viene modificato lo store assegnando alla locazione corrispondente a v1 il valore v
72
Funzione Ausiliaria: let niLoc x = match x with (Loc l) -> (Val l) |_ -> Undef;; let etaLoc x = match x with (Val n) when (n>=0) -> (Loc n) | _ -> Unbound;; trasformano locazioni in valori interi e viceversa
73
Espressioni valExpr: Expr * (env*mem)---> Val *(env*mem)
Funzione ricorsiva (valExpr)
74
Espressioni costanti valore di una variabile
risultato di una chiamata di funzione operazioni di confonto, somma tra espressioni (binarie) operazione unaria
75
Espressioni type aop = Add | Sub | Mul | Div | And | Or | Ls | Gr | Eq ;; type unop = Neg | Amp | Star;; type aExp = Num of int | Exp of aExp * aop * aExp | Bracket of aExp | UnExp of unop * aExp | Var of string | Apply of string * aExp ;;
76
Funzioni Ausiliarie: stato
getVal: (Env*Mem) * Ide---> Val deve restituire il valore associato all’identificatore x cercare nella pila di Frames Env la locazione l associata ad x restituire il valore associato ad l nella memoria
77
Implementazione let rec getVal (sigma,mu) x =
let b=(lookUp sigma x) in match b with | Loc n -> (lookM mu (Loc n)) | _ -> Undef;; lookUp cerca nell’env (pila) la locazione n associata ad x lookM cerca nella memoria il valore associato ad n
78
Implementazione:lookM
let rec lookM mu y = match mu with | Mem [] -> Undef | Mem (( i, v) :: xs) -> if (i=y) then v else (lookM (Mem xs) y);; la memoria e’ una lista di coppie (i,v), cerca ricorsivamente un identificatore uguale ad y
79
Costante, Parentesi let rec valExp e (sigma,mu) = match e with
| Num n -> ((Val n),(sigma,mu)) | Bracket x -> valExp x (sigma,mu)
80
Variabile let rec valExp e (sigma,mu) = match e with | Var s -> ((getVal (sigma,mu) s),(sigma,mu)) restituisce il valore associato alla variabile s, calcolato tramite getVal
81
Operazioni Binarie let rec valExp e (sigma,mu) = match e with | Exp (x, op, y) -> let (v1, (sigma1,mu1))= (valExp x (sigma,mu)) in let (v2,(sigma2,mu2))= (valExp y (sigma,mu1)) in... calcola ricorsivamente i valore v1 e v2 di x ed y, rispettivamente in un ordine
82
Procede per casi sull’operazione
if (isNumOp op) then (niNum ( (funNumOp op) (etaNum v1) (etaNum v2)),(sigma2,mu2)) else isNumOp restituisce true se e’ una operazione numerica (somma etc..) FunNumOp applica l’operazione corrispondente a op ai valori v1 e v2 niNum,etaNum servono solo per convertire i valori Val i in i e viceversa
83
Funzioni ausiliarie let isNumOp op = match op with | Add -> true
| Sub -> true | Div -> true | Mul -> true | _ -> false;;
84
Funzioni ausiliarie let funNumOp op = match op with| Add -> (+)|
Sub -> (-)| Mul -> (fun x y -> x*y) | Div -> (/) ;;
85
Funzioni ausiliarie di conversione per interi
let niNum x = (Val x);; let etaNum (Val x) = x;;
86
Procede per casi if (isBoolOp op) then
(niBool( (funBoolOp op) (etaBool v1) (etaBool v2)) ,(sigma2,mu2)) else (niBool( (funRelOp op) (etaNum v1) (etaNum v2)) ,(sigma2,mu2)) se e’ un’operazione booleana applica la relativa operazione ai valori booleani v1 e v2 se e’ un’operazione relazionale applica la relativa operazione ai valori booleani v1 e v2
87
Funzioni ausiliarie let isBoolOp op = match op with | And -> true
| Or -> true | _ -> false;;
88
Funzioni Ausiliarie let funBoolOp op = match op with | And -> (&)
| Or -> (or) ;; let funRelOp op = match op with| Ls -> (<) | Gr -> (>) | Eq -> (=);;
89
Funzioni Ausiliarie di conversione
let niBool x = if x then (Val 1) else (Val 0);; let etaBool (Val x) = if (x=0) then false else true;;
90
Operazioni Unarie: per casi
let rec valExp e (sigma,mu) = match e with | UnExp (op, x) -> (match op with Neg -> let (v1, (sigma1,mu1))= (valExp x (sigma,mu)) in (niBool( (funop1 op) (etaBool(v1)) ),(sigma1,mu1)) caso della negazione e’ analogo a quello visto prima calcola il valore v di x e chiama funzioni ausiliarie
91
Operazioni Unarie: puntatore
| UnExp (op, x) -> (match op with |Amp -> ((valDen x sigma),(sigma,mu)) deve restituire la locazione di x usa una funzione ausiliaria valDen
92
Funzione ausiliaria:valDen
let rec valDen e sigma = (match e with |Var s -> niLoc(lookUp sigma s) |Exp (x,y,z) -> Undef|UnExp(x,y) -> Undef| Bracket x -> Undef);; e’ definita nel caso di espressione e generica, ma e’ definita solo per le variabili tramite lookup restituisce la locazione associata ad s nell’ambiente sigma
93
Operazioni Unarie: deferenziato
| UnExp (op, x) -> (match op with |Star -> let (v,(sigma,mu1)) =(valExp x (sigma,mu)) in (lookM mu1 (etaLoc v),(sigma,mu1))) calcola il valore v di x (tramite valExp) restuisce il valore memorizzato nella memoria nella locazione v
94
Chiamata di Funzione Apply(s,a) dobbiamo applicare la funzione s al parametro attuale a nello stato (sigma,mu) Parte I: dobbiamo cercare il nome s nell’ambiente sigma, restituisce un FunDecl Funct(f,c,sigmaf) f e’ il parametro formale c e’ il corpo della funzione sigmaf e’ l’ambiente al momento della dichiarazione della funzione s (scoping statico) Parte II: dobbiamo valutare il parametro a nello stato corrente, calcolarne il valore v (per valore)
95
Chiamata di Funzione:Part II
Dobbiamo valutare il corpo della funzione c, in quale stato? Lo stato di valutazione si costruisce a partire da (sigmaf,mu) Bisogna mettere sulla pila sigmaf un EmptyFrame (push) che serve per contenere le dichiarazioni locali alla funzione Le dichirazioni locali conterranno il legame tra il parametro formale f ed il valore del parametro attuale v e la variabile speciale retval Nota che per inserire un legame devono essere modifica sia l’ambiente che la memoria
96
Chiamata di Funzione:Part III
Cosa restituisce? il valore associato alla variabile retval l’ambiente sigma al momento della chiamata (non modificato) la memoria modificata dall’esecuzione dei comandi
97
Chiamata di Funzione: valExp
Vediamo il codice di valExp per la funzione Molto complicato, perche’ di basso livello La nozione di stato (env,mem) non fornisce operazioni chiare per fare push, pop Inoltre l’introduzione di un nuovo legame in un frame viene fatto a mano, operando direttamente sulla lista che implementa il frame Analogamente l’introduzione di un nuovo legame nella memoria viene fatto a mano, operando direttamente sulla lista che lo implementa
98
Chiamata di funzione let rec valExp e (sigma,mu) = match e with | Apply (s,a) -> let (v,(sigma1,mu1))= valExp a (sigma,mu) in (match (lookUp sigma s) with Funct (f,c, sigmaf) -> calcola tramite valExp il valore v del parametro attuale a cerca tramite lookUp la FunDecl relativa ad s
99
Chiamata di funzione sceglie due locazioni libere in memoria l ed l1
(let (l,mu2)=(free mu1) in let (l1,mu3) =(free mu2) in let sigmav=(match (! sigmaf) with Stack sl -> addBind (addBind (Stack (Frame []::sl)) (f,l)) ("retVal",l1)) sceglie due locazioni libere in memoria l ed l1 modifica l’ambiente sigmaf , facendo push di un frame che contiene (f,l) e (retval l1)
100
Chiamata di funzione in let (sigma2,mu4)=
valCom c (sigmav,updateM mu3 (l, v)) in ((lookM mu4 l1),(sigma,mu4))) valuta il corpo della funzione c nell’ambiente sigmav costruito in precedenza,e nella memoria ottenuta aggiungendo il legame tra (l,v) restituisce il valore della locazione l1 nella memoria (il valore di retval), l’ambiente sigma iniziale, e la memoria finale mu4
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.