1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package hat.codebuilders;
26 import jdk.incubator.code.dialect.java.ClassType;
27
28 import java.util.function.Consumer;
29
30 public class C99HATCodeBuilder<T extends C99HATCodeBuilder<T>> extends HATCodeBuilder<T> {
31
32 public final T suffix_t(ClassType type){
33 String name = type.toClassName();
34 int dotIdx = name.lastIndexOf('.');
35 int dollarIdx = name.lastIndexOf('$');
36 int idx = Math.max(dotIdx, dollarIdx);
37 if (idx > 0) {
38 name = name.substring(idx + 1);
39 }
40 return suffix_t(name);
41 }
42
43 public final T suffix_t(String name) {
44 return identifier(name).identifier("_t");
45 }
46
47 public final T suffix_u(String name) {
48 return identifier(name).identifier("_u");
49 }
50
51 public final T suffix_s(String name) {
52 return identifier(name).identifier("_s");
53 }
54
55 public final T suffix_t(Class<?> klass) {
56 return suffix_t(klass.getSimpleName());
57 }
58
59 public final T suffix_u(Class<?> klass) {
60 return suffix_u(klass.getSimpleName());
61 }
62
63 public final T suffix_s(Class<?> klass) {
64 return suffix_s(klass.getSimpleName());
65 }
66
67 public final T structOrUnion(boolean isStruct) {
68 return (isStruct ? structKeyword() : union());
69 }
70
71
72 public final T typedefKeyword() {
73 return keyword("typedef");
74 }
75
76
77 public final T structKeyword() {
78 return keyword("struct");
79 }
80
81 public final T union() {
82 return keyword("union");
83 }
84
85
86 public final T externC() {
87 return externKeyword().space().dquote("C");
88 }
89
90 public final T hashDefineKeyword() {
91 return hash().keyword("define");
92 }
93
94 public final T hashIfdefKeyword() {
95 return hash().keyword("ifdef");
96 }
97
98 public final T hashIfndefKeyword() {
99 return hash().keyword("ifndef");
100 }
101
102 public final T hashEndif() {
103 return hash().keyword("endif").nl();
104 }
105
106 public final T hashIfdef(String value) {
107 return hashIfdefKeyword().space().constant(value).nl();
108 }
109
110 public final T hashIfndef(String value) {
111 return hashIfndefKeyword().space().constant(value).nl();
112 }
113
114 public final T hashIfdef(String value, Consumer<T> consumer) {
115 return hashIfdef(value).accept(consumer).hashEndif();
116 }
117
118 public final T hashIfndef(String value, Consumer<T> consumer) {
119 return hashIfndef(value).accept(consumer).hashEndif();
120 }
121
122 public final T pragmaKeyword() {
123 return keyword("pragma");
124 }
125
126 public final T includeKeyword() {
127 return keyword("include");
128 }
129
130 public final T hashDefine(String name, String... values) {
131 hashDefineKeyword().space().identifier(name);
132 for (String value : values) {
133 space().constant(value);
134 }
135 return nl();
136 }
137
138 public final T hashDefine(String name, Consumer<T> consumer) {
139 hashDefineKeyword().space().identifier(name);
140 space();
141 consumer.accept(self());
142 return nl();
143 }
144
145 public final T pragma(String name, String... values) {
146 hash().pragmaKeyword().space().identifier(name);
147 for (String value : values) {
148 space().constant(value);
149 }
150 return nl();
151 }
152 public final T includeSys(String... values) {
153 for (String value : values) {
154 hash().includeKeyword().space().lt().identifier(value).gt().nl();
155 }
156 return self();
157 }
158 public final T include(String... values) {
159 for (String value : values) {
160 hash().includeKeyword().space().dquote().identifier(value).dquote().nl();
161 }
162 return nl();
163 }
164
165 public final T externKeyword() {
166 return keyword("extern");
167 }
168
169 public final T u08Type() {
170 return typeName("unsigned").space().s08Type();
171 }
172 public final T u08Type(String identifier) {
173 return u08Type().space().identifier(identifier);
174 }
175 public final T u08PtrType() {
176 return u08Type().space().asterisk();
177 }
178 public final T u08PtrType(String identifier) {
179 return u08PtrType().identifier(identifier);
180 }
181
182
183
184 public final T u32Type() {
185 return typeName("unsigned").space().s32Type();
186 }
187
188 public final T u32Type(String identifier ) {
189 return u32Type().space().identifier(identifier);
190 }
191
192 public final T u64Type() {
193 return typeName("unsigned").space().s64Type();
194 }
195
196 public final T u16Type() {
197 return typeName("unsigned").space().s16Type();
198 }
199 public final T u16Type(String identifier) {
200 return u16Type().space().identifier(identifier);
201 }
202
203 public final T typedefStructOrUnion(boolean isStruct, Class<?> klass, Consumer<T> consumer) {
204 return typedefKeyword()
205 .space()
206 .structOrUnion(isStruct)
207 .space()
208 .either(isStruct, _ -> suffix_s(klass), _ -> suffix_u(klass))
209 .braceNlIndented(consumer)
210 .suffix_t(klass).semicolonNl();
211 }
212
213 public final T typedefStruct(String name, Consumer<T> consumer) {
214 return typedefKeyword()
215 .space()
216 .structKeyword()
217 .space()
218 .suffix_s(name)
219 .braceNlIndented(consumer)
220 .suffix_t(name)
221 .semicolonNl();
222 }
223 public final T typedefStruct(Class<?>clazz, Consumer<T> consumer) {
224 return typedefStruct(clazz.getSimpleName(), consumer);
225 }
226
227
228 public final T typedefSingleValueStruct(String structName, String type) {
229 return typedefStruct(structName,_-> typeName(type).space().identifier("value").semicolonNl());
230 }
231
232 public final T funcDef(Consumer<T> type,Consumer<T> name, Consumer<T> args, Consumer<T> body){
233 type.accept(self());
234 space();
235 name.accept(self());
236 paren(args);
237 braceNlIndented(body);
238 return nl();
239 }
240 public final T assign(Consumer<T> lhs, Consumer<T> rhs){
241 lhs.accept(self());
242 space().equals().space();
243 rhs.accept(self());
244 return self();
245 }
246
247 public final T cast(Consumer<T> type){
248 return paren(_-> type.accept(self()));
249 }
250 public final T returnKeyword(Consumer<T> exp){
251 return returnKeyword().space().paren(_-> exp.accept(self())).semicolon();
252 }
253
254 public final T call(Consumer<T> name,Consumer<T> ...args){
255 name.accept(self());
256 return paren(_->commaSpaceSeparated(args));
257 }
258 public final T call(String name,Consumer<T> ...args){
259 return call(_->identifier(name),args);
260 }
261
262 public final T forLoop(Consumer<T> init, Consumer<T> test, Consumer<T>mutate, Consumer<T>body){
263 return forKeyword()
264 .paren(_->{
265 init.accept(self());
266 semicolon().space();
267 test.accept(self());
268 semicolon().space();mutate.accept(self());
269 })
270 .braceNlIndented(body::accept)
271 .nl();
272 }
273
274
275 public final T sizeof() {
276 return emitText("sizeof");
277 }
278 public final T sizeof(String identifier) {
279 return sizeof(_->identifier(identifier));
280 }
281 public final T sizeof(Consumer<T> consumer) {
282 return sizeof().paren(consumer);
283 }
284 public final T voidPtrType() {
285 return voidType().space().asterisk();
286 }
287 public final T voidPtrType(String identifier) {
288 return voidPtrType().identifier(identifier);
289 }
290 public final T sizeType() {
291 return typeName("size_t");
292 }
293 public final T sizeType(String identifier) {
294 return sizeType().space().identifier(identifier);
295 }
296 }