5
5
6
6
use JSON::XS qw( decode_json) ;
7
7
8
- my %TYPEMAP = (
8
+ my %TYPE_MAP = (
9
9
' unsigned-int' => ' uint' ,
10
10
' unsigned-char' => ' uint8' ,
11
11
' signed-char' => ' int8' ,
17
17
' unsigned-long-long' => ' (ulong-long-type)' ,
18
18
);
19
19
20
- my %SCMAP = (
21
- ' static' => ' intern' ,
22
- ' none' => ' extern-c' ,
23
- ' extern' => ' extern-c' ,
24
- );
25
-
26
20
sub type_to_string
27
21
{
28
- my ($type ) = @_ ;
22
+ my ($type , $imports ) = @_ ;
29
23
30
24
my $tag = $type -> {' tag' };
31
25
if ($tag =~ / ^:/ ) {
32
26
$tag =~ s / ^:// ;
33
27
}
34
28
35
29
if ($tag eq ' pointer' ) {
36
- return " (p " .(type_to_string($type -> {' type' }))." )" ;
30
+ return " (p " .(type_to_string($type -> {' type' }, $imports ))." )" ;
37
31
}
38
32
if ($tag eq ' array' ) {
39
33
return " (array-of " .$type -> {' size' }." " .
40
- (type_to_string($type -> {' type' }))." )" ;
34
+ (type_to_string($type -> {' type' }, $imports ))." )" ;
41
35
}
42
36
if ($tag eq ' struct' ) {
43
37
return $type -> {' name' };
44
38
}
45
39
if ($tag eq ' bitfield' ) {
46
- my $bf_type = type_to_string($type -> {' type' });
40
+ my $bf_type = type_to_string($type -> {' type' }, $imports );
47
41
return sprintf (" (bf %s %s )" ,
48
42
$bf_type ,
49
43
$type -> {' width' });
@@ -52,8 +46,11 @@ sub type_to_string
52
46
return $type -> {' name' };
53
47
}
54
48
55
- my $mapped_type = $TYPEMAP {$tag };
49
+ my $mapped_type = $TYPE_MAP {$tag };
56
50
if ($mapped_type ) {
51
+ if ($mapped_type =~ / ^\( / ) {
52
+ $imports -> {' stdlib' } = 1;
53
+ }
57
54
return $mapped_type ;
58
55
}
59
56
@@ -62,26 +59,33 @@ sub type_to_string
62
59
63
60
sub type_to_flat_string
64
61
{
65
- my ($type ) = @_ ;
62
+ my ($type , $imports ) = @_ ;
66
63
67
- my $str = type_to_string($type );
64
+ my $str = type_to_string($type , $imports );
68
65
$str =~ tr / () / / ;
69
66
$str =~ s / // g ;
70
67
71
68
return $str ;
72
69
}
73
70
71
+ my %SC_MAP = (
72
+ ' static' => ' intern' ,
73
+ ' none' => ' extern-c' ,
74
+ ' extern' => ' extern-c' ,
75
+ );
76
+
74
77
sub storage_class_to_string
75
78
{
76
- return $SCMAP {$_ [0]};
79
+ return $SC_MAP {$_ [0]};
77
80
}
78
81
79
82
sub process_function
80
83
{
81
- my ($data ) = @_ ;
84
+ my ($data , $imports ) = @_ ;
82
85
83
86
my @params =
84
- map { sprintf (" (%s %s )" , $_ -> {' name' }, type_to_string($_ -> {' type' })) }
87
+ map { sprintf (" (%s %s )" , $_ -> {' name' },
88
+ type_to_string($_ -> {' type' }, $imports )) }
85
89
@{$data -> {' parameters' }};
86
90
if (not @params ) {
87
91
@params = ' void' ;
@@ -92,34 +96,35 @@ sub process_function
92
96
$data -> {' name' },
93
97
storage_class_to_string($data -> {' storage_class' }
94
98
|| $data -> {' storage-class' }),
95
- type_to_string($data -> {' return-type' }),
99
+ type_to_string($data -> {' return-type' }, $imports ),
96
100
$param_str );
97
101
}
98
102
99
103
sub process_variable
100
104
{
101
- my ($data ) = @_ ;
105
+ my ($data , $imports ) = @_ ;
102
106
103
107
sprintf (" (def %s (var extern %s ))" ,
104
108
$data -> {' name' },
105
- type_to_string($data -> {' type' }));
109
+ type_to_string($data -> {' type' }, $imports ));
106
110
}
107
111
108
112
sub process_const
109
113
{
110
- my ($data ) = @_ ;
114
+ my ($data , $imports ) = @_ ;
111
115
112
116
sprintf (" (def %s (var intern %s ))" ,
113
117
$data -> {' name' },
114
- type_to_string($data -> {' type' }));
118
+ type_to_string($data -> {' type' }, $imports ));
115
119
}
116
120
117
121
sub process_struct
118
122
{
119
- my ($data ) = @_ ;
123
+ my ($data , $imports ) = @_ ;
120
124
121
125
my @fields =
122
- map { sprintf (" (%s %s )" , $_ -> {' name' }, type_to_string($_ -> {' type' })) }
126
+ map { sprintf (" (%s %s )" , $_ -> {' name' },
127
+ type_to_string($_ -> {' type' }, $imports )) }
123
128
@{$data -> {' fields' }};
124
129
my $field_str = (@fields ? " (" .(join ' ' , @fields )." )" : " " );
125
130
@@ -130,7 +135,7 @@ sub process_struct
130
135
131
136
sub process_enum
132
137
{
133
- my ($data ) = @_ ;
138
+ my ($data , $imports ) = @_ ;
134
139
135
140
my @fields =
136
141
map { sprintf (" (%s %s )" , $_ -> {' name' }, $_ -> {' value' }) }
@@ -144,24 +149,26 @@ sub process_enum
144
149
145
150
sub process_typedef
146
151
{
147
- my ($data ) = @_ ;
152
+ my ($data , $imports ) = @_ ;
148
153
149
154
sprintf (" (def %s (struct extern ((a %s ))))" ,
150
155
$data -> {' name' },
151
- type_to_string($data -> {' type' }));
156
+ type_to_string($data -> {' type' }, $imports ));
152
157
}
153
158
154
159
sub process_union
155
160
{
156
- my ($data ) = @_ ;
161
+ my ($data , $imports ) = @_ ;
162
+
163
+ $imports -> {' variant' } = 1;
157
164
158
165
my $name = $data -> {' name' };
159
166
160
167
my @constructors =
161
168
map { sprintf (" (%s -%s ((value %s )))" ,
162
169
$name ,
163
- type_to_flat_string($_ -> {' type' }),
164
- type_to_string($_ -> {' type' })) }
170
+ type_to_flat_string($_ -> {' type' }, $imports ),
171
+ type_to_string($_ -> {' type' }, $imports )) }
165
172
@{$data -> {' fields' }};
166
173
my $constructor_str = join ' ' , @constructors ;
167
174
@@ -170,47 +177,46 @@ sub process_union
170
177
$constructor_str );
171
178
}
172
179
180
+ my %PROCESS_MAP = (
181
+ function => \&process_function,
182
+ extern => \&process_variable,
183
+ struct => \&process_struct,
184
+ const => \&process_const,
185
+ enum => \&process_enum,
186
+ typedef => \&process_typedef,
187
+ union => \&process_union,
188
+ );
189
+
173
190
sub main
174
191
{
175
- print " (import stdlib) \n " ;
176
- print " (import variant) \n " ;
192
+ my %imports ;
193
+ my @bindings ;
177
194
178
195
while (defined (my $entry = <>)) {
179
196
chomp $entry ;
180
- if ($entry eq ' [' ) {
181
- next ;
182
- }
183
- if ($entry eq ' ]' ) {
197
+ if (($entry eq ' [' ) or ($entry eq ' ]' )) {
184
198
next ;
185
199
}
186
200
$entry =~ s / ,\s *$// ;
187
201
my $data = decode_json($entry );
188
202
my $tag = $data -> {' tag' };
189
- if ($tag eq ' function' ) {
190
- my $str = process_function($data );
191
- print " $str \n " ;
192
- } elsif ($tag eq ' extern' ) {
193
- my $str = process_variable($data );
194
- print " $str \n " ;
195
- } elsif ($tag eq ' struct' ) {
196
- my $str = process_struct($data );
197
- print " $str \n " ;
198
- } elsif ($tag eq ' const' ) {
199
- my $str = process_const($data );
200
- print " $str \n " ;
201
- } elsif ($tag eq ' enum' ) {
202
- my $str = process_enum($data );
203
- print " $str \n " ;
204
- } elsif ($tag eq ' typedef' ) {
205
- my $str = process_typedef($data );
206
- print " $str \n " ;
207
- } elsif ($tag eq ' union' ) {
208
- my $str = process_union($data );
209
- print " $str \n " ;
203
+ if ($PROCESS_MAP {$tag }) {
204
+ push @bindings , $PROCESS_MAP {$tag }-> ($data , \%imports );
210
205
} else {
211
206
warn " unable to process tag '$tag '" ;
212
207
}
213
208
}
209
+
210
+ my @imports = sort keys %imports ;
211
+ if (@imports ) {
212
+ for my $import (@imports ) {
213
+ print " (import $import )\n " ;
214
+ }
215
+ print " \n " ;
216
+ }
217
+ for my $binding (@bindings ) {
218
+ print " $binding \n " ;
219
+ }
214
220
}
215
221
216
222
main();
0 commit comments