84e008c8d1a1b19c71b9f051b3ee98f652ba822a
[wrappi.git] / generator / wrappi_types.ml
1 (* wrappi
2  * Copyright (C) 2011 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *)
18
19 open Camlp4.PreCast
20
21 open Wrappi_utils
22
23 open Printf
24
25 type ptype =
26   | TBool
27   | TBuffer
28   | TEnum of string
29   | TFile
30   | THash of ptype
31   | TInt
32   | TInt32
33   | TInt64
34   | TList of ptype
35   | TNullable of ptype
36   | TString
37   | TStruct of string
38   | TTypedef of string
39   | TUInt32
40   | TUInt64
41   | TUnion of string
42
43 type prec
44
45 type parameter = string * ptype * prec option
46
47 type rtype = RVoid | RStaticString | Return of ptype
48
49 type ftype = rtype * parameter list * parameter list
50
51 type c_code = {
52   cc_loc : Camlp4.PreCast.Loc.t;
53   cc_code : string;
54 }
55
56 type entry_point = {
57   ep_loc : Camlp4.PreCast.Loc.t;
58   ep_local : bool;
59   ep_name : string;
60   ep_ftype : ftype;
61   ep_code : c_code option;
62   ep_includes : string list;
63 }
64
65 type typedef = {
66   td_loc : Camlp4.PreCast.Loc.t;
67   td_name : string;
68   td_type : ptype;
69 }
70
71 type enum = {
72   en_loc : Camlp4.PreCast.Loc.t;
73   en_name : string;
74   en_identifiers : string array;
75 }
76
77 type struct_decl = {
78   sd_loc : Camlp4.PreCast.Loc.t;
79   sd_name : string;
80   sd_fields : (string * ptype) array;
81 }
82
83 type union = {
84   un_loc : Camlp4.PreCast.Loc.t;
85   un_name : string;
86   un_fields : (string * ptype) array;
87 }
88
89 type api = {
90   api_typedefs : typedef StringMap.t;
91   api_enums : enum StringMap.t;
92   api_structs : struct_decl StringMap.t;
93   api_unions : union StringMap.t;
94   api_entry_points : entry_point StringMap.t;
95 }
96
97 let iter xs f =
98   let xs = StringMap.bindings xs in
99   let cmp (a, _) (b, _) = compare a b in
100   let xs = List.sort cmp xs in
101   List.iter (fun (_, x) -> f x) xs
102
103 let iter_typedefs { api_typedefs = tds } f = iter tds f
104 let iter_enums { api_enums = ens } f = iter ens f
105 let iter_structs { api_structs = sds } f = iter sds f
106 let iter_unions { api_unions = uns } f = iter uns f
107 let iter_entry_points { api_entry_points = eps } f = iter eps f
108
109 let rec string_of_ptype = function
110   | TBool -> "bool"
111   | TBuffer -> "buffer"
112   | TEnum name -> sprintf "enum %s" name
113   | TFile -> "file"
114   | THash t -> sprintf "hash(%s)" (string_of_ptype t)
115   | TInt -> "int"
116   | TInt32 -> "int32"
117   | TInt64 -> "int64"
118   | TList t -> sprintf "list(%s)" (string_of_ptype t)
119   | TNullable t -> sprintf "nullable(%s)" (string_of_ptype t)
120   | TString -> "string"
121   | TStruct name -> sprintf "struct %s" name
122   | TTypedef name -> name
123   | TUInt32 -> "uint32"
124   | TUInt64 -> "uint64"
125   | TUnion name -> sprintf "union %s" name
126 let string_of_rtype = function
127   | RVoid -> "void"
128   | RStaticString -> "static_string"
129   | Return t -> string_of_ptype t
130 let string_of_parameter (name, t, _) =
131   sprintf "%s %s" (string_of_ptype t) name
132 let string_of_parameters params =
133   sprintf "(%s)" (String.concat ", " (List.map string_of_parameter params))
134 let string_of_ftype (ret, req, opt) =
135   sprintf "%s %s %s"
136     (string_of_rtype ret) (string_of_parameters req) (string_of_parameters opt)
137 let string_of_c_code code = code.cc_code
138
139 let string_of_typedef td =
140   sprintf "typedef %s %s" td.td_name (string_of_ptype td.td_type)
141
142 let string_of_enum en =
143   sprintf "enum %s {%s}" en.en_name
144     (String.concat ", " (Array.to_list en.en_identifiers))
145
146 let string_of_struct sd = assert false
147 let string_of_union un = assert false
148
149 let string_of_entry_point ep =
150   sprintf "entry_point%s %s %s <<%s>>"
151     (*(Loc.to_string ep.ep_loc)*)
152     (if ep.ep_local then " local" else "")
153     ep.ep_name
154     (string_of_ftype ep.ep_ftype)
155     (match ep.ep_code with
156     | None -> "/* implicit */"
157     | Some code -> string_of_c_code code)