--- /dev/null
+module List = ListLabels
+
+module Temp = Tiger_temp
+
+type access =
+ | InFrame of {offset_from_frame_pointer : int}
+ | InReg of {register : Temp.Temp.t}
+
+type t =
+(* p.136 Frame.t is a data structure holding:
+ * - the locations of all the formals
+ * - instructions required to implement the "view shift"
+ * - the number of locals allocated so far
+ * - the `label` at which the function's machine code is to begin (see p.140)
+ * *)
+ { name : Temp.Label.t
+ ; formals : access list
+ ; locals_count : int
+ ; instructions : unit (* TODO: instructions for view shift *)
+ }
+
+let name {name; _} =
+ name
+
+let formals {formals; _} =
+ formals
+
+let alloc offset_from_frame_pointer ~escapes =
+ if escapes then
+ InFrame {offset_from_frame_pointer}
+ else
+ InReg {register = Temp.Temp.gen ()}
+
+let alloc_local _ ~escapes =
+ (* FIXME: offset_from_frame_pointer. With neither mutation nor new frame? *)
+ let offset_from_frame_pointer = 0 in
+ alloc offset_from_frame_pointer ~escapes
+
+let make ~name ~formals =
+ (* p.136: For each formal parameter, "newFrame" must calculate two things:
+ * - How the parameter will be seen from inside the function
+ * (in a register, or in a frame location);
+ * - What instructions must be produced to implement the "view shift"
+ * *)
+ let formals, locals_count =
+ (* TODO: What should offset increment be? Word? *)
+ List.fold_left formals ~init:([], 0) ~f:(fun (formals, offset) escapes ->
+ ((alloc offset ~escapes) :: formals, succ offset)
+ )
+ in
+ { name
+ ; formals
+ ; locals_count
+ ; instructions = () (* TODO: instructions for view shift *)
+ }