modification pour Unbound Value les op binaires et les fonctions prédéfini
This commit is contained in:
parent
f13440c6f2
commit
ec2816ddba
1 changed files with 43 additions and 20 deletions
|
@ -105,6 +105,23 @@ let write_block e i v = T.(FunCall (FunId "write_block", [ e; i; v ]))
|
||||||
let read_block e i = T.(FunCall (FunId "read_block", [ e; i ]))
|
let read_block e i = T.(FunCall (FunId "read_block", [ e; i ]))
|
||||||
let lint i = T.(Literal (LInt (Int64.of_int i)))
|
let lint i = T.(Literal (LInt (Int64.of_int i)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(* Liste de fonction prédéfini par le code, que l'on retrouve dans les tests*)
|
||||||
|
let fonction_predef =
|
||||||
|
["print_string";
|
||||||
|
"equal_string";
|
||||||
|
"equal_char";
|
||||||
|
"observe_int";
|
||||||
|
"print_int"]
|
||||||
|
|
||||||
|
(* On regarde si la fonction est prédéfini : soit par des noms, soit par des opérations binaires*)
|
||||||
|
let is_a_predefined_function (S.Id op) =
|
||||||
|
FopixInterpreter.is_binary_primitive op ||
|
||||||
|
List.mem op fonction_predef
|
||||||
|
|
||||||
(** [free_variables e] returns the list of free variables that
|
(** [free_variables e] returns the list of free variables that
|
||||||
occur in [e].*)
|
occur in [e].*)
|
||||||
let free_variables =
|
let free_variables =
|
||||||
|
@ -121,17 +138,15 @@ let free_variables =
|
||||||
| s :: xs -> M.union (f s) (unions f xs)
|
| s :: xs -> M.union (f s) (unions f xs)
|
||||||
in
|
in
|
||||||
(* Une variable libre est une variable qui peut être substitué *)
|
(* Une variable libre est une variable qui peut être substitué *)
|
||||||
|
|
||||||
(* 1.2
|
|
||||||
TODO : rajouter des explications pour While Define et Fun *)
|
|
||||||
let rec fvs = function
|
let rec fvs = function
|
||||||
| S.Literal _ -> M.empty
|
| S.Literal _ -> M.empty
|
||||||
| S.Variable x -> M.singleton x
|
(* Si la fonction est prédéfini, alors ce n'est pas une variable libre. *)
|
||||||
|
| S.Variable x -> if is_a_predefined_function x then M.empty else M.singleton x
|
||||||
| S.While (cond, e) -> unions fvs [ cond; e ]
|
| S.While (cond, e) -> unions fvs [ cond; e ]
|
||||||
| S.Define (vd, a) ->
|
| S.Define (vd, a) ->
|
||||||
let liste_def_valeur =
|
let liste_def_valeur =
|
||||||
match vd with
|
match vd with
|
||||||
| S.SimpleValue (id, expr) -> [ id, expr ]
|
| S.SimpleValue (id, expr) -> [(id, expr)]
|
||||||
| S.RecFunctions list -> list
|
| S.RecFunctions list -> list
|
||||||
in
|
in
|
||||||
let id, expr = List.split liste_def_valeur in
|
let id, expr = List.split liste_def_valeur in
|
||||||
|
@ -204,13 +219,10 @@ let translate (p : S.t) env =
|
||||||
let fs, e = expression (reset_vars env) e in
|
let fs, e = expression (reset_vars env) e in
|
||||||
fs @ [ T.DefineValue (identifier x, e) ]
|
fs @ [ T.DefineValue (identifier x, e) ]
|
||||||
| S.RecFunctions fdefs ->
|
| S.RecFunctions fdefs ->
|
||||||
let fs, defs = define_recursive_functions fdefs in
|
let fs, defs = define_recursive_functions env fdefs in
|
||||||
fs @ List.map (fun (x, e) -> T.DefineValue (x, e)) defs
|
fs @ List.map (fun (x, e) -> T.DefineValue (x, e)) defs
|
||||||
and define_recursive_functions rdefs =
|
and define_recursive_functions env rdefs =
|
||||||
(* 1.5
|
|
||||||
TODO *)
|
|
||||||
(*failwith "Students! This is your job (define_recursive_functions)!"*)
|
|
||||||
|
|
||||||
(*On récupère d'abord les informations qui nous intéresse : nom, variables libres,
|
(*On récupère d'abord les informations qui nous intéresse : nom, variables libres,
|
||||||
arguments, et le corps de la fonction récursive *)
|
arguments, et le corps de la fonction récursive *)
|
||||||
let rdefs =(
|
let rdefs =(
|
||||||
|
@ -274,12 +286,11 @@ let translate (p : S.t) env =
|
||||||
| S.SimpleValue (id, b) ->
|
| S.SimpleValue (id, b) ->
|
||||||
let bfs, b = expression env b in
|
let bfs, b = expression env b in
|
||||||
afs @ bfs, T.Define (identifier id, a, b)
|
afs @ bfs, T.Define (identifier id, a, b)
|
||||||
| S.RecFunctions _ -> failwith "Students! This is your job (S.RecFunctions)!")
|
| S.RecFunctions rdefs ->
|
||||||
|
let fs, defs = define_recursive_functions env rdefs in
|
||||||
|
afs @ fs, defines defs a
|
||||||
|
)
|
||||||
| S.Apply (a, bs) ->
|
| S.Apply (a, bs) ->
|
||||||
(* (* 1.3 (4) *)
|
|
||||||
let afs, a = expression env a in
|
|
||||||
let bsfs, bs = expressions env bs in
|
|
||||||
afs @ bsfs, T.UnknownFunCall (a, bs) *)
|
|
||||||
apply env a bs
|
apply env a bs
|
||||||
| S.IfThenElse (a, b, c) ->
|
| S.IfThenElse (a, b, c) ->
|
||||||
let afs, a = expression env a in
|
let afs, a = expression env a in
|
||||||
|
@ -333,9 +344,16 @@ let translate (p : S.t) env =
|
||||||
and function_identifier (S.Id x) = T.FunId x
|
and function_identifier (S.Id x) = T.FunId x
|
||||||
(* Ici, on rajoute notre fonction anonyme dans la liste des
|
(* Ici, on rajoute notre fonction anonyme dans la liste des
|
||||||
définitions de fonctions *)
|
définitions de fonctions *)
|
||||||
(* Pas sûr pour les T.Id, pareil dans les autres fonctions d'ailleurs *)
|
|
||||||
and add_liste_funcdef env fid x expr =
|
and add_liste_funcdef env fid x expr =
|
||||||
let dfs, expr = expression env expr in
|
let dfs, expr = expression env expr in
|
||||||
|
let dfs, expr =
|
||||||
|
(
|
||||||
|
let aux x (xs, acc) =
|
||||||
|
match x with
|
||||||
|
| T.DefineValue (id, exp) -> xs, T.Define (id,exp,acc)
|
||||||
|
| x -> x::xs, acc in
|
||||||
|
List.fold_right aux dfs ([], expr)
|
||||||
|
) in
|
||||||
dfs @ [ T.DefineFunction (fid, T.Id "oldenvironment" :: x, expr) ]
|
dfs @ [ T.DefineFunction (fid, T.Id "oldenvironment" :: x, expr) ]
|
||||||
|
|
||||||
and fonction_anonyme ?name ?block env f x e =
|
and fonction_anonyme ?name ?block env f x e =
|
||||||
|
@ -367,6 +385,8 @@ let translate (p : S.t) env =
|
||||||
+ la taille de la liste de variable (le nombre de variable libre) *)
|
+ la taille de la liste de variable (le nombre de variable libre) *)
|
||||||
and new_cloture espace list_variable =
|
and new_cloture espace list_variable =
|
||||||
allocate_block (lint (espace + List.length list_variable + 1))
|
allocate_block (lint (espace + List.length list_variable + 1))
|
||||||
|
|
||||||
|
|
||||||
(* Fonction qui rajoute à la cloture l'ensemble de variable libres *)
|
(* Fonction qui rajoute à la cloture l'ensemble de variable libres *)
|
||||||
and add_to_cloture env fname env_var free_vars rdefs =
|
and add_to_cloture env fname env_var free_vars rdefs =
|
||||||
(* On commence d'abord par écrire dans le premier bloc le nom de
|
(* On commence d'abord par écrire dans le premier bloc le nom de
|
||||||
|
@ -420,15 +440,18 @@ let translate (p : S.t) env =
|
||||||
le premier bloc et la suite *)
|
le premier bloc et la suite *)
|
||||||
let instrs = List.rev (env_var :: first_block :: vars_free @ vars_fun) in
|
let instrs = List.rev (env_var :: first_block :: vars_free @ vars_fun) in
|
||||||
seqs instrs, env
|
seqs instrs, env
|
||||||
(* 1.4
|
|
||||||
TODO : Fonction qui s'occupe de S.Apply *)
|
|
||||||
|
|
||||||
|
|
||||||
(* Revoir les explications c'est pas clair *)
|
(* Revoir les explications c'est pas clair *)
|
||||||
and apply env f arguments =
|
and apply env f arguments =
|
||||||
(* D'abord, on traduit chaque arguments *)
|
(* D'abord, on traduit chaque arguments *)
|
||||||
|
|
||||||
let defs_args, trad_arguments = expressions env arguments in
|
let defs_args, trad_arguments = expressions env arguments in
|
||||||
(* On créé un FunCall en fonction de f *)
|
(* On créé un FunCall en fonction de f *)
|
||||||
match f with
|
match f with
|
||||||
| S.Variable x when Dict.lookup x env.externals <> None ->
|
| S.Variable x when Dict.lookup x env.externals <> None || is_a_predefined_function x->
|
||||||
(* Si f est une externe fonction, on créé directement un FunCall *)
|
(* Si f est une externe fonction, on créé directement un FunCall *)
|
||||||
[], T.FunCall (function_identifier x, trad_arguments)
|
[], T.FunCall (function_identifier x, trad_arguments)
|
||||||
| _ ->
|
| _ ->
|
||||||
|
|
Reference in a new issue