This repository has been archived by the owner on May 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathminiOCaml_da_estendere.ml
144 lines (120 loc) · 4.66 KB
/
miniOCaml_da_estendere.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
(*File del Prof. Ferrari, da estendere*)
(* The language *)
type ide = string;;
type exp = CstInt of int
| CstTrue
| CstFalse
| Den of ide
| Sum of exp * exp
| Sub of exp * exp
| Times of exp * exp
| Ifthenelse of exp * exp * exp
| Eq of exp * exp
| Let of ide * exp * exp
| Fun of ide * exp
| Letrec of ide * ide * exp * exp
| Apply of exp * exp;;
type 'v env = (string * 'v) list;;
type evT = Int of int | Bool of bool | Closure of ide * exp * evT env | RecClosure of ide * ide * exp * evT env | Unbound;;
let emptyEnv = [ ("", Unbound)] ;;
let bind (s: evT env) (i:string) (x:evT) = ( i, x ) :: s;;
let rec lookup (s:evT env) (i:string) = match s with
| [] -> Unbound
| (j,v)::sl when j = i -> v
| _::sl -> lookup sl i;;
let typecheck (x, y) = match x with
| "int" ->
(match y with
| Int(u) -> true
| _ -> false)
| "bool" ->
(match y with
| Bool(u) -> true
| _ -> false)
| _ -> failwith ("not a valid type");;
let int_eq(x,y) =
match (typecheck("int",x), typecheck("int",y), x, y) with
| (true, true, Int(v), Int(w)) -> Bool(v = w)
| (_,_,_,_) -> failwith("run-time error ");;
let int_plus(x, y) =
match(typecheck("int",x), typecheck("int",y), x, y) with
| (true, true, Int(v), Int(w)) -> Int(v + w)
| (_,_,_,_) -> failwith("run-time error ");;
let int_sub(x, y) =
match(typecheck("int",x), typecheck("int",y), x, y) with
| (true, true, Int(v), Int(w)) -> Int(v - w)
| (_,_,_,_) -> failwith("run-time error ");;
let int_times(x, y) =
match(typecheck("int",x), typecheck("int",y), x, y) with
| (true, true, Int(v), Int(w)) -> Int(v * w)
| (_,_,_,_) -> failwith("run-time error ");;
let rec eval (e:exp) (s:evT env) = match e with
| CstInt(n) -> Int(n)
| CstTrue -> Bool(true)
| CstFalse -> Bool(false)
| Eq(e1, e2) -> int_eq((eval e1 s), (eval e2 s))
| Times(e1,e2) -> int_times((eval e1 s), (eval e2 s))
| Sum(e1, e2) -> int_plus((eval e1 s), (eval e2 s))
| Sub(e1, e2) -> int_sub((eval e1 s), (eval e2 s))
| Ifthenelse(e1,e2,e3) -> let g = eval e1 s in
(match (typecheck("bool", g), g) with
| (true, Bool(true)) -> eval e2 s
| (true, Bool(false)) -> eval e3 s
| (_, _) -> failwith ("nonboolean guard"))
| Den(i) -> lookup s i
| Let(i, e, ebody) -> eval ebody (bind s i (eval e s))
| Fun(arg, ebody) -> Closure(arg,ebody,s)
| Letrec(f, arg, fBody, letBody) ->
let benv = bind (s) (f) (RecClosure(f, arg, fBody,s)) in
eval letBody benv
| Apply(Den(f), eArg) ->
let fclosure = lookup s f in
(match fclosure with
| Closure(arg, fbody, fDecEnv) ->
let aVal = eval eArg s in
let aenv = bind fDecEnv arg aVal in
eval fbody aenv
| RecClosure(f, arg, fbody, fDecEnv) ->
let aVal = eval eArg s in
let rEnv = bind fDecEnv f fclosure in
let aenv = bind rEnv arg aVal in
eval fbody aenv
| _ -> failwith("non functional value"))
| Apply(_,_) -> failwith("Application: not first order function") ;;
Letrec("fact", "n",
Ifthenelse(Eq(Den("n"),CstInt(0)),
CstInt(1),
Times(Den("n"),Apply(Den("fact"),Sub(Den("n"),CstInt(1))))), Apply(Den("fact"),CstInt(3)))
(* Interprete full *)
let rec eval1 (e:exp) (s:evT env) = match e with
| CstInt(n) -> Int(n)
| CstTrue -> Bool(true)
| CstFalse -> Bool(false)
| Eq(e1, e2) -> int_eq((eval e1 s), (eval e2 s))
| Times(e1,e2) -> int_times((eval e1 s), (eval e2 s))
| Sum(e1, e2) -> int_plus((eval e1 s), (eval e2 s))
| Sub(e1, e2) -> int_sub((eval e1 s), (eval e2 s))
| Ifthenelse(e1,e2,e3) -> let g = eval e1 s in
(match (typecheck("bool", g), g) with
| (true, Bool(true)) -> eval e2 s
| (true, Bool(false)) -> eval e3 s
| (_, _) -> failwith ("nonboolean guard"))
| Den(i) -> lookup s i
| Let(i, e, ebody) -> eval ebody (bind s i (eval e s))
| Fun(arg, ebody) -> Closure(arg,ebody,s)
| Letrec(f, arg, fBody, letBody) ->
let benv = bind (s) (f) (RecClosure(f, arg, fBody,s)) in
eval letBody benv
| Apply(eF, eArg) ->
let fclosure = eval eF s in
(match fclosure with
| Closure(arg, fbody, fDecEnv) ->
let aVal = eval eArg s in
let aenv = bind fDecEnv arg aVal in
eval fbody aenv
| RecClosure(f, arg, fbody, fDecEnv) ->
let aVal = eval eArg s in
let rEnv = bind fDecEnv f fclosure in
let aenv = bind rEnv arg aVal in
eval fbody aenv
| _ -> failwith("non functional value"));;