diff --git a/flap/src/hopix/hopixInterpreter.ml b/flap/src/hopix/hopixInterpreter.ml index 9a6f500..5b7f9fc 100644 --- a/flap/src/hopix/hopixInterpreter.ml +++ b/flap/src/hopix/hopixInterpreter.ml @@ -344,7 +344,7 @@ and definition runtime d = and value_definition runtime = function | SimpleValue (id, _, expr) -> (* Ici on associe l'ID et l'expression - * => Retourne l'environnement modifié *) + => Retourne l'environnement modifié *) let env' = Environment.bind runtime.environment @@ -354,14 +354,13 @@ and value_definition runtime = function { runtime with environment = env' } | RecFunctions rf -> (* Ici on ajoute les noms des fonctions à l'environnement - * pour qu'elles puissent s'appeller dans leur corps de fonction - * => Retourne l'environnement modifié *) - (* TODO *) + pour qu'elles puissent s'appeller dans leur corps de fonction + => Retourne l'environnement modifié *) { runtime with environment = define_rec runtime.environment rf } and define_rec env rf = (* Ajoute les fonctions récursives dans l'environnement - * par défaut on dit qu'elle renvoie Unit *) + par défaut on dit qu'elle renvoie Unit *) let env' = List.fold_left (fun curr_env (id, _, _) -> Environment.bind curr_env id.value VUnit) @@ -369,7 +368,7 @@ and define_rec env rf = rf in (* On associe les fonctions avec leur contenu en ignorant le type via - * une closure en les rajoutant à l'environnement *) + une closure en les rajoutant à l'environnement *) List.iter ((fun env'' (name, _, FunctionDefinition (pattern, expr)) -> Environment.update name.position name.value env'' (VClosure (env'', pattern, expr))) @@ -394,67 +393,68 @@ and expression pos environment memory = function | Record (labels, _) -> VRecord (List.map (pair_labels_gvalue environment memory) labels) | Field (expr, label, _) -> - field_value expr label environment memory (* On ignore la liste de type *) - | Tuple [] -> (* Cas pour le Tuple vide. Un tuple vide ne contient rien (logique), donc on utilise un VUnit*) + (* On ignore la liste de type *) + field_value expr label environment memory + | Tuple [] -> + (* Cas pour le Tuple vide. Un tuple vide ne contient rien (logique), + donc on utilise un VUnit *) VUnit - | Tuple list_expr -> - tuple_value list_expr environment memory - | Sequence list_expr -> - sequence_value list_expr environment memory - | Define (value_def, expr) -> - define_value value_def expr environment memory + | Tuple list_expr -> tuple_value list_expr environment memory + | Sequence list_expr -> sequence_value list_expr environment memory + | Define (value_def, expr) -> define_value value_def expr environment memory | Fun (FunctionDefinition (pattern, expr)) -> VClosure (environment, pattern, expr) | Apply (f, x) -> apply_expression f x environment memory | Ref ref -> ref_value ref environment memory | Assign (expr1, expr2) -> - assign_value expr1 expr2 environment memory; VUnit + assign_value expr1 expr2 environment memory; + VUnit | Read read -> read_value read environment memory - | Case (expr, branches) -> - case_value expr branches environment memory + | Case (expr, branches) -> case_value expr branches environment memory | IfThenElse (expr1, expr2, expr3) -> if_then_else_value expr1 expr2 expr3 environment memory | While (expr1, expr2) -> while_value expr1 expr2 environment memory pos | For (id, expr1, expr2, expr3) -> for_value id expr1 expr2 expr3 environment memory - | TypeAnnotation _ -> VUnit -(* On ignore le type car on interprète *) + | TypeAnnotation _ -> + (* On ignore le type car on interprète *) + VUnit -(* Variable : On cherche la variable dans l'environnement *) -and variable_value id environment = - Environment.lookup id.position id.value environment +(** Variable: On cherche la variable dans l'environnement *) +and variable_value id environment = Environment.lookup id.position id.value environment - (* Tuple : On applique à chaque expression de la liste l'opération de calcul de sa valeur *) -and tuple_value list_expr environment memory = +(** Tuple: On applique à chaque expression de la liste l'opération de calcul de sa valeur *) +and tuple_value list_expr environment memory = VTuple (List.map (expression' environment memory) list_expr) -(* Sequence : on evalue chaque expression, - * puis on récupère la dernière à avoir été évalué. - * Le dernier élément se trouve facilement en faisant un reverse de liste - * et en récupérant la tête. *) +(** Sequence: on evalue chaque expression, + puis on récupère la dernière à avoir été évalué. + Le dernier élément se trouve facilement en faisant un reverse de liste + et en récupérant la tête. *) and sequence_value list_expr environment memory = let vs = List.map (expression' environment memory) list_expr in - List.hd (List.rev vs) + List.hd (List.rev vs) -(*Define : On évalue la définition local puis on en fait un nouveau runtime et on calcule la valeur de l'expression. *) +(** Define: On évalue la définition local puis on en fait un nouveau runtime et + on calcule la valeur de l'expression. *) and define_value value_def expr environment memory = let runtime = value_definition { environment; memory } value_def in - expression' runtime.environment runtime.memory expr + expression' runtime.environment runtime.memory expr -(* Reference : On alloue de la mémoire pour le résultat du calcul de l'expression *) +(** Reference: On alloue de la mémoire pour le résultat du calcul de l'expression *) and ref_value ref environment memory = - let dref = expression' environment memory ref in - VLocation (Memory.allocate memory Mint.one dref) + let dref = expression' environment memory ref in + VLocation (Memory.allocate memory Mint.one dref) -(* Lecture : On va lire l'espace mémoire *) -and read_value read environment memory = +(** Lecture: On va lire l'espace mémoire *) +and read_value read environment memory = let loc = value_as_location (expression' environment memory read) in - (match loc with - | Some adr -> - Memory.read (Memory.dereference memory adr) Mint.zero - (* On lis la valeur de la mémoire *) - | None -> error [position read] "Erreur read") - -(* Case : On effectue le pattern matching des branches associés à notre case, - * et on renvoie l'environnement modifié après avoir calculer toute les branches. *) + match loc with + | Some adr -> + Memory.read (Memory.dereference memory adr) Mint.zero + (* On lis la valeur de la mémoire *) + | None -> error [ position read ] "Erreur read" + +(** Case: On effectue le pattern matching des branches associés à notre case, + et on renvoie l'environnement modifié après avoir calculer toute les branches. *) and case_value expr branches environment memory = (* On calcule d'abord l'expression *) let expr' = expression' environment memory expr in @@ -478,17 +478,20 @@ and case_value expr branches environment memory = | [] -> error [ expr.position ] "erreur" | _ as env -> List.hd env - (* For : On va calculer les valeurs de l'expression (ici expr3) à chaque itération de la boucle *) +(** For: On va calculer les valeurs de l'expression (ici expr3) + à chaque itération de la boucle *) and for_value id expr1 expr2 expr3 environment memory = let borne_inf = value_as_int (expression' environment memory expr1) in let borne_sup = value_as_int (expression' environment memory expr2) in match borne_inf, borne_sup with - (* On regarde que les borne_inf et borne_sup ont bien une valeur d'entier *) - (* Si c'est le cas, alors nous sommes bien dans une boucle for et on effectue ses opérations *) + (* On regarde que les borne_inf et borne_sup ont bien une valeur d'entier + Si c'est le cas, alors nous sommes bien dans une boucle for et on effectue + ses opérations *) | Some borne_inf, Some borne_sup -> boucle_for id borne_inf borne_sup expr3 environment memory - (* On appelle une seconde fonction car pour évalué la boucle for, il faudra rappeler la boucle - en augmentant l'indice de la borne inférieur de 1 à chaque appelle. *) + (* On appelle une seconde fonction car pour évalué la boucle for, il faudra + rappeler la boucle en augmentant l'indice de la borne inférieur de 1 + à chaque appelle. *) | _ -> error [ expr1.position; expr2.position ] "erreur" and boucle_for id borne_inf borne_sup expr3 environment memory = @@ -502,12 +505,11 @@ and boucle_for id borne_inf borne_sup expr3 environment memory = boucle_for id (Mint.add borne_inf Mint.one) borne_sup expr3 env' memory) else VUnit (* Cas où nous ne sommes plus dans la boucle, on renvoie un VUnit *) -(* Assign *) -(* On commence par récupérer l'évaluation de expr1, qui correspond à la valeur - * à laquelle est affecté expr2 *) +(** Assign: On commence par récupérer l'évaluation de expr1, qui correspond à la valeur + à laquelle est affecté expr2 *) and assign_value expr1 expr2 environment memory = let vall = value_as_location (expression' environment memory expr1) in - (* On regarde ensuite si*) + (* On regarde ensuite si *) match vall with | None -> error [ expr1.position; expr2.position ] "erreur assign" | Some v -> assign_calcul environment memory expr2 v @@ -517,9 +519,11 @@ and assign_calcul environment memory expr2 v = let mem = Memory.dereference memory v in Memory.write mem Mint.zero value +(** While: Tant que la condition (valeur de l'expression 1) est true, + alors on calcule l'expression de expression 2 -(*While : Tant que la condition (valeur de l'expression 1) est true, alors on calcule l'expression de expression 2 - Sinon, on renvoie un VUnit, qui va stopper le processus d'interprétation pour While. *) + Sinon, on renvoie un VUnit, qui va stopper le processus d'interprétation + pour While. *) and while_value expr1 expr2 environment memory pos = let cond = expression' environment memory expr1 in (* On récupère la valeur de la condition *) @@ -529,8 +533,9 @@ and while_value expr1 expr2 environment memory pos = expression pos environment memory (While (expr1, expr2)) | false -> VUnit -(* IfThenELse : Comme pour While, on regarde si la condition est vrai, si c'est le cas, - alors on calcule l'expression du "then", sinon celle du "else" *) +(** IfThenELse: Comme pour While, on regarde si la condition est vrai, + si c'est le cas, alors on calcule l'expression du "then", + sinon celle du "else" *) and if_then_else_value expr1 expr2 expr3 environment memory = let cond = expression' environment memory expr1 in (* On récupère la valeur de la condition *) @@ -540,18 +545,18 @@ and if_then_else_value expr1 expr2 expr3 environment memory = (* Si c'est true, alors on évalue la première expression *) | false -> expression' environment memory expr3 (* sinon la deuxième *) - (* Record : on calcule l'expression, et on associe à chaque élément de la liste la valeur du label *) +(** Record: on calcule l'expression, et on associe à chaque élément + de la liste la valeur du label *) and field_value expr label environment memory = match expression' environment memory expr with | VRecord record -> List.assoc label.value record | _ -> assert false (* Cas où il n'y a pas de record, donc c'est une erreur *) - (* Fonction annexe qui renverra une paire label * valeur de expression *) +(** Fonction annexe qui renverra une paire label * valeur de expression *) and pair_labels_gvalue environment memory (lab, expr) = Position.value lab, expression' environment memory expr - -(* Apply : on applique la fonction f à x en fonction des différents cas possibles *) +(** Apply: On applique la fonction f à x en fonction des différents cas possibles *) and apply_expression f x environment memory = let x_val = expression' environment memory x in match expression' environment memory f with @@ -567,19 +572,14 @@ and apply_expression f x environment memory = | None -> failwith "erreur") | _ -> assert false (* By typing *) -(* Littéraux *) +(** Littéraux *) and literal_expression = function | LInt n -> VInt n | LChar c -> VChar c | LString s -> VString s - - - - (* --------------- PATTERN MATCHING ----------------- *) - and pattern environment pat expression = match pat, expression with | PWildcard, _ -> wildcard_pattern environment @@ -595,14 +595,16 @@ and pattern environment pat expression = | PAnd pl, _ -> and_pattern environment pl expression | _ -> None -(* PWildcard : on renvoie l'environnement sans modification *) -and wildcard_pattern environment = Some environment -(* PVariable : On bind la valeur de la variable ) l'expression dans l'environnement *) +(** PWildcard: On renvoie l'environnement sans modification *) +and wildcard_pattern environment = Some environment + +(** PVariable: On bind la valeur de la variable - l'expression dans l'environnement *) and variable_pattern var env expression = Some (Environment.bind env var.value expression) -(* PTypeAnnotation : On calcule le pattern à son tour *) + +(** PTypeAnnotation: On calcule le pattern à son tour *) and typeannot_pattern pattern' env expression = pattern env pattern' expression -(* PLiteral : On regarde si la valeur du pattern correspond à celle de l'expression *) +(** PLiteral: On regarde si la valeur du pattern correspond à celle de l'expression *) and literal_pattern pl environment expression = let valeur_literal = pl.value in let verif_literal l1 l2 = if l1 = l2 then Some environment else None in @@ -612,37 +614,38 @@ and literal_pattern pl environment expression = | LString str1, VString str2 -> verif_literal str1 str2 | _ -> None - (* PTagged : On regarde si les deux constructeurs sont égaux, si c'est le cas on calcule - comme si c'était un PTuple, les deux listes de patterns que nous avons *) +(** PTagged: On regarde si les deux constructeurs sont égaux, si c'est le cas + on calcule comme si c'était un PTuple, les deux listes de patterns que + nous avons *) and tagged_pattern cons1 cons2 pattern1 pattern2 environment = if cons1.value = cons2 then tuple_pattern environment pattern1 pattern2 else None - (*PRecord On compare les deux records, on essaye de trouver un match pour chaque field - (du premier record) dans le deuxième record, si c'est le cas on met à jour l'env, sinon - On regarde le prochain élément. *) +(** PRecord: On compare les deux records, on essaye de trouver un match pour + chaque field (du premier record) dans le deuxième record, si c'est le cas + on met à jour l'env, sinon on regarde le prochain élément. *) and record_pattern environment r r' = match r with | [] -> Some environment | field :: reste -> - let labbel_pattern = record_labbel_pattern environment field r' in - match labbel_pattern with - | Some env' -> record_pattern env' reste r' - | None -> None - + let labbel_pattern = record_label_pattern environment field r' in + (match labbel_pattern with + | Some env' -> record_pattern env' reste r' + | None -> None) - and record_labbel_pattern environment field r' = - match r' with - | [] -> None - | (label,pat) :: reste -> - if (value (fst field)) = label then - match pattern environment (value (snd field)) pat with - | Some env' -> Some env' - | None -> record_labbel_pattern environment field reste - else - record_labbel_pattern environment field reste +(* Auxillaire *) +and record_label_pattern environment field r' = + match r' with + | [] -> None + | (label, pat) :: reste -> + if value (fst field) = label + then ( + match pattern environment (value (snd field)) pat with + | Some env' -> Some env' + | None -> record_label_pattern environment field reste) + else record_label_pattern environment field reste -(* PTuple : On a deux tuples, qui pour chaque pair d'éléments effectue un pattern matching, et -renvoie le nouvel environnement *) +(** PTuple: On a deux tuples, qui pour chaque pair d'éléments effectue + un pattern matching, et renvoie le nouvel environnement *) and tuple_pattern environment tab tab2 = if List.length tab = List.length tab2 then ( @@ -656,7 +659,8 @@ and tuple_pattern environment tab tab2 = | _ -> None) else None -(* POr : Renvoie le nouvelle environnement si au moins un des patterns match avec l'expression*) +(** Por: Renvoie le nouvelle environnement si au moins un des + patterns match avec l'expression *) and or_pattern env pl expression = match pl with | [] -> None @@ -666,7 +670,8 @@ and or_pattern env pl expression = | Some env' -> Some env' | None -> or_pattern env pl' expression) - (* PAnd : de même, mais chaque élément de la liste des patterns doivent matchs avec l'expression*) +(** PAnd: De même, mais chaque élément de la liste des patterns doivent + matchs avec l'expression *) and and_pattern env pl expression = match pl with | [] -> Some env @@ -676,18 +681,6 @@ and and_pattern env pl expression = | None -> None | Some env' -> and_pattern env' pl' expression) - - - - - - - - - - - - (** This function returns the difference between two runtimes. *) and extract_observable runtime runtime' = let rec substract new_environment env env' =