package pfff

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file ml_to_generic.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
(* Yoann Padioleau
 *
 * Copyright (C) 2019 r2c
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation, with the
 * special exception on linking described in file license.txt.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the file
 * license.txt for more details.
 *)
open Common

open Ast_ml
module G = Ast_generic

(*****************************************************************************)
(* Prelude *)
(*****************************************************************************)
(* Ast_ml to Ast_generic.
 *
 * See ast_generic.ml for more information.
 *)

(*****************************************************************************)
(* Helpers *)
(*****************************************************************************)
let id = fun x -> x
let option = Common.map_opt
let list = List.map

let string = id
let bool = id
let int = id

let error = Ast_generic.error

let fake_info () = Parse_info.fake_info "FAKE"

(*****************************************************************************)
(* Entry point *)
(*****************************************************************************)

let info x = x
let tok v = info v

let wrap = fun _of_a (v1, v2) ->
  let v1 = _of_a v1 and v2 = info v2 in 
  (v1, v2)

let rec ident v = wrap string v

and name (v1, v2) = 
  let v1 = qualifier v1 and v2 = ident v2 in 
  v2, { G.empty_name_info with G.name_qualifier = Some v1 }

and qualifier v = list ident v

and type_ =
  function
  | TyName v1 -> let v1 = name v1 in G.TyApply (v1, [])
  | TyVar v1 -> let v1 = ident v1 in G.TyVar v1
  | TyFunction ((v1, v2)) -> let v1 = type_ v1 and v2 = type_ v2 in 
                             G.TyFun ([v1], v2)
  | TyApp ((v1, v2)) -> let v1 = list type_ v1 and v2 = name v2 in
                        G.TyApply (v2, v1 |> List.map (fun t -> G.TypeArg t))
  | TyTuple v1 -> let v1 = list type_ v1 in G.TyTuple v1

and expr =
  function
  | L v1 -> let v1 = literal v1 in G.L v1
  | Name v1 -> let v1 = name v1 in G.Name (v1, G.empty_id_info ())
  | Constructor ((v1, v2)) ->
      let v1 = name v1 and v2 = option expr v2 in
      G.Constructor (v1, Common.opt_to_list v2)
  | Tuple v1 -> let v1 = list expr v1 in G.Tuple v1
  | List v1 -> let v1 = list expr v1 in G.Container (G.List, v1)
  | Sequence v1 -> let v1 = list expr v1 in G.Seq v1
  | Prefix ((v1, v2)) -> let v1 = wrap string v1 and v2 = expr v2 in
                         let n = v1, G.empty_name_info in
                         G.Call (G.Name (n, G.empty_id_info()), [G.Arg v2])
  | Infix ((v1, v2, v3)) ->
    let n = v2, G.empty_name_info in
    let v1 = expr v1 and v3 = expr v3 in
    G.Call (G.Name (n, G.empty_id_info()), [G.Arg v1; G.Arg v3])

  | Call ((v1, v2)) -> let v1 = expr v1 and v2 = list argument v2 in
                       G.Call (v1, v2)
  | RefAccess ((v1, v2)) -> 
    let _v1 = tok v1 and v2 = expr v2 in
    G.DeRef (v2)
  | RefAssign ((v1, v2, v3)) ->
      let v1 = expr v1 and _v2 = tok v2 and v3 = expr v3 in
      G.Assign (G.DeRef v1, v3)
  | FieldAccess ((v1, v2)) -> 
    let v1 = expr v1 in
    (match v2 with
    | [], id -> let id = ident id in G.ObjAccess (v1, id)
    | _ -> let v2 = name v2 in 
           G.OtherExpr (G.OE_FieldAccessQualified, [G.E v1; G.N v2])
    )
  | FieldAssign ((v1, v2, v3)) ->
      let v1 = expr v1 and v3 = expr v3 in
    (match v2 with
    | [], id -> let id = ident id in G.Assign (G.ObjAccess (v1, id), v3)
    | _ -> let v2 = name v2 in 
           G.Assign (G.OtherExpr (G.OE_FieldAccessQualified, [G.E v1; G.N v2]),
                     v3)
    )
      
  | Record ((v1, v2)) ->
      let v1 = option expr v1
      and v2 =
        list (fun (v1, v2) -> let v2 = expr v2 in
          (match v1 with
          | [], id -> let id = ident id in
                      let ent = G.basic_entity id [] in
                      G.FieldVar (ent, {G.vinit = Some v2; vtype = None})
          | _ -> let v1 = name v1 in
                 let e = 
                   G.OtherExpr (G.OE_FieldAccessQualified, [G.N v1; G.E v2]) in
                 let st = G.ExprStmt e in
                 G.FieldStmt (st)
          )
        )
          v2
      in 
      let obj = G.Record v2 in
      (match v1 with
      | None -> obj
      | Some e -> G.OtherExpr (G.OE_RecordWith, [G.E e; G.E obj])
      )
  | New ((v1, v2)) -> let v1 = tok v1 and v2 = name v2 in 
                      G.Call (G.IdSpecial (G.New, v1), 
                              [G.Arg (G.Name (v2, G.empty_id_info()))])
  | ObjAccess ((v1, v2)) -> let v1 = expr v1 and v2 = ident v2 in
                            G.ObjAccess (v1, v2)
  | LetIn ((v1, v2, v3)) ->
      let _v1 = list let_binding v1
      and _v2 = expr v2
      and _v3 = rec_opt v3
      in 
      raise Todo
  | Fun ((v1, v2)) -> 
    let v1 = list parameter v1 
    and v2 = expr v2 in 
    let def = { G.fparams = v1; frettype = None; fbody = G.ExprStmt v2 } in
    G.Lambda def

  | Nop -> G.Nop
  | If ((v1, v2, v3)) ->
      let v1 = expr v1 and v2 = expr v2 and v3 = expr v3 in 
      G.Conditional (v1, v2, v3)
  | Match ((v1, v2)) ->
      let v1 = expr v1 and v2 = list match_case v2 in
      G.MatchPattern (v1, v2)
  | Try ((v1, v2)) ->
      let v1 = expr v1 and v2 = list match_case v2 in 
      let catches = v2 |> List.map (fun (pat, e) -> pat, G.ExprStmt e) in
      let st = G.Try (G.ExprStmt v1, catches, None) in
      G.OtherExpr (G.OE_StmtExpr, [G.S st])

  | While ((v1, v2)) -> 
    let v1 = expr v1 and v2 = expr v2 in 
    let st = G.While (v1, G.ExprStmt v2) in
    G.OtherExpr (G.OE_StmtExpr, [G.S st])
    
  | For ((v1, v2, v3, v4, v5)) ->
      let v1 = ident v1
      and v2 = expr v2
      and (tok, nextop, condop) = for_direction v3
      and v4 = expr v4
      and v5 = expr v5
      in 
      let ent = G.basic_entity v1 [] in
      let var = { G.vinit = Some v2; vtype = None } in
      let n = G.Name ((v1, G.empty_name_info), G.empty_id_info()) in
      let next = (G.AssignOp (n, (nextop, tok), G.L (G.Int ("1", tok)))) in
      let cond = G.Call (G.IdSpecial (G.ArithOp condop, tok),
                         [G.Arg n; G.Arg v4]) in
      let header = G.ForClassic ([G.ForInitVar (ent, var)],
                                 cond, next) in
      let st = G.For (header, G.ExprStmt v5) in
      G.OtherExpr (G.OE_StmtExpr, [G.S st])
  
and literal =
  function
  | Int v1 -> let v1 = wrap string v1 in G.Int v1
  | Float v1 -> let v1 = wrap string v1 in G.Float v1
  | Char v1 -> let v1 = wrap string v1 in G.Char v1
  | String v1 -> let v1 = wrap string v1 in G.String v1

and argument =
  function
  | Arg v1 -> let v1 = expr v1 in G.Arg v1
  | ArgKwd ((v1, v2)) -> 
    let v1 = ident v1 and v2 = expr v2 in 
    G.ArgKwd (v1, v2)
  | ArgQuestion ((v1, v2)) -> 
    let v1 = ident v1 and v2 = expr v2 in
    G.ArgOther (G.OA_ArgQuestion, [G.Id v1; G.E v2])                          

and match_case (v1, (v2, v3)) =
  let v1 = pattern v1 and v2 = expr v2 and v3 = option expr v3 in
  (match v3 with
  | None -> v1, v2
  | Some x -> G.PatWhen (v1, x), v2
  )

and for_direction =
  function
  | To v1 -> let v1 = tok v1 in v1, G.Plus, G.LtE
  | Downto v1 -> let v1 = tok v1 in v1, G.Minus, G.GtE

and rec_opt v = option tok v

and pattern =
  function
  | PatVar v1 -> let v1 = ident v1 in G.PatVar (v1, G.empty_id_info())
  | PatLiteral v1 -> let v1 = literal v1 in G.PatLiteral v1
  | PatConstructor ((v1, v2)) ->
      let v1 = name v1 and v2 = option pattern v2 in
      G.PatConstructor (v1, Common.opt_to_list v2)
  | PatConsInfix ((v1, v2, v3)) ->
      let v1 = pattern v1 and v2 = tok v2 and v3 = pattern v3 in
      let n = ("::", v2), G.empty_name_info in
      G.PatConstructor (n, [v1;v3])
  | PatTuple v1 -> let v1 = list pattern v1 in 
                   G.PatTuple v1
  | PatList v1 -> let v1 = list pattern v1 in G.PatList v1
  | PatUnderscore v1 -> let v1 = tok v1 in G.PatUnderscore v1
  | PatRecord v1 ->
      let v1 =
        list
          (fun (v1, v2) -> let v1 = name v1 and v2 = pattern v2 in v1, v2) v1
      in 
      G.PatRecord v1
  | PatAs ((v1, v2)) -> 
    let v1 = pattern v1 and v2 = ident v2 in 
    G.PatAs (v1, (v2, G.empty_id_info ()))
  | PatDisj ((v1, v2)) -> 
    let v1 = pattern v1 and v2 = pattern v2 in 
    G.PatDisj (v1, v2)
  | PatTyped ((v1, v2)) -> 
    let v1 = pattern v1 and v2 = type_ v2 in 
    G.PatTyped (v1, v2)

and let_binding =
  function
  | LetClassic v1 -> let _v1 = let_def v1 in raise Todo
  | LetPattern ((v1, v2)) -> let v1 = pattern v1 and v2 = expr v2 in 
                             G.LetPattern (v1, v2)

and let_def { lname = lname; lparams = lparams; lbody = lbody } =
  let _v1 = ident lname in
  let _v2 = list parameter lparams in 
  let _v3 = expr lbody in
  ()

and parameter v = G.ParamPattern (pattern v)
  
and type_declaration { tname = tname; tparams = tparams; tbody = tbody
                     } =
  let v1 = ident tname in
  let v2 = list type_parameter tparams in
  let v3 = type_def_kind tbody in
  let entity = { (G.basic_entity v1 []) with G.tparams = v2 } in
  let def = { G.tbody = v3 } in
  entity, def

and type_parameter v = ident v, []

and type_def_kind =
  function
  | AbstractType -> G.OtherTypeKind (G.OTKO_AbstractType, [])
  | CoreType v1 -> let v1 = type_ v1 in G.AliasType v1
  | AlgebricType v1 ->
      let v1 =
        list
          (fun (v1, v2) ->
             let v1 = ident v1 and v2 = list type_ v2 in 
             G.OrConstructor (v1, v2))
          v1
      in G.OrType v1
  | RecordType v1 ->
      let v1 =
        list
          (fun (v1, v2, v3) ->
             let v1 = ident v1
             and v2 = type_ v2
             and v3 = option tok v3
             in 
             let ent = G.basic_entity v1
               (match v3 with Some _ -> [G.Mutable] | None -> []) in
             G.FieldVar (ent, { G.vinit = None; vtype = Some v2 }))
          v1
      in G.AndType v1
  
and module_declaration { mname = mname; mbody = mbody } =
  let _v1 = ident mname in 
  let _v2 = module_expr mbody in
  ()

and module_expr =
  function
  | ModuleName v1 -> let _v1 = name v1 in ()
  | ModuleStruct v1 -> let _v1 = list item v1 in ()

and item =
  function
  | Type v1 -> let _v1 = list type_declaration v1 in ()

  | Exception ((v1, v2)) ->
      let _v1 = ident v1 and _v2 = list type_ v2 in ()
  | External ((v1, v2, v3)) ->
      let _v1 = ident v1
      and _v2 = type_ v2
      and _v3 = list (wrap string) v3
      in ()
  | Open v1 -> let _v1 = name v1 in ()

  | Val ((v1, v2)) -> let _v1 = ident v1 and _v2 = type_ v2 in ()
  | Let ((v1, v2)) ->
      let _v1 = rec_opt v1 and _v2 = list let_binding v2 in ()

  | Module v1 -> let _v1 = module_declaration v1 in ()

and program xs = List.map item xs
OCaml

Innovation. Community. Security.