Begin translation module
[tiger.ml.git] / compiler / src / lib / tiger / tiger_translate.ml
1 module List = ListLabels
2
3 module Frame = Tiger_frame
4 module Temp = Tiger_temp
5 module T = Tiger_tree
6
7 module Level = struct
8 type t =
9 { parent : t option
10 ; name : Temp.Label.t
11 ; formals : bool list
12 ; frame : Frame.t
13 }
14
15 let init =
16 let name = Temp.Label.gen () in
17 let formals = [] in
18 { parent = None
19 ; name
20 ; formals
21 ; frame = Frame.make ~name ~formals
22 }
23
24 let next t ~name ~formals =
25 (* Adding the extra parameter for the static link. See p. 142 *)
26 let formals = true :: formals in
27 { parent = Some t
28 ; name
29 ; formals
30 ; frame = Frame.make ~name ~formals
31 }
32
33 let formals = function {formals; _} ->
34 formals
35
36 let frame = function {frame; _} ->
37 frame
38 end
39
40 type gen_stm =
41 (Tiger_temp.Label.t * Tiger_temp.Label.t) -> Tiger_tree.stm
42
43 type exp =
44 | Ex of Tiger_tree.exp
45 | Nx of Tiger_tree.stm
46 | Cx of gen_stm
47
48 type access =
49 (* must know about static links *)
50 { level : Level.t
51 ; frame_access : Frame.access
52 }
53
54 let alloc_local ~level ~escapes =
55 { level
56 ; frame_access = Frame.alloc_local (Level.frame level) ~escapes
57 }
58
59 let formals ~level =
60 (* FIXME: This seems wrong. Should we call Frame.formals? *)
61 List.map (Level.formals level) ~f:(fun escapes ->
62 alloc_local ~level ~escapes
63 )
64
65 let rec seq = function
66 (* TODO: Is appending 0 OK? How else can the empty case be handled? *)
67 | [] -> T.EXP (T.CONST 0)
68 | s :: ss -> T.SEQ (s, seq ss)
69
70 let cond_stm gen_stm =
71 let t = Temp.Label.gen () in
72 let f = Temp.Label.gen () in
73 let r = Temp.Temp.gen () in
74 let stms =
75 [ T.MOVE (T.TEMP r, T.CONST 1)
76 ; gen_stm (t, f)
77 ; T.LABEL f
78 ; T.MOVE (T.TEMP r, T.CONST 0)
79 ; T.LABEL t
80 ]
81 in
82 (seq stms, T.TEMP r)
83
84 let unEx = function
85 | Ex exp -> exp
86 | Nx stm -> T.ESEQ (stm, T.CONST 0)
87 | Cx gen ->
88 let stm, exp = cond_stm gen in
89 T.ESEQ (stm, exp)
90
91 let unNx = function
92 | Ex exp -> T.EXP exp
93 | Nx stm -> stm
94 | Cx gen -> fst (cond_stm gen)
95
96 let unCx = function
97 (* "should never occur in compiling a well typed Tiger program" p.154 *)
98 | Nx _ -> assert false
99 | Ex e -> fun (_, _) -> T.EXP e (* TODO: Is this right? *)
100 | Cx g -> g
101
102 let dummy__FIXME = Ex (T.CONST 0)
This page took 0.07176 seconds and 4 git commands to generate.