From 095b120963d2453ca4a87ba5b38dedac43b178ed Mon Sep 17 00:00:00 2001 From: Nicolas PENELOUX Date: Tue, 7 Nov 2023 20:32:03 +0100 Subject: [PATCH] 34/72, ajout assign/while/define et correction Record --- flap/src/hopix/hopixInterpreter.ml | 73 +++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/flap/src/hopix/hopixInterpreter.ml b/flap/src/hopix/hopixInterpreter.ml index 1695c1e..ad4e961 100644 --- a/flap/src/hopix/hopixInterpreter.ml +++ b/flap/src/hopix/hopixInterpreter.ml @@ -385,7 +385,7 @@ and expression' environment memory e = E, M ⊢ e ⇓ v, M' and E = [runtime.environment], M = [runtime.memory]. *) -and expression _pos environment memory = function +and expression pos environment memory = function | Literal l -> literal_expression l.value | Variable (id, _) -> @@ -393,28 +393,27 @@ and expression _pos environment memory = function Environment.lookup id.position id.value environment | Tagged(constructor,_,list_t) -> (* On ignore le type car on interprète *) - (* TODO *) VTagged(constructor.value, List.map(expression' environment memory) list_t) - | Record(labels,_) -> (* - VRecord(List.map((label_gvalue_pair environment memory) labels))*) - failwith ("oui") + | Record(labels,_) -> + VRecord(List.map((pair_labels_gvalue) (environment) (memory)) labels) - | Field(expr,label,_) -> (* On ignore la liste de type *) - field_value expr label environment memory + | 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*) VUnit | Tuple list_exp -> VTuple (List.map (expression' environment memory) list_exp) + + (*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(list_expr) -> (let vs = List.map (expression' environment memory) list_expr in List.hd (List.rev vs)) | Define(value_def,expr) -> - (* - let new_runtime = environment memory value_def in - expression' (new_runtime.environment new_runtime.memory expr)*) - failwith("TODO") + let runtime = value_definition { environment; memory} value_def in + expression' runtime.environment runtime.memory expr | Fun (FunctionDefinition(pattern,expr)) -> VClosure(environment, pattern, expr) @@ -424,9 +423,9 @@ and expression _pos environment memory = function let dref = expression' environment memory ref in VLocation (Memory.allocate memory Mint.one dref) - | Assign _ -> - (* TODO *) - failwith "Students! This is your job (Assign)!" + | Assign(expr1,expr2) -> (*assign_value expr1 expr2 environment memory*) + failwith ("todo") + | Read read -> let loc = value_as_location (expression' environment memory read) in (match loc with @@ -435,26 +434,56 @@ and expression _pos environment memory = function | Case(expr,branch) -> (*case_value expr branch environment memory*) (* TODO *) failwith "Students! This is your job (Case)!" + | IfThenElse(expr1,expr2,expr3) -> if_then_else_value expr1 expr2 expr3 environment memory - | While _ -> - (* TODO *) - failwith "Students! This is your job (While)!" + + | While(expr1,expr2) -> while_value expr1 expr2 environment memory pos + | For _ -> (* TODO *) failwith "Students! This is your job (For)!" - | TypeAnnotation _ -> + + | TypeAnnotation _ -> VUnit (* On ignore le type car on interprète *) - VUnit (* TODO a finir (à commencer plutôt) and case_value expr branch environment memory = let v = expression' environment memory expr in *) + (* 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 = expression' environment memory expr1 in + + (* On regarde ensuite si*) + match value_as_location vall with + + (*TODO : corriger le bug unit*) + | None -> failwith "erreur" + | Some(v) -> + (let value = expression' environment memory expr2 in + let mem = Memory.dereference(memory) (v) in + Memory.write (mem) Mint.zero (value)) +*) +and pair_labels_gvalue environment memory (lab, expr) = + (Position.value lab, expression' environment memory expr) + +and while_value expr1 expr2 environment memory pos = + let cond = expression' environment memory expr1 in (* On récupère la valeur de la condition *) + match value_as_bool cond with + | true -> + let expr' = expression' environment memory expr2 in + expression pos environment memory (While(expr1,expr2)) + | false -> VUnit + + 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 *) - if value_as_bool cond = true then - expression' environment memory expr2 else (* SI c'est true, alors on évalue la première expression*) - expression' environment memory expr3 (* sinon la deuxième *) + match value_as_bool cond with + | true -> expression' environment memory expr2 + (* SI c'est true, alors on évalue la première expression*) + | false -> expression' environment memory expr3 (* sinon la deuxième *)