(* refactoring -------------------------------------------------------------- *) module IR = struct (* unify var and fn_name as 'global identifiers' *) type uid = string (* Unique identifiers for temporaries. *) type lbl = string type gid = string (* New! global value identifiers *) (* "gensym" -- generate a new unique identifier *) let mk_uid : unit -> uid = let ctr = ref 0 in fun () -> ctr := !ctr + 1; Printf.sprintf "tmp%d" (!ctr) (* operands *) type opn = | Id of uid | Const of int64 (* binary arithmetic operations *) type bop = | Add | Mul (* comparison operations *) type cmpop = | Eq | Lt (* instructions *) (* note that there is no nesting of operations! *) (* pull out the common 'uid' element from these constructors *) type insn = | Binop of bop * opn * opn (* Rename let to binop *) | Load of gid | Store of gid * opn | ICmp of cmpop * opn * opn | Call of gid * (opn list) | Alloca type terminator = | Ret | Br of lbl (* unconditional branch *) | Cbr of opn * lbl * lbl (* conditional branch *) (* Basic blocks *) type block = { insns: (uid * insn) list; terminator: terminator } (* Control Flow Graph: a pair of an entry block and a set labeled blocks *) type cfg = block * (lbl * block) list type gdecl = | GInt of int64 (* The only real change is to "factor out" the name of the function and unify that concept with the "global identifier" names for gdecl. *) type fdecl = { param : uid list; cfg : cfg } type program = { gdecls : (gid * gdecl) list; fdecls : (gid * fdecl) list; } module MLMeaning = struct let add = Int64.add let mul = Int64.mul let load (x : int64 ref) = (!x) let store o (x : int64 ref) = x := o let icmp cmpop x y = cmpop x y let eq (x : int64) (y : int64) = x = y let lt x y = x < y let ret x = x let cbr cnd lbl1 lbl2 = if cnd then lbl1 () else lbl2 () let br lbl = lbl () let alloca () = ref 0L let call f x = f x end end