exception VariableNonDeclaree;; type expression = Ent of int | Plus of expression * expression | Mult of expression * expression | Div of expression * expression | Moins of expression * expression | Opp of expression | Egal of expression * expression | Sup of expression * expression | Inf of expression * expression | Var of string ;; type instruction = Declaration of string | Affectation of string * expression | Bloc of instruction list | While of expression * instruction | If of expression * instruction | Print of expression | Println | Nord | Sud | Est | Ouest ;; type direction = N | S | E | O;; type variable = {nom: string; mutable valeur: int};; let run p deplacer = let variables = [] in let rec valeur_variable nom vars = match vars with | [] -> raise VariableNonDeclaree | {nom=n; valeur=v}::xs when n = nom -> v | {nom=n; valeur=v}::xs -> valeur_variable nom xs in let rec affecter_variable nom va vars = match vars with | [] -> raise VariableNonDeclaree | c::xs when c.nom = nom -> c.valeur <- va | c::xs -> affecter_variable nom va xs in let declarer_variable nom vars = {nom=nom; valeur=0}::vars in let rec eval expression vars = match expression with | Ent n -> n | Plus (e1, e2) -> (eval e1 vars) + (eval e2 vars) | Mult (e1, e2) -> (eval e1 vars) * (eval e2 vars) | Div (e1, e2) -> (eval e1 vars) / (eval e2 vars) | Moins (e1, e2) -> (eval e1 vars) - (eval e2 vars) | Opp e1 -> (-1) * (eval e1 vars) | Egal (e1, e2) -> (match (eval e1 vars) = (eval e2 vars) with true -> 1 | false -> 0) | Sup (e1, e2) -> (match (eval e1 vars) > (eval e2 vars) with true -> 1 | false -> 0) | Inf (e1, e2) -> (match (eval e1 vars) < (eval e2 vars) with true -> 1 | false -> 0) | Var s -> valeur_variable s vars in let rec exec instruction vars = match instruction with | Declaration s -> declarer_variable s vars | Affectation (s, e) -> affecter_variable s (eval e vars) vars; vars | Print e -> print_int (eval e vars); vars | Println -> print_string "\n"; vars | Bloc [] -> vars | Bloc (i::is) -> exec (Bloc is) (exec i vars) | While (e, i) as w -> (match (eval e vars) with 0 -> vars | _ -> exec w (exec i vars)) | If (e, i) -> (match (eval e vars) with | 0 -> vars | _ -> exec i vars) | Nord -> deplacer N vars | Sud -> deplacer S vars | Est -> deplacer E vars | Ouest -> deplacer O vars in exec p variables ;; "x = 10; while (x < 40) { print x; println; x = x + 10; }";; let test_run () = let () = begin Graphics.open_graph " 400x400"; Graphics.moveto (Graphics.size_x () / 2) (Graphics.size_y () / 2); end in let deplacer direction variables = let aller (x, y) = begin Graphics.rlineto x y; Unix.sleep 1; variables end in match direction with | N -> aller(0, 10) | S -> aller(0, -10) | E -> aller(10, 0) | O -> aller(-10, 0) in let p = Bloc [ Declaration "x"; Affectation ("x", Ent 0); While (Inf (Var "x", Ent 10), Bloc [ Est; Nord; Affectation ("x", Plus (Var "x", Ent 1)) ]); Affectation ("x", Ent 0); While (Inf (Var "x", Ent 10), Bloc [ Nord; Ouest; Affectation ("x", Plus (Var "x", Ent 1)) ]); Affectation ("x", Ent 0); While (Inf (Var "x", Ent 10), Bloc [ Ouest; Sud; Affectation ("x", Plus (Var "x", Ent 1)) ]); Affectation ("x", Ent 0); While (Inf (Var "x", Ent 10), Bloc [ Sud; Est; Affectation ("x", Plus (Var "x", Ent 1)) ]); ] in run p deplacer;; let () = ignore (test_run ()); ignore (read_line()); ;;