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 }