open Pp

exception PasEncore

type valeur =
  | Vint of int
  | Undefined

type erreur =
  | Inconnue of string
  | DivZero
  | Type of type_expr * valeur
  | PasDef

exception Erreur of erreur

let erreur e = raise (Erreur e)
;;

(* Les environnements *)

type env_t = {
  fonctions : (string * definition) list ;
  globals : (string * valeur ref) list ;
  locals : (string * valeur ref) list
  } 

let trouve_var {globals = glob ; locals = loc } x =
  try List.assoc x loc with
  | Not_found ->
      try List.assoc x glob with
      | Not_found -> erreur (Inconnue ("variable: "^x))


let binop op i1 i2 = match op with
| Plus -> Vint (i1 + i2)
| Minus -> Vint (i1 - i2)
| Times -> Vint (i1 * i2)
| Div ->
    if i2 = 0 then
      erreur DivZero
    else
      Vint (i1/i2)
|  _ -> raise PasEncore


let rec expr env = function
| Int i -> Vint i
| Bin (op,e1, e2) ->  binop op (expr_int env e1) (expr_int env e2) 
| Get x -> !(trouve_var env x)
| _ -> raise PasEncore

and expr_int env e = match expr env e with
| Vint i -> i
| Undefined -> erreur PasDef
| v -> erreur (Type (Integer,v))

and instr env = function
  | Set (x, e) ->
      let xcell = trouve_var env x in
      let v = expr env e in
      xcell := v
  | Sequence is ->
      List.iter (instr env) is
  | Writeln_int e ->
      let i = expr_int env e in
      print_int i ;
      print_newline ()
  | _ -> raise PasEncore

      
let eval
    {global_vars = globs ;
      definitions = defs ;
      main = i} =
  let start_env =
    {globals = List.map (fun (x,_) -> x, ref Undefined) globs ;
      fonctions  = defs ;
      locals = []} in
  instr start_env i

Ce document a été traduit de LATEX par HEVEA.