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 hat.dialect.HATF16Op;
 27 import hat.dialect.HATMemoryVarOp;
 28 import hat.dialect.HATVectorOp;
 29 import jdk.incubator.code.dialect.java.ClassType;
 30 
 31 import java.util.function.Consumer;
 32 
 33 public  class C99HATCodeBuilder<T extends C99HATCodeBuilder<T>> extends HATCodeBuilder<T> {
 34 
 35     public final T varName(HATMemoryVarOp hatLocalVarOp) {
 36         identifier(hatLocalVarOp.varName());
 37         return self();
 38     }
 39 
 40     public final T varName(HATVectorOp.HATVectorVarOp hatVectorVarOp) {
 41         identifier(hatVectorVarOp.varName());
 42         return self();
 43     }
 44 
 45     public final T varName(HATVectorOp.HATVectorLoadOp vectorLoadOp) {
 46         identifier(vectorLoadOp.varName());
 47         return self();
 48     }
 49 
 50     public final T varName(HATVectorOp.HATVectorStoreView hatVectorStoreView) {
 51         identifier(hatVectorStoreView.varName());
 52         return self();
 53     }
 54 
 55     public final T varName(HATVectorOp.HATVectorBinaryOp hatVectorBinaryOp) {
 56         identifier(hatVectorBinaryOp.varName());
 57         return self();
 58     }
 59 
 60     public final T varName(HATVectorOp.HATVectorVarLoadOp hatVectorVarLoadOp) {
 61         identifier(hatVectorVarLoadOp.varName());
 62         return self();
 63     }
 64 
 65     public final T varName(HATF16Op.HATF16VarOp hatF16VarOp) {
 66         identifier(hatF16VarOp.varName());
 67         return self();
 68     }
 69 
 70     public final T suffix_t(ClassType type){
 71         String name = type.toClassName();
 72         int dotIdx = name.lastIndexOf('.');
 73         int dollarIdx = name.lastIndexOf('$');
 74         int idx = Math.max(dotIdx, dollarIdx);
 75         if (idx > 0) {
 76             name = name.substring(idx + 1);
 77         }
 78         return suffix_t(name);
 79     }
 80 
 81     public final T suffix_t(String name) {
 82         return identifier(name).identifier("_t");
 83     }
 84 
 85     public final T suffix_u(String name) {
 86         return identifier(name).identifier("_u");
 87     }
 88 
 89     public final T suffix_s(String name) {
 90         return identifier(name).identifier("_s");
 91     }
 92 
 93     public final T suffix_t(Class<?> klass) {
 94         return suffix_t(klass.getSimpleName());
 95     }
 96 
 97     public final T suffix_u(Class<?> klass) {
 98         return suffix_u(klass.getSimpleName());
 99     }
100 
101     public final T suffix_s(Class<?> klass) {
102         return suffix_s(klass.getSimpleName());
103     }
104 
105     public final T structOrUnion(boolean isStruct) {
106         return (isStruct ? structKeyword() : union());
107     }
108 
109     public final T typedefKeyword() {
110         return keyword("typedef");
111     }
112 
113     public final T structKeyword() {
114         return keyword("struct");
115     }
116 
117     public final T union() {
118         return keyword("union");
119     }
120 
121     public final T externC() {
122         return externKeyword().space().dquote("C");
123     }
124 
125     public final T hashDefineKeyword() {
126         return hash().keyword("define");
127     }
128 
129     public final T hashIfdefKeyword() {
130         return hash().keyword("ifdef");
131     }
132 
133     public final T hashIfndefKeyword() {
134         return hash().keyword("ifndef");
135     }
136 
137     public final T hashEndif() {
138         return hash().keyword("endif").nl();
139     }
140 
141     public final T hashIfdef(String value) {
142         return hashIfdefKeyword().space().constant(value).nl();
143     }
144 
145     public final T hashIfndef(String value) {
146         return hashIfndefKeyword().space().constant(value).nl();
147     }
148 
149     public final T hashIfdef(String value, Consumer<T> consumer) {
150         return hashIfdef(value).accept(consumer).hashEndif();
151     }
152 
153     public final T hashIfndef(String value, Consumer<T> consumer) {
154         return hashIfndef(value).accept(consumer).hashEndif();
155     }
156 
157     public final T pragmaKeyword() {
158         return keyword("pragma");
159     }
160 
161     public final T includeKeyword() {
162         return keyword("include");
163     }
164 
165     public final T hashDefine(String name, String... values) {
166         hashDefineKeyword().space().identifier(name);
167         for (String value : values) {
168             space().constant(value);
169         }
170         return nl();
171     }
172 
173     public final T hashDefine(String name, Consumer<T> consumer) {
174         hashDefineKeyword().space().identifier(name);
175         space();
176         consumer.accept(self());
177         return nl();
178     }
179 
180     public final T pragma(String name, String... values) {
181         hash().pragmaKeyword().space().identifier(name);
182         for (String value : values) {
183             space().constant(value);
184         }
185         return nl();
186     }
187 
188     public final T includeSys(String... values) {
189         for (String value : values) {
190             hash().includeKeyword().space().lt().identifier(value).gt().nl();
191         }
192         return self();
193     }
194 
195     public final T include(String... values) {
196         for (String value : values) {
197             hash().includeKeyword().space().dquote().identifier(value).dquote().nl();
198         }
199         return nl();
200     }
201 
202     public final T externKeyword() {
203         return keyword("extern");
204     }
205 
206     public final T u08Type() {
207         return typeName("unsigned").space().s08Type();
208     }
209 
210     public final T u08Type(String identifier) {
211         return u08Type().space().identifier(identifier);
212     }
213 
214     public final T u08PtrType() {
215         return u08Type().space().asterisk();
216     }
217 
218     public final T u08PtrType(String identifier) {
219         return u08PtrType().identifier(identifier);
220     }
221 
222     public final T u32Type() {
223         return typeName("unsigned").space().s32Type();
224     }
225 
226     public final T u32Type(String identifier ) {
227         return u32Type().space().identifier(identifier);
228     }
229 
230     public final T u64Type() {
231         return typeName("unsigned").space().s64Type();
232     }
233 
234     public final T u16Type() {
235         return typeName("unsigned").space().s16Type();
236     }
237 
238     public final T u16Type(String identifier) {
239         return u16Type().space().identifier(identifier);
240     }
241 
242     public final T bfloat16Type(String identifier) {
243         return suffix_t("BFLOAT16_UNION").space().identifier(identifier);
244     }
245 
246     public final  T typedefStructOrUnion(boolean isStruct, Class<?> klass, Consumer<T> consumer) {
247         return typedefKeyword()
248                 .space()
249                 .structOrUnion(isStruct)
250                 .space()
251                 .either(isStruct, _ -> suffix_s(klass), _ -> suffix_u(klass))
252                 .braceNlIndented(consumer)
253                 .suffix_t(klass).semicolonNl();
254     }
255 
256     public final T typedefStruct(String name, Consumer<T> consumer) {
257         return typedefKeyword()
258                 .space()
259                 .structKeyword()
260                 .space()
261                 .suffix_s(name)
262                 .braceNlIndented(consumer)
263                 .suffix_t(name)
264                 .semicolonNl();
265     }
266 
267     public final T typedefUnion(String name, Consumer<T> consumer) {
268         return typedefKeyword()
269                 .space()
270                 .union()
271                 .space()
272                 .suffix_s(name)
273                 .braceNlIndented(consumer)
274                 .suffix_t(name)
275                 .semicolonNl();
276     }
277 
278     public final T typedefStruct(Class<?>clazz, Consumer<T> consumer) {
279         return typedefStruct(clazz.getSimpleName(), consumer);
280     }
281 
282     public final T typedefSingleValueStruct(String structName, String type) {
283         return typedefStruct(structName,_-> typeName(type).space().identifier("value").semicolon());
284     }
285 
286     public final T unionBfloat16() {
287         return typedefUnion("BFLOAT16_UNION", _ -> {
288             typeName("float").space().identifier("f").semicolon().nl();
289             u16Type("s").sizeArray(2).semicolon();
290         });
291     }
292 
293     public final T funcDef(Consumer<T> type, Consumer<T> name, Consumer<T> args, Consumer<T> body){
294         type.accept(self());
295         space();
296         name.accept(self());
297         paren(args);
298         braceNlIndented(body);
299         return nl();
300     }
301 
302     public final T assign(Consumer<T> lhs, Consumer<T> rhs){
303         lhs.accept(self());
304         space().equals().space();
305         rhs.accept(self());
306         return self();
307     }
308 
309     public final T cast(Consumer<T> type){
310         return paren(_-> type.accept(self()));
311     }
312 
313     public final T returnKeyword(Consumer<T> exp){
314         return returnKeyword().space().paren(_-> exp.accept(self())).semicolon();
315     }
316 
317     public final T call(Consumer<T> name,Consumer<T> ...args) {
318         name.accept(self());
319         return paren(_->commaSpaceSeparated(args));
320     }
321 
322     public final T call(String name,Consumer<T> ...args) {
323         return call(_->identifier(name),args);
324     }
325 
326     public final T forLoop(Consumer<T> init, Consumer<T> test, Consumer<T>mutate, Consumer<T>body) {
327         return  forKeyword()
328                 .paren(_->{
329                     init.accept(self());
330                     semicolon().space();
331                     test.accept(self());
332                     semicolon().space();mutate.accept(self());
333                 })
334                 .braceNlIndented(body::accept);
335     }
336 
337     public final T sizeof() {
338         return emitText("sizeof");
339     }
340 
341     public final T sizeof(String identifier) {
342         return sizeof(_->identifier(identifier));
343     }
344 
345     public final T sizeof(Consumer<T> consumer) {
346         return sizeof().paren(consumer);
347     }
348 
349     public final T voidPtrType() {
350         return voidType().space().asterisk();
351     }
352 
353     public final T voidPtrType(String identifier) {
354         return voidPtrType().identifier(identifier);
355     }
356 
357     public final T sizeType() {
358         return typeName("size_t");
359     }
360 
361     public final T sizeType(String identifier) {
362         return sizeType().space().identifier(identifier);
363     }
364 }