type valeur = | Vint of int | Vbool of bool | Varray of valeur array | Undefined |
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)) |
Not_found
lorsque qu'il n'y a pas de paire
(x,...)
dans la liste et de se servir de ce fait.
and extend x v env = {env with locals = (x,ref v) :: env.locals} |
let rec expr env = function | Int i -> Vint i and instr env = function | Set (x,e) -> ... |
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 |
expr_int
:
let expr env = function ... 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 ... |
let expr env = function ... | Geti (et, ei) -> let vt = expr_array env et in let vi = expr_int env ei in vt.(vi) ... |
let binop op i1 i2 = match op with | Plus -> Vint (i1 + i2) | ... let expr env = function ... | Binop (op, e1, e2) -> binop op (expr_int env e1) (expr_int env e2) |
call_env
).
Il s'agit de renvoyer l'environnement global étendu par les nouvelles
liaisons des variables locales à Undefined ; et des noms des
arguments (paramètres dits formels) à la valeur de l'argument
correspondant (paramètres dits effectifs) :
and env_locs env = function | [] -> env | (x,_) :: reste -> extend x Undefined (env_locs env reste) and env_args env f xs es = match xs,es with | [],[] -> take_globs env | (x,t)::xs, e::es -> let v = expr env e in extend x v (env_args env f xs es) | _ -> erreur (NumArgs f) and call_env env f fdef es = env_locs (env_args env f fdef.arguments es) fdef.local_vars |
env_args
.
function fact (x : integer) : integer begin ... fact := ... end |
let rec expr env = function ... | Function_call (f,e_args) -> let fdef = trouve_fun env f in let new_env = extend f Undefined (* variable re'sultat *) (call_env env f fdef e_args) in ... |
instr new_env fdef.body ; |
let fcell = trouve_var new_env f in (* recuperer le re'sultat *) !fcell |
expr_int
, expr_bool
, etc.),
par exemple pour tester une condition (booléen) ou accéder à un
tableau (type tableau et entier).Ce document a été traduit de LATEX par HEVEA.