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 
26 package jdk.code.tools.renderer;
27 
28 import java.io.StringWriter;
29 
30 public final class CStyleRenderer extends CommonRenderer<CStyleRenderer> {
31     public CStyleRenderer() {
32         super();
33     }
34 
35     public CStyleRenderer func(String identifier, TextRenderer.NestedRendererSAM<CStyleRenderer> args,
36                                TextRenderer.NestedRendererSAM<CStyleRenderer> body) {
37         return keyword("func").space().identifier(identifier).parenthesized(args).braced(body).nl();
38     }
39 
40     public CStyleRenderer forLoop(TextRenderer.NestedRendererSAM<CStyleRenderer> init, TextRenderer.NestedRendererSAM<CStyleRenderer> cond,
41                                   TextRenderer.NestedRendererSAM<CStyleRenderer> mutator, TextRenderer.NestedRendererSAM<CStyleRenderer> body) {
42         return forKeyword().oparen().nest(init).semicolon().space().nest(cond).semicolon().space().
43                 nest(mutator).cparen().braced(body).nl();
44     }
45 
46     public CStyleRenderer whileLoop(TextRenderer.NestedRendererSAM<CStyleRenderer> cond, TextRenderer.NestedRendererSAM<CStyleRenderer> body) {
47         return whileKeyword().oparen().nest(cond).cparen().braced(body).nl();
48     }
49 
50     public CStyleRenderer ifCondRaw(TextRenderer.NestedRendererSAM<CStyleRenderer> cond, TextRenderer.NestedRendererSAM<CStyleRenderer> thenBody) {
51         return ifKeyword().oparen().nest(cond).cparen().braced(thenBody);
52     }
53 
54     public CStyleRenderer ifCond(TextRenderer.NestedRendererSAM<CStyleRenderer> cond, TextRenderer.NestedRendererSAM<CStyleRenderer> thenBody) {
55         return ifCondRaw(cond, thenBody).nl();
56     }
57 
58     public CStyleRenderer ifCond(TextRenderer.NestedRendererSAM<CStyleRenderer> cond, TextRenderer.NestedRendererSAM<CStyleRenderer> thenBody,
59                                  TextRenderer.NestedRendererSAM<CStyleRenderer> elseBody) {
60         return ifCondRaw(cond, thenBody).elseKeyword().braced(elseBody).nl();
61     }
62 
63     public CStyleRenderer var(Class<?> clazz, String name) {
64         return type(clazz.getName()).space().identifier(name);
65     }
66 
67     public CStyleRenderer assign(String identifier) {
68         return identifier(identifier).equal();
69     }
70 
71     static public void main(String[] args) {
72         StringWriter writer = new StringWriter();
73         CStyleRenderer renderer = new CStyleRenderer().writer(writer).colorize();
74         renderer.lineComment("A new function");
75         renderer.func("funcName",
76                 (as) -> as.var(int.class, "name").comma().space()
77                         .var(int.class, "name2"),
78                 (fb) -> fb.lineComment("Inside body of func")
79                         .append("here;\nis;\nsome text").semicolon().nl()
80                         .forLoop(
81                                 (in) -> in.var(int.class, "a").equal().decLiteral(0),
82                                 (cc) -> cc.identifier("a").op("<").decLiteral(10),
83                                 (mu) -> mu.assign("a").identifier("a").op("+").decLiteral(1),
84                                 (lb) -> lb.lineComment("in loop")
85                                         .ifCond(
86                                                 (cc) -> cc.identifier("a").op(">").decLiteral(2),
87                                                 (th) -> th.lineComment("positive"),
88                                                 (el) -> el.lineComment("not so much ")
89                                         )
90                         )
91                         .nl()
92         ).nl();
93         System.out.println(writer);
94 
95     }
96 }