Advertisement
Luiggi_98

OCaml_Interprete_Funzionante_ConFunzioni

Dec 9th, 2018
379
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 14.25 KB | None | 0 0
  1. (*INTERPRETE DIOCAMEL BY LUIGGI FINALMENTE CHE WORKA YAHUUU*)
  2. (*Definisco cosa stracazzo è un identificatore*)
  3. type ide = string;;
  4. (*Definisco i tipi di tutte le espressioni usabili nel mio linguaggio MUAHAHAHAHA*)
  5. type exp =
  6. EInt of int |
  7. EBool of bool |
  8. EString of string |
  9. Den of ide |
  10. Addizione of exp * exp |
  11. Sottrazione of exp * exp |
  12. Moltiplicazione of exp * exp |
  13. Divisione of exp * exp |
  14. Quadrato of exp |
  15. Cubo of exp |
  16. Esp of exp * exp |
  17. Zero of exp |
  18. Equivalente of exp * exp |
  19. Maggiore of exp * exp |
  20. Minore of exp * exp |
  21. MaggioreUg of exp * exp |
  22. MinoreUg of exp * exp |
  23. Meno of exp |
  24. Not of exp |
  25. And of exp * exp |
  26. Or of exp * exp|
  27. Impl of exp * exp|
  28. Xor of exp * exp |
  29. Nand of exp * exp |
  30. IfThenElse of exp * exp * exp |
  31. Let of ide * exp * exp | (*ASSEGNAMENTO VARIABILE CON IL LET COME IN OCAMELL*)
  32. Fun of ide * exp | (*FUNZIONE ANONIMA CON UN PARAMETRO COME IN OCAMELL*)
  33. Apply of exp * exp | (*CHIAMATA DI FUNZIONE (LA FAMOSA FUNCALL DIOCAML)*)
  34. Letrec of ide * exp * exp;; (*CHIAMATA DI FUNZIONE RICORSIVA*)
  35. (*CREAZIONE DELL'AMBIENTE POLIMORFO (OVVERO L'AMBIENTE E' UNA FUNZIONE)*)
  36. type 't env = ide -> 't;;
  37. (*DEFINIZIONE DEI TIPI ESPRIMIBILI NEL MIO LINGUAGGIO*)
  38. type evT = Bool of bool | Int of int | Den of string | String of string | Unbound | Funval of efun | RecFunval of ide * efun and efun = ide * exp * evT env;;
  39. (*DEFINIZIONE DI AMBIENTE VUOTO*)
  40. let emptyenv = fun x -> Unbound;;
  41. (*FUNZIONE CHE CREA UNA NUOVA ASSOCIAZIONE NELL'AMBIENTE*)
  42. let applyenv (r : 't env) (i : ide) = r i;;
  43. (*FUNZIONE CHE ASSOCIA UN NUOVO VALORE A UN IDENTIFICATORE NELL'AMBIENTE SE ESISTE GIA', CHIAMA APPLYENV ALTRIMENTI (E QUINDI LO CREA)*)
  44. let bind (r : 't env) (i : ide) (v : 't) = fun x -> if (x = i) then v else applyenv r x;;
  45.  
  46.  
  47.  
  48.  
  49.  
  50. (*RUN TIME SUPPORT*)
  51. (*FUNZIONE CHE MI CONTROLLA I TIPI SENNO' SONO CAZZOTTI IN FACCIA*)
  52. let typecheck (s : string) (e : evT) : bool =
  53.     match s with
  54.         "int" -> (match e with  
  55.             Int(_) -> true |
  56.             (_) -> false) |
  57.         "string" -> (match e with
  58.             String(_) -> true |
  59.             (_) -> false) |
  60.         "bool" -> (match e with
  61.             Bool(_) -> true |
  62.             (_) -> false) |
  63.         _ -> failwith("Errore, tipo non valido");;
  64.  
  65. (*let stringa x = match x with
  66.     Int a -> "Intero"
  67.     | String a -> "Stringa"
  68.     | Bool a -> "Booleano"
  69.     | Unbound -> "Unbound ci scommetto 10 euro";;*)
  70. (*FUNZIONI AUSILIARIE DELLE OPERAZIONI DI BASE*)
  71. let add x y = if (typecheck "int" x && typecheck "int" y) then
  72.                     (match (x, y) with
  73.                         (Int(a),Int(b)) -> Int(a+b) |
  74.                         (_,_) -> failwith("Match sbagliato"))
  75.               else failwith("Errore di tipo");;
  76. let sott x y = if (typecheck "int" x && typecheck "int" y) then
  77.                     (match (x, y) with
  78.                         (Int(a),Int(b)) -> Int(a-b) |
  79.                         (_,_) -> failwith("Match sbagliato"))
  80.               else failwith("Errore di tipo");;
  81. let molt x y = if (typecheck "int" x && typecheck "int" y) then
  82.                     (match (x, y) with
  83.                         (Int(a),Int(b)) -> Int(a*b) |
  84.                         (_,_) -> failwith("Match sbagliato"))
  85.               else failwith("Errore di tipo");;
  86. let div x y = if (typecheck "int" x && typecheck "int" y) then
  87.                     (match (x, y) with
  88.                         (Int(a),Int(b)) -> if (b != 0) then Int(a/b) else failwith("Errore divisione per zero") |
  89.                         (_,_) -> failwith("Match sbagliato"))
  90.               else failwith("Errore di tipo");;
  91. let quad x = if (typecheck "int" x) then
  92.                     (match x with
  93.                         Int(a) -> Int(a*a) |
  94.                         (_) -> failwith("Match sbagliato"))
  95.               else failwith("Errore di tipo");;
  96. let cub x = if (typecheck "int" x) then
  97.                     (match x with
  98.                         (Int(a)) -> Int(a*a*a) |
  99.                         (_) -> failwith("Match sbagliato"))
  100.               else failwith("Errore di tipo");;
  101.  
  102. let rec pow x y = match (x,y) with
  103.                     (0,0) -> failwith("Che stracazzo volevi fare") |
  104.                     (0,_) -> 0 |
  105.                     (1,_) -> 1 |
  106.                     (_,0) -> 1 |
  107.                     (x,1) -> x |
  108.                     (x,y) -> x * pow x (y-1);;
  109.  
  110. let espon x y = if (typecheck "int" x && typecheck "int" y) then
  111.                     (match (x, y) with
  112.                         (Int(a),Int(b)) -> Int(pow a b) |
  113.                         (_,_) -> failwith("Match sbagliato"))
  114.               else failwith("Errore di tipo");;
  115.  
  116. let iszero x = if (typecheck "int" x) then
  117.                     (match x with
  118.                         (Int(a)) -> if x = Int(0) then Bool(true) else Bool(false) |
  119.                         (_) -> failwith("Match sbagliato"))
  120.               else failwith("Errore di tipo");;
  121. let meno x = if (typecheck "int" x) then
  122.                     (match x with
  123.                         (Int(a)) -> Int(-a) |
  124.                         (_) -> failwith("Match sbagliato"))
  125.               else failwith("Errore di tipo");;
  126.  
  127. let equiv x y = if (typecheck "int" x && typecheck "int" y) then
  128.                     (match (x, y) with
  129.                         (Int(a),Int(b)) -> Bool(a = b) |
  130.                         (_,_) -> failwith("Match sbagliato"))
  131.               else failwith("Errore di tipo");;
  132.  
  133. let magg x y = if (typecheck "int" x && typecheck "int" y) then
  134.                     (match (x, y) with
  135.                         (Int(a),Int(b)) -> Bool(a > b) |
  136.                         (_,_) -> failwith("Match sbagliato"))
  137.               else failwith("Errore di tipo");;
  138.  
  139. let minn x y = if (typecheck "int" x && typecheck "int" y) then
  140.                     (match (x, y) with
  141.                         (Int(a),Int(b)) -> Bool(a < b)|
  142.                         (_,_) -> failwith("Match sbagliato"))
  143.               else failwith("Errore di tipo");;
  144. let maggu x y = if (typecheck "int" x && typecheck "int" y) then
  145.                     (match (x, y) with
  146.                         (Int(a),Int(b)) -> Bool(a >= b) |
  147.                         (_,_) -> failwith("Match sbagliato"))
  148.               else failwith("Errore di tipo");;
  149. let minu x y = if (typecheck "int" x && typecheck "int" y) then
  150.                     (match (x, y) with
  151.                         (Int(a),Int(b)) -> Bool(a <= b) |
  152.                         (_,_) -> failwith("Match sbagliato"))
  153.               else failwith("Errore di tipo");;
  154. let et x y = if (typecheck "bool" x && typecheck "bool" y) then
  155.                     (match (x, y) with
  156.                         (Bool(a),Bool(b)) -> Bool(a && b) |
  157.                         (_,_) -> failwith("Match sbagliato"))
  158.               else failwith("Errore di tipo");;
  159. let oooh x y = if (typecheck "bool" x && typecheck "bool" y) then
  160.                     (match (x, y) with
  161.                         (Bool(a),Bool(b)) -> (Bool(a || b)) |
  162.                         (_,_) -> failwith("Match sbagliato"))
  163.               else failwith("Errore di tipo");;
  164. let impl x y = if (typecheck "bool" x && typecheck "bool" y) then
  165.                     (match (x, y) with
  166.                         (Bool(a),Bool(b)) -> if (a && not(b)) then Bool(false) else Bool(true) |
  167.                         (_,_) -> failwith("Match sbagliato"))
  168.               else failwith("Errore di tipo");;
  169. let nooh x = if (typecheck "bool" x) then
  170.                 (match x with
  171.                     Bool(a) -> Bool(not(a))
  172.                 | (_) -> failwith("Match sbagliato"))
  173.              else failwith("Errore di tipo");;
  174. let nand x y = if (typecheck "bool" x && typecheck "bool" y) then
  175.                     (match (x, y) with
  176.                         (Bool(a),Bool(b)) -> Bool((not(a)&&not(b)) || (not(a)&&b) || (a&&not(b))) |
  177.                         (_,_) -> failwith("Match sbagliato"))
  178.               else failwith("Errore di tipo");;
  179. let escorr x y = if (typecheck "bool" x && typecheck "bool" y) then
  180.                     (match (x, y) with
  181.                         (Bool(a),Bool(b)) -> Bool(not((a&&b) || (not(a)&&not(b)))) |
  182.                         (_,_) -> failwith("Match sbagliato"))
  183.               else failwith("Errore di tipo");;
  184. (*CREAZIONE DEL FINALMENTE INTERPRETE*)
  185. let rec eval (x:exp) (r: evT env) : evT = match x with
  186.     EInt n -> Int n |
  187.     EBool n -> Bool n |
  188.     EString n -> String n |
  189.     Den n -> applyenv r n |
  190.     Addizione (n,m) -> add(eval n r)(eval m r) |
  191.     Sottrazione (n,m) -> sott(eval n r)(eval m r)|
  192.     Moltiplicazione (n,m) -> molt(eval n r)(eval m r)|
  193.     Divisione (n,m) -> div(eval n r)(eval m r)|
  194.     Maggiore (n,m) -> magg(eval n r)(eval m r)|
  195.     Minore (n,m) -> minn(eval n r)(eval m r)|
  196.     MinoreUg (n,m) -> minu(eval n r)(eval m r)|
  197.     MaggioreUg (n,m) -> maggu(eval n r)(eval m r)|
  198.     Equivalente (n,m) -> equiv(eval n r)(eval m r)|
  199.     Cubo n -> cub (eval n r)|
  200.     Quadrato n -> quad (eval n r)|
  201.     Esp (n,m) -> espon(eval n r)(eval m r)|
  202.     Zero n -> meno (eval n r)|
  203.     Meno n -> meno (eval n r)|
  204.     Not n -> nooh (eval n r)|
  205.     And (n,m) -> et(eval n r)(eval m r)|
  206.     Or (n,m) -> oooh(eval n r)(eval m r)|
  207.     Xor (n,m) -> escorr(eval n r)(eval m r)|
  208.     Nand (n,m) -> nand(eval n r)(eval m r)|
  209.     Impl (n,m) -> impl(eval n r)(eval m r)| (*QUA TI VOGLIO*)
  210.     IfThenElse (cond,thn,els) -> let c = eval cond r in
  211.                                     if c=Bool(true) then eval thn r else eval els r |
  212.     Let (ide,e1,e2) -> eval e2 (bind r ide (eval e1 r))|
  213.     Fun (nomePar,corpoFun) -> Funval (nomePar,corpoFun,r) (*Dichiarazione di funzione (un solo parametro)*)|
  214.     Apply (ambFunDich,valParam) -> (*Devo dichiarare la chiusura della funzione*)
  215.             let chiusura = (eval ambFunDich r) in
  216.                 (match chiusura with (*Guardo che tipo di funzione è, ricorsiva oppure normale*)
  217.                 Funval (paramName,corpFun,ambDich) ->
  218.                     eval corpFun (bind ambDich paramName (eval valParam r)) (*caso di funzione normale, valuto il corpo della funzione con il parametro attuale nell'ambiente di dichiarazione della fnzione stessa*)
  219.                 |RecFunval(nomeFun, (paramName, corpoFun, ambDich)) ->
  220.                     let actVal = (eval valParam r) in (*Valuto il parametro attuale in un ambiente intermedio, nel quale associo il risultato della chiamata precedente e che verrà valutato nella chiamata successiva (fino al caso base se esiste, ma è un problema di chi lo usa non mio)*)
  221.                         let ambFinale = (bind ambDich nomeFun chiusura) in
  222.                             let ambAct = (bind ambFinale paramName actVal) in
  223.                                 eval corpoFun ambAct (* Valuto il corpo della funzione nell'ambiente finale, quello più aggiornato*)
  224.                 | _ -> failwith("Definizione che non è una funzione"))
  225.     |Letrec(nome, defFun, corpoFun) -> (*Questo è il riferimento alla chiusura di una funzione che sarà ricorsiva, ha infatti il nome della funzione a cui punta, la definizione della funzione (Fun) e il corpo del "let", ovvero la chiamata della funzione con un parametro attuale*)
  226.         (match defFun with
  227.             Fun(nomePar, corp) -> let r1 = (bind r nome (RecFunval(nome, (nomePar, corp, r)))) in
  228.                                             eval corpoFun r1
  229.             | _ -> failwith("Definfunzione"));;
  230.    
  231.  
  232.  
  233. (*TEST CASES*)
  234.  
  235. (*Tutte le operazioni booleane YEY*)
  236.  
  237. let funzTest = Fun("y",IfThenElse(MaggioreUg(EInt 5, EInt 6),Let("x",Addizione(EInt 0, EInt 3),Cubo(Den "x")),Quadrato(EInt 5)));;
  238. eval (Apply(funzTest, EInt 7)) emptyenv;;
  239. let gabri = Fun("x", Addizione(Den "x", EInt 1));;
  240. let chiamata = Apply(gabri,(Moltiplicazione(EInt 7, EInt 12)));;
  241. eval chiamata emptyenv;;
  242.  
  243. let trasformaInAssoluto = Fun("x",IfThenElse(MaggioreUg(Den "x", EInt 0),Den "x", Meno(Den "x")));;
  244. let chiamata = Apply(trasformaInAssoluto, EInt (-3));;
  245. eval chiamata emptyenv;;
  246. (*Test dell'IF THEN ELSE (con addizione,sottrazione, maggioreuguale, quadrato, cubo, let funzionanti)*)
  247. let espr1 =
  248. IfThenElse(
  249.     MaggioreUg(
  250.         EInt 5, EInt 6
  251.     ),
  252.     Let(
  253.         "x",
  254.         Addizione(
  255.             EInt 0,
  256.             EInt 3
  257.         ),
  258.         Cubo(
  259.             Den "x"
  260.         )
  261.     ),
  262.     Quadrato(
  263.         EInt 5
  264.     )
  265. );;
  266. eval espr1 emptyenv;;
  267. let espr2 =
  268. IfThenElse(
  269.     MaggioreUg(
  270.         EInt 5, EInt 4
  271.     ),
  272.     Let(
  273.         "x",
  274.         Sottrazione(
  275.             EInt 0,
  276.             EInt 3
  277.         ),
  278.         Cubo(
  279.             Den "x"
  280.         )
  281.     ),
  282.     Quadrato(
  283.         EInt 5
  284.     )
  285. );;
  286. eval espr2 emptyenv;;
  287. (* Test dei booleani *)
  288. let espr3 =
  289. IfThenElse(
  290.     Impl(
  291.         Xor(
  292.             Nand(
  293.                 Not(
  294.                     EBool true
  295.                 ),
  296.                 EBool false
  297.             ),
  298.             Or(
  299.                 And(
  300.                     EBool false,
  301.                     EBool false
  302.                 ),
  303.                 EBool true
  304.             )
  305.         ),
  306.         EBool false
  307.     ),
  308.     EBool true,
  309.     EBool false
  310. );;
  311. eval espr3 emptyenv;;
  312.  
  313. let espr4 =
  314. IfThenElse(
  315.     Impl(
  316.         Xor(
  317.             Nand(
  318.                 Not(
  319.                     EBool true
  320.                 ),
  321.                 EBool false
  322.             ),
  323.             Or(
  324.                 And(
  325.                     EBool false,
  326.                     EBool false
  327.                 ),
  328.                 EBool false
  329.             )
  330.         ),
  331.         EBool false
  332.     ),
  333.     EBool true,
  334.     EBool false
  335. );;
  336. eval espr4 emptyenv;;
  337.  
  338. (*Test FUNZIONI (normali e ricorsive)*)
  339. (*Funzione che dato un parametro mi restituisce il suo doppio diviso per 4 (in intero)*)
  340. let corpoFunzioneAnon =
  341. Fun(
  342.     "x",
  343.     Divisione(
  344.         Moltiplicazione(
  345.             Den "x",
  346.             EInt 2
  347.         ),
  348.         EInt 4
  349.     )
  350. );;
  351. let chiamataFunzAnon =
  352. Apply(
  353.     corpoFunzioneAnon,
  354.     EInt 8
  355. );;
  356. eval chiamataFunzAnon emptyenv;;
  357. (*Funzione del fattoriale, dato un numero restituisce il suo fattoriale*)
  358. let corpF =
  359. Fun(
  360.     "x",
  361.     IfThenElse(
  362.         Equivalente(
  363.             Den "x",
  364.             EInt 0
  365.         ),
  366.         EInt 1,
  367.         Moltiplicazione(
  368.             Den "x",
  369.             Apply(
  370.                 Den "fact",
  371.                 Sottrazione(
  372.                     Den "x",
  373.                     EInt 1
  374.                 )
  375.             )
  376.         )
  377.     )
  378. );;
  379. (*Applico il fattoriale di 5 *)
  380. let fattoriale =
  381. Letrec(
  382.     "fact",
  383.     corpF,
  384.     Apply(
  385.         Den "fact",
  386.         EInt 5
  387.     )
  388. );;
  389.  
  390. eval fattoriale emptyenv;; (*EUREKA*)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement