type address = Gen.temp (* Dans un contexte plus général, les variables qui s'échappent seraient allouées en pile *) type frame = { name : Gen.label; return_label : Gen.label; args : address list; result : address option; mutable locals : int; mutable no_local_yet : bool; } let frame start stop args return = { name = start; return_label = stop; args = List.map (fun x -> Gen.new_temp()) args; result = (match return with Some _ -> Some (Gen.new_temp()) | _ -> None); locals = 0; no_local_yet = true; } let new_frame x = frame (Gen.new_label()) (Gen.new_label()) x;; (* NOTE: dans la prochaine version, fournir une interface similarire aux primitives, i.e. reçoit deux paramètres de type int (nombre d'arguments) et bool (fonction ou procédure). *) let named_frame name = let start = Gen.prefixed_label name in let stop = Gen.prefixed_label (name^"_end") in frame start stop ;; let frame_args f = f.args let frame_name f = f.name let frame_result f = f.result let frame_return f = f.return_label let frame_size f = f.locals;; let frame_size_label f = Gen.label_string f.name^"_f" let stupid_label = Gen.new_label();; let new_primitive s args return = let dummy = Gen.new_temp() in { name = Gen.named_label s; return_label = stupid_label; args = Array.to_list (Array.create args dummy); result = if return then Some dummy else None; no_local_yet = false; locals = 0 } (* taille du mot *) let wordsize = 4;; (* allocation d'un espace en pile *) let alloc_local f = let n = f.locals in f.no_local_yet <- false; f.locals <- f.locals + wordsize; n;; let make_space_for_args f n = assert f.no_local_yet; f.locals <- max f.locals (n * wordsize);; (* primitives *) let write_int = new_primitive "print_int" 1 false;; let writeln_int = new_primitive "println_int" 1 false;; let read_int = new_primitive "read_int" 0 true;; let alloc = new_primitive "alloc" 1 true;; (* adresses globales *) let global_space = Gen.named_label "Glob";;