You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by jf...@apache.org on 2019/05/04 15:47:36 UTC

[plc4x] branch feature/code-gen updated (df3d23a -> f0600d0)

This is an automated email from the ASF dual-hosted git repository.

jfeinauer pushed a change to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git.


    from df3d23a  First stage towards code-gen.
     new 4e8ef99  Code generator is able to build Classes.
     new f0600d0  Now even Inner Classes are supported.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../plc4x/codegen/version2/AbstractNode.java       |  14 ++
 .../codegen/version2/AssignementExpression.java    |  29 +++
 .../plc4x/codegen/version2/BinaryExpression.java   |  43 ++++
 .../org/apache/plc4x/codegen/version2/Block.java   |  29 +++
 .../plc4x/codegen/version2/CallExpression.java     |  44 ++++
 .../plc4x/codegen/version2/ClassDefinition.java    |  55 +++++
 .../{CodePrinter.java => version2/CodeWriter.java} |   7 +-
 .../codegen/version2/ConditionalStatement.java     |  16 ++
 .../plc4x/codegen/version2/ConstantNode.java       |  24 ++
 .../codegen/version2/ConstructorDeclaration.java   |  18 ++
 .../codegen/version2/DeclarationStatement.java     |  33 +++
 .../apache/plc4x/codegen/version2/Expression.java  |   9 +
 .../plc4x/codegen/version2/FieldDeclaration.java   |  20 ++
 .../plc4x/codegen/version2/FieldReference.java     |  16 ++
 .../apache/plc4x/codegen/version2/FileNode.java    |  25 ++
 .../apache/plc4x/codegen/version2/Generator.java   |  44 ++++
 .../apache/plc4x/codegen/version2/IfStatement.java |  36 +++
 .../plc4x/codegen/version2/JavaGenerator.java      | 235 ++++++++++++++++++
 .../org/apache/plc4x/codegen/version2/Method.java  |  51 ++++
 .../plc4x/codegen/version2/MethodDefinition.java   |  42 ++++
 .../plc4x/codegen/version2/NewExpression.java      |  26 ++
 .../org/apache/plc4x/codegen/version2/Node.java    |   9 +
 .../apache/plc4x/codegen/version2/NodeVisitor.java |  10 +
 .../codegen/version2/ParameterExpression.java      |  23 ++
 .../plc4x/codegen/version2/PhpGenerator.java       |  93 +++++++
 .../apache/plc4x/codegen/version2/Primitive.java   |  19 ++
 .../plc4x/codegen/version2/ReturnStatement.java    |  22 ++
 .../apache/plc4x/codegen/version2/Statement.java   |   4 +
 .../apache/plc4x/codegen/version2/TypeNode.java    |  17 ++
 .../apache/plc4x/codegen/version2/TypeUtil.java    |  11 +
 .../plc4x/codegen/version2/JavaGeneratorTest.java  | 275 +++++++++++++++++++++
 .../plc4x/codegen/version2/PhpGeneratorTest.java   |  23 ++
 32 files changed, 1319 insertions(+), 3 deletions(-)
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AbstractNode.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AssignementExpression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/BinaryExpression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Block.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CallExpression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
 copy sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/{CodePrinter.java => version2/CodeWriter.java} (89%)
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConditionalStatement.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstantNode.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstructorDeclaration.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/DeclarationStatement.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Expression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldDeclaration.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldReference.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FileNode.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/IfStatement.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Method.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/MethodDefinition.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NewExpression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Node.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NodeVisitor.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ParameterExpression.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Primitive.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ReturnStatement.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Statement.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeNode.java
 create mode 100644 sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeUtil.java
 create mode 100644 sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
 create mode 100644 sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/PhpGeneratorTest.java


[plc4x] 02/02: Now even Inner Classes are supported.

Posted by jf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jfeinauer pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit f0600d054c12924a8b6f00d5e64ca43b7e644ab0
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat May 4 17:47:26 2019 +0200

    Now even Inner Classes are supported.
---
 .../plc4x/codegen/version2/ClassDefinition.java    | 30 ++++++++++++++-
 .../apache/plc4x/codegen/version2/FileNode.java    | 25 ++++++++++++
 .../apache/plc4x/codegen/version2/Generator.java   |  4 +-
 .../plc4x/codegen/version2/JavaGenerator.java      | 22 +++++++++--
 .../plc4x/codegen/version2/PhpGenerator.java       |  6 ++-
 .../plc4x/codegen/version2/JavaGeneratorTest.java  | 45 ++++++++++++++++++++--
 6 files changed, 121 insertions(+), 11 deletions(-)

diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
index 76c33a7..ce212a3 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
@@ -10,13 +10,39 @@ public class ClassDefinition implements Node {
     private final List<FieldDeclaration> fields;
     private final List<ConstructorDeclaration> constructors;
     private final List<MethodDefinition> methods;
+    private final List<ClassDefinition> innerClasses;
 
-    public ClassDefinition(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+    public ClassDefinition(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods, List<ClassDefinition> innerClasses) {
         this.namespace = namespace;
         this.className = className;
         this.fields = fields;
         this.constructors = constructors;
         this.methods = methods;
+        this.innerClasses = innerClasses;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public List<FieldDeclaration> getFields() {
+        return fields;
+    }
+
+    public List<ConstructorDeclaration> getConstructors() {
+        return constructors;
+    }
+
+    public List<MethodDefinition> getMethods() {
+        return methods;
+    }
+
+    public List<ClassDefinition> getInnerClasses() {
+        return innerClasses;
     }
 
     @Override public <T> T accept(NodeVisitor<T> visitor) {
@@ -24,6 +50,6 @@ public class ClassDefinition implements Node {
     }
 
     @Override public void write(Generator writer) {
-        writer.generateClass(this.namespace, this.className, this.fields, this.constructors, this.methods);
+        writer.generateClass(this.namespace, this.className, this.fields, this.constructors, this.methods, innerClasses, true);
     }
 }
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FileNode.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FileNode.java
new file mode 100644
index 0000000..36cc3a7
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FileNode.java
@@ -0,0 +1,25 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+/**
+ * Defines a File in Java
+ */
+public class FileNode implements Node {
+
+    private final ClassDefinition mainClass;
+    private final List<ClassDefinition> innerClasses;
+
+    public FileNode(ClassDefinition mainClass, List<ClassDefinition> innerClasses) {
+        this.mainClass = mainClass;
+        this.innerClasses = innerClasses;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generateFile(mainClass, innerClasses);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
index 687164a..5d06f13 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
@@ -32,11 +32,13 @@ public interface Generator {
 
     void generateReturn(Expression value);
 
-    void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods);
+    void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods, List<ClassDefinition> innerClasses, boolean mainClass);
 
     void generateFieldDeclaration(TypeNode type, String name);
 
     void generateFieldReference(TypeNode type, String name);
 
     void generateConstructor(String className, List<ParameterExpression> parameters, Block body);
+
+    void generateFile(ClassDefinition mainClass, List<ClassDefinition> innerClasses);
 }
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
index 665500e..899c8fb 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
@@ -143,10 +143,14 @@ public class JavaGenerator implements Generator {
         value.write(this);
     }
 
-    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods, List<ClassDefinition> innerClasses, boolean mainClass) {
         // Add static?!
         // Own File?
-        writer.write("public class ");
+        writer.startLine("public ");
+        if (!mainClass) {
+            writer.write("static ");
+        }
+        writer.write("class ");
         writer.write(className);
         // TODO extends / implements
         writer.write(" {");
@@ -172,9 +176,15 @@ public class JavaGenerator implements Generator {
             writer.writeLine("");
         }
 
+        // If there are inner classes, implement them
+        if (innerClasses != null) {
+            for (ClassDefinition innerClass : innerClasses) {
+                this.generateClass(innerClass.getNamespace(), innerClass.getClassName(), innerClass.getFields(), innerClass.getConstructors(), innerClass.getMethods(), innerClass.getInnerClasses(), false);
+            }
+        }
+
         writer.endBlock();
-        writer.write("}");
-        writer.endLine();
+        writer.writeLine("}");
     }
 
     @Override public void generateFieldDeclaration(TypeNode type, String name) {
@@ -209,6 +219,10 @@ public class JavaGenerator implements Generator {
         writer.writeLine("}");
     }
 
+    @Override public void generateFile(ClassDefinition mainClass, List<ClassDefinition> innerClasses) {
+        generateClass(mainClass.getNamespace(), mainClass.getClassName(), mainClass.getFields(), mainClass.getConstructors(), mainClass.getMethods(), innerClasses, true);
+    }
+
     private String getOperator(BinaryExpression.Operation op) {
         switch (op) {
             case EQ:
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
index 279a525..c5a71e7 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
@@ -71,7 +71,7 @@ public class PhpGenerator implements Generator {
 
     }
 
-    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods, List<ClassDefinition> innerClasses, boolean mainClass) {
 
     }
 
@@ -86,4 +86,8 @@ public class PhpGenerator implements Generator {
     @Override public void generateConstructor(String className, List<ParameterExpression> parameters, Block body) {
 
     }
+
+    @Override public void generateFile(ClassDefinition mainClass, List<ClassDefinition> innerClasses) {
+
+    }
 }
diff --git a/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
index ae4f312..ad1738a 100644
--- a/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
+++ b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
@@ -159,6 +159,7 @@ public class JavaGeneratorTest {
     @Test
     public void defineClass() {
         final FieldDeclaration current = new FieldDeclaration(Primitive.DOUBLE, "current");
+        final FieldReference currentRef = new FieldReference(Primitive.DOUBLE, "current");
 
         final ParameterExpression a = new ParameterExpression(Primitive.DOUBLE, "a");
         final ParameterExpression b = new ParameterExpression(Primitive.DOUBLE, "b");
@@ -173,7 +174,6 @@ public class JavaGeneratorTest {
                 )
             )
         );
-        final FieldReference currentRef = new FieldReference(Primitive.DOUBLE, "current");
         final MethodDefinition inc = new MethodDefinition("inc", Primitive.VOID,
             Collections.EMPTY_LIST,
             new Block(
@@ -184,7 +184,7 @@ public class JavaGeneratorTest {
             )
         );
 
-        final ClassDefinition clazz = new ClassDefinition("org.apache.plc4x", "MyClazz", Arrays.asList(current), Collections.emptyList(), Arrays.asList(inc, decl));
+        final ClassDefinition clazz = new ClassDefinition("org.apache.plc4x", "MyClazz", Arrays.asList(current), Collections.emptyList(), Arrays.asList(inc, decl), null);
 
         clazz.write(generator);
         final String code = writer.getCode();
@@ -219,7 +219,43 @@ public class JavaGeneratorTest {
                     new Block(new AssignementExpression(currentRef, value))
                 )
             ),
-            Collections.emptyList());
+            Collections.emptyList(), null);
+
+        clazz.write(generator);
+        final String code = writer.getCode();
+        assertEquals("public class MyClazz {\n" +
+            "    \n" +
+            "    public double current;\n" +
+            "    \n" +
+            "    public MyClazz(double value) {\n" +
+            "        this.current = value;\n" +
+            "    }\n" +
+            "    \n" +
+            "}\n", code);
+    }
+
+    @Test
+    public void defineClassWithInnerClass() {
+        final FieldDeclaration current = new FieldDeclaration(Primitive.DOUBLE, "current");
+
+        final FieldReference currentRef = new FieldReference(Primitive.DOUBLE, "current");
+
+        final ParameterExpression value = new ParameterExpression(Primitive.DOUBLE, "value");
+
+        // Define Inner Class
+        final ClassDefinition innerClass = new ClassDefinition("", "MyInnerClazz", Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), null);
+
+        final ClassDefinition clazz = new ClassDefinition("org.apache.plc4x",
+            "MyClazz",
+            Arrays.asList(current),
+            Arrays.asList(
+                new ConstructorDeclaration(
+                    Collections.singletonList(value),
+                    new Block(new AssignementExpression(currentRef, value))
+                )
+            ),
+            Collections.emptyList(),
+            Collections.singletonList(innerClass));
 
         clazz.write(generator);
         final String code = writer.getCode();
@@ -231,6 +267,9 @@ public class JavaGeneratorTest {
             "        this.current = value;\n" +
             "    }\n" +
             "    \n" +
+            "    public static class MyInnerClazz {\n" +
+            "        \n" +
+            "    }\n" +
             "}\n", code);
     }
 }
\ No newline at end of file


[plc4x] 01/02: Code generator is able to build Classes.

Posted by jf...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jfeinauer pushed a commit to branch feature/code-gen
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 4e8ef998f7379f44c05103ec8e1bb9e832a1a2c8
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat May 4 17:21:47 2019 +0200

    Code generator is able to build Classes.
---
 .../plc4x/codegen/version2/AbstractNode.java       |  14 ++
 .../codegen/version2/AssignementExpression.java    |  29 +++
 .../plc4x/codegen/version2/BinaryExpression.java   |  43 ++++
 .../org/apache/plc4x/codegen/version2/Block.java   |  29 +++
 .../plc4x/codegen/version2/CallExpression.java     |  44 ++++
 .../plc4x/codegen/version2/ClassDefinition.java    |  29 +++
 .../apache/plc4x/codegen/version2/CodeWriter.java  |  57 +++++
 .../codegen/version2/ConditionalStatement.java     |  16 ++
 .../plc4x/codegen/version2/ConstantNode.java       |  24 +++
 .../codegen/version2/ConstructorDeclaration.java   |  18 ++
 .../codegen/version2/DeclarationStatement.java     |  33 +++
 .../apache/plc4x/codegen/version2/Expression.java  |   9 +
 .../plc4x/codegen/version2/FieldDeclaration.java   |  20 ++
 .../plc4x/codegen/version2/FieldReference.java     |  16 ++
 .../apache/plc4x/codegen/version2/Generator.java   |  42 ++++
 .../apache/plc4x/codegen/version2/IfStatement.java |  36 ++++
 .../plc4x/codegen/version2/JavaGenerator.java      | 221 +++++++++++++++++++
 .../org/apache/plc4x/codegen/version2/Method.java  |  51 +++++
 .../plc4x/codegen/version2/MethodDefinition.java   |  42 ++++
 .../plc4x/codegen/version2/NewExpression.java      |  26 +++
 .../org/apache/plc4x/codegen/version2/Node.java    |   9 +
 .../apache/plc4x/codegen/version2/NodeVisitor.java |  10 +
 .../codegen/version2/ParameterExpression.java      |  23 ++
 .../plc4x/codegen/version2/PhpGenerator.java       |  89 ++++++++
 .../apache/plc4x/codegen/version2/Primitive.java   |  19 ++
 .../plc4x/codegen/version2/ReturnStatement.java    |  22 ++
 .../apache/plc4x/codegen/version2/Statement.java   |   4 +
 .../apache/plc4x/codegen/version2/TypeNode.java    |  17 ++
 .../apache/plc4x/codegen/version2/TypeUtil.java    |  11 +
 .../plc4x/codegen/version2/JavaGeneratorTest.java  | 236 +++++++++++++++++++++
 .../plc4x/codegen/version2/PhpGeneratorTest.java   |  23 ++
 31 files changed, 1262 insertions(+)

diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AbstractNode.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AbstractNode.java
new file mode 100644
index 0000000..abf44ae
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AbstractNode.java
@@ -0,0 +1,14 @@
+package org.apache.plc4x.codegen.version2;
+
+public abstract class AbstractNode implements Node {
+
+    public final TypeNode type;
+
+    protected AbstractNode(TypeNode type) {
+        this.type = type;
+    }
+
+    public TypeNode getType() {
+        return this.type;
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AssignementExpression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AssignementExpression.java
new file mode 100644
index 0000000..9544eed
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/AssignementExpression.java
@@ -0,0 +1,29 @@
+package org.apache.plc4x.codegen.version2;
+
+public class AssignementExpression extends Expression {
+
+    private final Expression target;
+    private final Node value;
+
+    protected AssignementExpression(Expression target, Node value) {
+        super(target.getType());
+        this.target = target;
+        this.value = value;
+    }
+
+    public Node getTarget() {
+        return target;
+    }
+
+    public Node getValue() {
+        return value;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generate(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/BinaryExpression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/BinaryExpression.java
new file mode 100644
index 0000000..0aef957
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/BinaryExpression.java
@@ -0,0 +1,43 @@
+package org.apache.plc4x.codegen.version2;
+
+public class BinaryExpression extends Expression {
+
+    private final Node left;
+    private final Node right;
+    private final Operation op;
+
+    protected BinaryExpression(TypeNode type, Node left, Node right, Operation op) {
+        super(type);
+        this.left = left;
+        this.right = right;
+        this.op = op;
+    }
+
+    public Node getLeft() {
+        return left;
+    }
+
+    public Node getRight() {
+        return right;
+    }
+
+    public Operation getOp() {
+        return op;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generate(this);
+    }
+
+    public enum Operation {
+        EQ,
+        NEQ,
+        GT,
+        LT,
+        PLUS;
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Block.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Block.java
new file mode 100644
index 0000000..dff5888
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Block.java
@@ -0,0 +1,29 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class Block extends Statement {
+
+    private final List<Node> statements;
+
+    public Block(List<Node> statements) {
+        this.statements = statements;
+    }
+
+    public Block(Node... statements) {
+        this(Arrays.asList(statements));
+    }
+
+    public List<Node> getStatements() {
+        return statements;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.writeBlock(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CallExpression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CallExpression.java
new file mode 100644
index 0000000..d3060a7
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CallExpression.java
@@ -0,0 +1,44 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CallExpression extends Expression {
+
+    private final Method method;
+    private final Node target;
+    private final List<Node> arguments;
+
+    /**
+     * Static Method ==> target == null
+     * @param method
+     * @param target
+     * @param arguments
+     */
+    public CallExpression(Method method, Node target, Node... arguments) {
+        super(method.getReturnType());
+        this.method = method;
+        this.target = target;
+        this.arguments = Arrays.asList(arguments);
+    }
+
+    public Method getMethod() {
+        return method;
+    }
+
+    public Node getTarget() {
+        return target;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        if (target == null) {
+            writer.generateStaticCall(method, arguments);
+        } else {
+            writer.generateCall(target, method, arguments);
+        }
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
new file mode 100644
index 0000000..76c33a7
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ClassDefinition.java
@@ -0,0 +1,29 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public class ClassDefinition implements Node {
+
+    private final String namespace;
+    private final String className;
+
+    private final List<FieldDeclaration> fields;
+    private final List<ConstructorDeclaration> constructors;
+    private final List<MethodDefinition> methods;
+
+    public ClassDefinition(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+        this.namespace = namespace;
+        this.className = className;
+        this.fields = fields;
+        this.constructors = constructors;
+        this.methods = methods;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generateClass(this.namespace, this.className, this.fields, this.constructors, this.methods);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CodeWriter.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CodeWriter.java
new file mode 100644
index 0000000..a2e897e
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/CodeWriter.java
@@ -0,0 +1,57 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.stream.IntStream;
+
+/**
+ * Helper class to print code.
+ */
+public class CodeWriter {
+
+    private StringBuffer buffer = new StringBuffer();
+    private int tabSize;
+
+    private int intendationLvl = 0;
+
+    public CodeWriter(int tabSize) {
+        this.tabSize = tabSize;
+    }
+
+    public void startBlock() {
+        this.intendationLvl += tabSize;
+    }
+
+    public void endBlock() {
+        if (intendationLvl < tabSize) {
+            throw new RuntimeException("Closing a Block which is not open!");
+        }
+        this.intendationLvl -= tabSize;
+    }
+
+    public void write(String s) {
+        buffer.append(s);
+    }
+
+    public void startLine(String s) {
+        writeIntendation();
+        write(s);
+    }
+
+    public void endLine() {
+        buffer.append("\n");
+    }
+
+    public void writeLine(String s) {
+        writeIntendation();
+        buffer.append(s);
+        buffer.append("\n");
+    }
+
+    private void writeIntendation() {
+        // Write the intendation
+        IntStream.range(0, intendationLvl).forEach(i -> buffer.append(" "));
+    }
+
+    public String getCode() {
+        return buffer.toString();
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConditionalStatement.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConditionalStatement.java
new file mode 100644
index 0000000..9a381b1
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConditionalStatement.java
@@ -0,0 +1,16 @@
+package org.apache.plc4x.codegen.version2;
+
+public class ConditionalStatement extends Expression {
+
+    protected ConditionalStatement(TypeNode type) {
+        super(type);
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstantNode.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstantNode.java
new file mode 100644
index 0000000..df43f3c
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstantNode.java
@@ -0,0 +1,24 @@
+package org.apache.plc4x.codegen.version2;
+
+public class ConstantNode extends Expression {
+
+    private Object value;
+
+    public ConstantNode(Object value) {
+        super(TypeUtil.infer(value));
+        this.value = value;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    @Override public void write(Generator generator) {
+        generator.generate(this);
+    }
+
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstructorDeclaration.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstructorDeclaration.java
new file mode 100644
index 0000000..084d548
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ConstructorDeclaration.java
@@ -0,0 +1,18 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public class ConstructorDeclaration extends MethodDefinition {
+
+    public ConstructorDeclaration(List<ParameterExpression> parameters, Block body) {
+        super(null, null, parameters, body);
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        throw new UnsupportedOperationException("This should be called by the Class Implementor!");
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/DeclarationStatement.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/DeclarationStatement.java
new file mode 100644
index 0000000..cfc5b06
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/DeclarationStatement.java
@@ -0,0 +1,33 @@
+package org.apache.plc4x.codegen.version2;
+
+public class DeclarationStatement extends Statement {
+
+    public final ParameterExpression parameterExpression;
+    public final Expression initializer;
+
+    public DeclarationStatement(ParameterExpression parameterExpression, Expression initializer) {
+        this.parameterExpression = parameterExpression;
+        this.initializer = initializer;
+    }
+
+    public ParameterExpression getParameterExpression() {
+        return parameterExpression;
+    }
+
+    public Expression getInitializer() {
+        return initializer;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    @Override public void write(Generator generator) {
+        if (initializer != null) {
+            generator.generateDeclarationWithInitializer(this);
+        } else {
+            generator.generateDeclaration(this);
+        }
+    }
+
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Expression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Expression.java
new file mode 100644
index 0000000..77bd812
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Expression.java
@@ -0,0 +1,9 @@
+package org.apache.plc4x.codegen.version2;
+
+public abstract class Expression extends AbstractNode {
+
+    protected Expression(TypeNode type) {
+        super(type);
+    }
+
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldDeclaration.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldDeclaration.java
new file mode 100644
index 0000000..c4f8790
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldDeclaration.java
@@ -0,0 +1,20 @@
+package org.apache.plc4x.codegen.version2;
+
+public class FieldDeclaration implements Node {
+
+    private final TypeNode type;
+    private final String name;
+
+    public FieldDeclaration(TypeNode type, String name) {
+        this.type = type;
+        this.name = name;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generateFieldDeclaration(type, name);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldReference.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldReference.java
new file mode 100644
index 0000000..7ae8759
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/FieldReference.java
@@ -0,0 +1,16 @@
+package org.apache.plc4x.codegen.version2;
+
+public class FieldReference extends ParameterExpression {
+
+    public FieldReference(TypeNode type, String name) {
+        super(type, name);
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generateFieldReference(type, getName());
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
new file mode 100644
index 0000000..687164a
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Generator.java
@@ -0,0 +1,42 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public interface Generator {
+
+    void generate(ConstantNode constantNode);
+
+    void generateDeclarationWithInitializer(DeclarationStatement declarationStatement);
+
+    void generateDeclaration(DeclarationStatement declarationStatement);
+
+    void generate(ParameterExpression parameterExpression);
+
+    void generate(Primitive primitive);
+
+    void generate(IfStatement ifStatement);
+
+    void writeBlock(Block statements);
+
+    void generate(BinaryExpression binaryExpression);
+
+    void generate(AssignementExpression assignementExpression);
+
+    void generateStaticCall(Method method, List<Node> constantNode);
+
+    void generateCall(Node target, Method method, List<Node> constantNode);
+
+    void generate(NewExpression newExpression);
+
+    void generate(MethodDefinition methodDefinition);
+
+    void generateReturn(Expression value);
+
+    void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods);
+
+    void generateFieldDeclaration(TypeNode type, String name);
+
+    void generateFieldReference(TypeNode type, String name);
+
+    void generateConstructor(String className, List<ParameterExpression> parameters, Block body);
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/IfStatement.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/IfStatement.java
new file mode 100644
index 0000000..e984f9b
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/IfStatement.java
@@ -0,0 +1,36 @@
+package org.apache.plc4x.codegen.version2;
+
+public class IfStatement extends Statement {
+
+    private Expression condition;
+    private Block body;
+    private Block orElse;
+
+    public IfStatement(Expression condition, Block body, Block orElse) {
+        // Check condition returns Binary
+        this.condition = condition;
+        this.body = body;
+        this.orElse = orElse;
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public Block getBody() {
+        return body;
+    }
+
+    public Block getOrElse() {
+        return orElse;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generate(this);
+    }
+
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
new file mode 100644
index 0000000..665500e
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/JavaGenerator.java
@@ -0,0 +1,221 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public class JavaGenerator implements Generator {
+
+    private final CodeWriter writer;
+
+    public JavaGenerator(CodeWriter writer) {
+        this.writer = writer;
+    }
+
+    @Override public void generate(ConstantNode constantNode) {
+        writer.write(constantNode.getValue().toString());
+    }
+
+    @Override public void generateDeclarationWithInitializer(DeclarationStatement declarationStatement) {
+        declarationStatement.getParameterExpression().getType().write(this);
+        writer.write(" ");
+        declarationStatement.getParameterExpression().write(this);
+        writer.write(" = ");
+        declarationStatement.getInitializer().write(this);
+    }
+
+    @Override public void generateDeclaration(DeclarationStatement declarationStatement) {
+        declarationStatement.getParameterExpression().getType().write(this);
+        writer.write(" ");
+        declarationStatement.getParameterExpression().write(this);
+    }
+
+    @Override public void generate(ParameterExpression parameterExpression) {
+        writer.write(parameterExpression.getName());
+    }
+
+    @Override public void generate(Primitive primitive) {
+        writer.write(primitive.getTypeString());
+    }
+
+    @Override public void generate(IfStatement ifStatement) {
+        writer.startLine("if (");
+        ifStatement.getCondition().write(this);
+        writer.write(") {\n");
+        writeBlock(ifStatement.getBody());
+        if (ifStatement.getOrElse() != null) {
+            writer.writeLine("} else {");
+            writeBlock(ifStatement.getOrElse());
+        }
+        writer.writeLine("}");
+    }
+
+    @Override public void writeBlock(Block statements) {
+        writer.startBlock();
+        for (Node statement : statements.getStatements()) {
+            // Dont to the wrapping for Statemetns
+            if (statement instanceof IfStatement) {
+                statement.write(this);
+            } else {
+                writer.startLine("");
+                statement.write(this);
+                writer.write(";");
+                writer.endLine();
+            }
+        }
+        writer.endBlock();
+    }
+
+    @Override public void generate(BinaryExpression binaryExpression) {
+        binaryExpression.getLeft().write(this);
+        writer.write(" ");
+        writer.write(getOperator(binaryExpression.getOp()));
+        writer.write(" ");
+        binaryExpression.getRight().write(this);
+    }
+
+    @Override public void generate(AssignementExpression assignementExpression) {
+        assignementExpression.getTarget().write(this);
+        writer.write(" = ");
+        assignementExpression.getValue().write(this);
+    }
+
+    @Override public void generateStaticCall(Method method, List<Node> arguments) {
+        writer.write(method.getType().getTypeString());
+        writer.write(".");
+        writer.write(method.getName());
+        writer.write("(");
+        generateArgumentList(arguments);
+        writer.write(")");
+    }
+
+    private void generateArgumentList(List<Node> arguments) {
+        for (int i = 0; i < arguments.size(); i++) {
+            arguments.get(i).write(this);
+            if (i < arguments.size() - 1) {
+                writer.write(", ");
+            }
+        }
+    }
+
+    @Override public void generateCall(Node target, Method method, List<Node> arguments) {
+        target.write(this);
+        writer.write(".");
+        writer.write(method.getName());
+        writer.write("(");
+        generateArgumentList(arguments);
+        writer.write(")");
+    }
+
+    @Override public void generate(NewExpression newExpression) {
+        writer.write("new ");
+        newExpression.getType().write(this);
+        writer.write("(");
+        generateArgumentList(newExpression.getArguments());
+        writer.write(")");
+    }
+
+    @Override public void generate(MethodDefinition methodDefinition) {
+        writer.startLine("public ");
+        // Special handling of VOID is necessary
+        if (methodDefinition.getResultType() == Primitive.VOID) {
+            writer.write("void");
+        } else {
+            methodDefinition.getResultType().write(this);
+        }
+        writer.write(" ");
+        writer.write(methodDefinition.getName());
+        writer.write("(");
+        for (int i = 0; i < methodDefinition.getParameters().size(); i++) {
+            methodDefinition.getParameters().get(i).getType().write(this);
+            writer.write(" ");
+            methodDefinition.getParameters().get(i).write(this);
+            if (i < methodDefinition.getParameters().size() - 1) {
+                writer.write(", ");
+            }
+        }
+        writer.write(") {");
+        writer.endLine();
+        methodDefinition.getBody().write(this);
+        writer.writeLine("}");
+    }
+
+    @Override public void generateReturn(Expression value) {
+        writer.write("return ");
+        value.write(this);
+    }
+
+    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+        // Add static?!
+        // Own File?
+        writer.write("public class ");
+        writer.write(className);
+        // TODO extends / implements
+        writer.write(" {");
+        writer.endLine();
+        writer.startBlock();
+
+        writer.writeLine("");
+        // Fields
+        for (FieldDeclaration field : fields) {
+            field.write(this);
+            writer.writeLine("");
+        }
+
+        // Constructors
+        for (ConstructorDeclaration constructor : constructors) {
+            this.generateConstructor(className, constructor.getParameters(), constructor.getBody());
+            writer.writeLine("");
+        }
+
+        // Methods
+        for (MethodDefinition method : methods) {
+            method.write(this);
+            writer.writeLine("");
+        }
+
+        writer.endBlock();
+        writer.write("}");
+        writer.endLine();
+    }
+
+    @Override public void generateFieldDeclaration(TypeNode type, String name) {
+        writer.startLine("public ");
+        type.write(this);
+        writer.write(" ");
+        writer.write(name);
+        writer.write(";");
+        writer.endLine();
+    }
+
+    @Override public void generateFieldReference(TypeNode type, String name) {
+        writer.write("this.");
+        writer.write(name);
+    }
+
+    @Override public void generateConstructor(String className, List<ParameterExpression> parameters, Block body) {
+        writer.startLine("public ");
+        writer.write(className);
+        writer.write("(");
+        for (int i = 0; i < parameters.size(); i++) {
+            parameters.get(i).getType().write(this);
+            writer.write(" ");
+            parameters.get(i).write(this);
+            if (i < parameters.size() - 1) {
+                writer.write(", ");
+            }
+        }
+        writer.write(") {");
+        writer.endLine();
+        body.write(this);
+        writer.writeLine("}");
+    }
+
+    private String getOperator(BinaryExpression.Operation op) {
+        switch (op) {
+            case EQ:
+                return "==";
+            case PLUS:
+                return "+";
+        }
+        throw new UnsupportedOperationException("The Operator " + op + " is currently not implemented!");
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Method.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Method.java
new file mode 100644
index 0000000..9cfdd0c
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Method.java
@@ -0,0 +1,51 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+/**
+ * Method Declaration
+ */
+public class Method implements Node {
+
+    private final TypeNode type;    // Type where this thing is defined on
+    private final String name;
+    private final TypeNode returnType;
+    private final List<TypeNode> parameterTypes;
+    private final List<TypeNode> expressionTypes;
+
+    public Method(TypeNode type, String name, TypeNode returnType, List<TypeNode> parameterTypes, List<TypeNode> expressionTypes) {
+        this.type = type;
+        this.name = name;
+        this.returnType = returnType;
+        this.parameterTypes = parameterTypes;
+        this.expressionTypes = expressionTypes;
+    }
+
+    public TypeNode getType() {
+        return type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public TypeNode getReturnType() {
+        return returnType;
+    }
+
+    public List<TypeNode> getParameterTypes() {
+        return parameterTypes;
+    }
+
+    public List<TypeNode> getExpressionTypes() {
+        return expressionTypes;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/MethodDefinition.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/MethodDefinition.java
new file mode 100644
index 0000000..b7f2249
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/MethodDefinition.java
@@ -0,0 +1,42 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public class MethodDefinition implements Node {
+
+    private final String name;
+    private final TypeNode resultType;
+    private final List<ParameterExpression> parameters;
+    private final Block body;
+
+    public MethodDefinition(String name, TypeNode resultType, List<ParameterExpression> parameters, Block body) {
+        this.name = name;
+        this.resultType = resultType;
+        this.parameters = parameters;
+        this.body = body;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public TypeNode getResultType() {
+        return resultType;
+    }
+
+    public List<ParameterExpression> getParameters() {
+        return parameters;
+    }
+
+    public Block getBody() {
+        return body;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generate(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NewExpression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NewExpression.java
new file mode 100644
index 0000000..1e4c467
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NewExpression.java
@@ -0,0 +1,26 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class NewExpression extends Expression {
+
+    private List<Node> arguments;
+
+    public NewExpression(TypeNode myClazz, Node... arguments) {
+        super(myClazz);
+        this.arguments = Arrays.asList(arguments);
+    }
+
+    public List<Node> getArguments() {
+        return arguments;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generate(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Node.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Node.java
new file mode 100644
index 0000000..e569b05
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Node.java
@@ -0,0 +1,9 @@
+package org.apache.plc4x.codegen.version2;
+
+public interface Node {
+
+    <T> T accept(NodeVisitor<T> visitor);
+
+    void write(Generator writer);
+
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NodeVisitor.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NodeVisitor.java
new file mode 100644
index 0000000..dc690d6
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/NodeVisitor.java
@@ -0,0 +1,10 @@
+package org.apache.plc4x.codegen.version2;
+
+public interface NodeVisitor<T> {
+
+    T visit(ConstantNode constantNode);
+
+    T visit(DeclarationStatement declarationStatement);
+
+    T visit(ParameterExpression parameterExpression);
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ParameterExpression.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ParameterExpression.java
new file mode 100644
index 0000000..8216e70
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ParameterExpression.java
@@ -0,0 +1,23 @@
+package org.apache.plc4x.codegen.version2;
+
+public class ParameterExpression extends Expression {
+
+    private final String name;
+
+    public ParameterExpression(TypeNode type, String name) {
+        super(type);
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return visitor.visit(this);
+    }
+
+    @Override public void write(Generator generator) {
+        generator.generate(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
new file mode 100644
index 0000000..279a525
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/PhpGenerator.java
@@ -0,0 +1,89 @@
+package org.apache.plc4x.codegen.version2;
+
+import java.util.List;
+
+public class PhpGenerator implements Generator {
+
+    private final CodeWriter writer;
+
+    public PhpGenerator(CodeWriter writer) {
+        this.writer = writer;
+    }
+
+    @Override public void generate(ConstantNode constantNode) {
+        this.writer.write(constantNode.getValue().toString());
+    }
+
+    @Override public void generateDeclarationWithInitializer(DeclarationStatement declarationStatement) {
+        this.writer.startLine("");
+        this.writer.write("$");
+        this.writer.write(declarationStatement.getParameterExpression().getName());
+        this.writer.write(" = ");
+        declarationStatement.getInitializer().write(this);
+        this.writer.write("\n");
+    }
+
+    @Override public void generateDeclaration(DeclarationStatement declarationStatement) {
+
+    }
+
+    @Override public void generate(ParameterExpression parameterExpression) {
+        // not needed
+    }
+
+    @Override public void generate(Primitive primitive) {
+        // Not needed, php is typeless
+    }
+
+    @Override public void generate(IfStatement ifStatement) {
+
+    }
+
+    @Override public void writeBlock(Block statements) {
+
+    }
+
+    @Override public void generate(BinaryExpression binaryExpression) {
+
+    }
+
+    @Override public void generate(AssignementExpression assignementExpression) {
+
+    }
+
+    @Override public void generateStaticCall(Method method, List<Node> constantNode) {
+
+    }
+
+    @Override public void generateCall(Node target, Method method, List<Node> constantNode) {
+
+    }
+
+    @Override public void generate(NewExpression newExpression) {
+
+    }
+
+    @Override public void generate(MethodDefinition methodDefinition) {
+
+    }
+
+    @Override public void generateReturn(Expression value) {
+
+    }
+
+    @Override public void generateClass(String namespace, String className, List<FieldDeclaration> fields, List<ConstructorDeclaration> constructors, List<MethodDefinition> methods) {
+
+    }
+
+    @Override public void generateFieldDeclaration(TypeNode type, String name) {
+
+    }
+
+    @Override public void generateFieldReference(TypeNode type, String name) {
+
+    }
+
+    @Override public void generateConstructor(String className, List<ParameterExpression> parameters, Block body) {
+
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Primitive.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Primitive.java
new file mode 100644
index 0000000..67f11bb
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Primitive.java
@@ -0,0 +1,19 @@
+package org.apache.plc4x.codegen.version2;
+
+public class Primitive extends TypeNode {
+
+    public static final TypeNode DOUBLE = new Primitive("double");
+    public static final TypeNode VOID = new Primitive("Void");
+
+    public Primitive(String typeString) {
+        super(typeString);
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator generator) {
+        generator.generate(this);
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ReturnStatement.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ReturnStatement.java
new file mode 100644
index 0000000..0e87d6f
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/ReturnStatement.java
@@ -0,0 +1,22 @@
+package org.apache.plc4x.codegen.version2;
+
+public class ReturnStatement extends Statement {
+
+    private final Expression value;
+
+    public ReturnStatement(Expression value) {
+        this.value = value;
+    }
+
+    public Expression getValue() {
+        return value;
+    }
+
+    @Override public <T> T accept(NodeVisitor<T> visitor) {
+        return null;
+    }
+
+    @Override public void write(Generator writer) {
+        writer.generateReturn(this.getValue());
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Statement.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Statement.java
new file mode 100644
index 0000000..128baa8
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/Statement.java
@@ -0,0 +1,4 @@
+package org.apache.plc4x.codegen.version2;
+
+public abstract class Statement implements Node {
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeNode.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeNode.java
new file mode 100644
index 0000000..6623eae
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeNode.java
@@ -0,0 +1,17 @@
+package org.apache.plc4x.codegen.version2;
+
+/**
+ * Stub for the Type System.
+ */
+public abstract class TypeNode implements Node {
+
+    private final String typeString;
+
+    protected TypeNode(String typeString) {
+        this.typeString = typeString;
+    }
+
+    String getTypeString() {
+        return this.typeString;
+    }
+}
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeUtil.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeUtil.java
new file mode 100644
index 0000000..fd6a010
--- /dev/null
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/version2/TypeUtil.java
@@ -0,0 +1,11 @@
+package org.apache.plc4x.codegen.version2;
+
+public class TypeUtil {
+
+    public static TypeNode infer(Object o) {
+        if (o instanceof Double) {
+            return Primitive.DOUBLE;
+        }
+        throw new UnsupportedOperationException("No type available for object " + o);
+    }
+}
diff --git a/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
new file mode 100644
index 0000000..ae4f312
--- /dev/null
+++ b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/JavaGeneratorTest.java
@@ -0,0 +1,236 @@
+package org.apache.plc4x.codegen.version2;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaGeneratorTest {
+
+    private CodeWriter writer;
+    private JavaGenerator generator;
+
+    @Before
+    public void setUp() throws Exception {
+        writer = new CodeWriter(4);
+        generator = new JavaGenerator(writer);
+    }
+
+    @Test
+    public void writeDeclaration() {
+        final DeclarationStatement stmt = new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "a"), new ConstantNode(5.0));
+        stmt.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("double a = 5.0", code);
+    }
+
+    @Test
+    public void ifStatement() {
+        final Statement stmt = new IfStatement(
+            new BinaryExpression(Primitive.DOUBLE, new ParameterExpression(Primitive.DOUBLE, "a"),
+                new ConstantNode(10.0),
+                BinaryExpression.Operation.EQ),
+            new Block(new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "b"), new ConstantNode(5.0))),
+            new Block(new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "b"), new ConstantNode(3.0)))
+        );
+
+        stmt.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("if (a == 10.0) {\n" +
+            "    double b = 5.0;\n" +
+            "} else {\n" +
+            "    double b = 3.0;\n" +
+            "}\n", code);
+    }
+
+    @Test
+    public void IfIf() {
+        final Statement stmt = new Block(Arrays.asList(
+            new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "c"), null),
+            new IfStatement(
+                new BinaryExpression(Primitive.DOUBLE, new ParameterExpression(Primitive.DOUBLE, "a"),
+                    new ConstantNode(10.0),
+                    BinaryExpression.Operation.EQ),
+                new Block(
+                    new IfStatement(
+                        new BinaryExpression(Primitive.DOUBLE, new ParameterExpression(Primitive.DOUBLE, "b"),
+                            new ConstantNode(10.0),
+                            BinaryExpression.Operation.EQ),
+                        new Block(
+                            new AssignementExpression(new ParameterExpression(Primitive.DOUBLE, "c"), new ConstantNode(5.0)),
+                            new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "d"), new ConstantNode(100.0))
+                        ),
+                        null
+                    )
+                ),
+                null
+            )));
+
+        stmt.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("    double c;\n" +
+            "    if (a == 10.0) {\n" +
+            "        if (b == 10.0) {\n" +
+            "            c = 5.0;\n" +
+            "            double d = 100.0;\n" +
+            "        }\n" +
+            "    }\n", code);
+    }
+
+    @Test
+    public void callStaticMethod() {
+        final TypeNode myClazz = new Primitive("MyClazz");
+        Expression expr = new CallExpression(new Method(myClazz, "toString", Primitive.VOID, Collections.singletonList(Primitive.DOUBLE), Collections.EMPTY_LIST), null, new ConstantNode(5.0));
+
+        expr.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("MyClazz.toString(5.0)", code);
+    }
+
+    @Test
+    public void callMethod() {
+        final TypeNode myClazz = new Primitive("MyClazz");
+        Expression expr = new CallExpression(new Method(myClazz, "toString", Primitive.VOID, Collections.singletonList(Primitive.DOUBLE), Collections.EMPTY_LIST), new ParameterExpression(myClazz, "a"), new ConstantNode(5.0));
+
+        expr.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("a.toString(5.0)", code);
+    }
+
+    @Test
+    public void complexCallAssignment() {
+        final TypeNode myClazz = new Primitive("MyClazz");
+        final ParameterExpression instance = new ParameterExpression(myClazz, "instance");
+        final Method getNumberMethod = new Method(myClazz, "getNumber", Primitive.DOUBLE, Collections.emptyList(), Collections.emptyList());
+        final Method staticMethod = new Method(myClazz, "staticMethod", Primitive.DOUBLE, Collections.emptyList(), Collections.emptyList());
+        Statement stmt = new Block(Arrays.asList(
+            new DeclarationStatement(instance, null),
+            new AssignementExpression(instance, new NewExpression(myClazz)),
+            new AssignementExpression(instance, new NewExpression(myClazz, new NewExpression(myClazz))),
+            new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "a"), new CallExpression(getNumberMethod, instance)),
+            new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "b"), new CallExpression(staticMethod, null))
+        ));
+
+        stmt.write(generator);
+        final String code = writer.getCode();
+        assertEquals("    MyClazz instance;\n" +
+            "    instance = new MyClazz();\n" +
+            "    instance = new MyClazz(new MyClazz());\n" +
+            "    double a = instance.getNumber();\n" +
+            "    double b = MyClazz.staticMethod();\n", code);
+    }
+
+    @Test
+    public void writeMethodDefinition() {
+        final ParameterExpression a = new ParameterExpression(Primitive.DOUBLE, "a");
+        final ParameterExpression b = new ParameterExpression(Primitive.DOUBLE, "b");
+        final MethodDefinition decl = new MethodDefinition("add", Primitive.DOUBLE,
+            Arrays.asList(
+                a,
+                b
+            ),
+            new Block(
+                new ReturnStatement(
+                    new BinaryExpression(a.getType(), a, b, BinaryExpression.Operation.PLUS)
+                )
+            )
+        );
+
+        decl.write(generator);
+        final String code = writer.getCode();
+        assertEquals("public double add(double a, double b) {\n" +
+            "    return a + b;\n" +
+            "}\n", code);
+    }
+
+    @Test
+    public void defineClass() {
+        final FieldDeclaration current = new FieldDeclaration(Primitive.DOUBLE, "current");
+
+        final ParameterExpression a = new ParameterExpression(Primitive.DOUBLE, "a");
+        final ParameterExpression b = new ParameterExpression(Primitive.DOUBLE, "b");
+        final MethodDefinition decl = new MethodDefinition("add", Primitive.DOUBLE,
+            Arrays.asList(
+                a,
+                b
+            ),
+            new Block(
+                new ReturnStatement(
+                    new BinaryExpression(a.getType(), a, b, BinaryExpression.Operation.PLUS)
+                )
+            )
+        );
+        final FieldReference currentRef = new FieldReference(Primitive.DOUBLE, "current");
+        final MethodDefinition inc = new MethodDefinition("inc", Primitive.VOID,
+            Collections.EMPTY_LIST,
+            new Block(
+                new AssignementExpression(
+                    currentRef,
+                    new BinaryExpression(currentRef.getType(), currentRef, new ConstantNode(1.0), BinaryExpression.Operation.PLUS)
+                )
+            )
+        );
+
+        final ClassDefinition clazz = new ClassDefinition("org.apache.plc4x", "MyClazz", Arrays.asList(current), Collections.emptyList(), Arrays.asList(inc, decl));
+
+        clazz.write(generator);
+        final String code = writer.getCode();
+        assertEquals("public class MyClazz {\n" +
+            "    \n" +
+            "    public double current;\n" +
+            "    \n" +
+            "    public void inc() {\n" +
+            "        this.current = this.current + 1.0;\n" +
+            "    }\n" +
+            "    \n" +
+            "    public double add(double a, double b) {\n" +
+            "        return a + b;\n" +
+            "    }\n" +
+            "    \n" +
+            "}\n", code);
+    }
+
+    @Test
+    public void defineClassWithConstructor() {
+        final FieldDeclaration current = new FieldDeclaration(Primitive.DOUBLE, "current");
+
+        final FieldReference currentRef = new FieldReference(Primitive.DOUBLE, "current");
+
+        final ParameterExpression value = new ParameterExpression(Primitive.DOUBLE, "value");
+        final ClassDefinition clazz = new ClassDefinition("org.apache.plc4x",
+            "MyClazz",
+            Arrays.asList(current),
+            Arrays.asList(
+                new ConstructorDeclaration(
+                    Collections.singletonList(value),
+                    new Block(new AssignementExpression(currentRef, value))
+                )
+            ),
+            Collections.emptyList());
+
+        clazz.write(generator);
+        final String code = writer.getCode();
+        assertEquals("public class MyClazz {\n" +
+            "    \n" +
+            "    public double current;\n" +
+            "    \n" +
+            "    public MyClazz(double value) {\n" +
+            "        this.current = value;\n" +
+            "    }\n" +
+            "    \n" +
+            "}\n", code);
+    }
+}
\ No newline at end of file
diff --git a/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/PhpGeneratorTest.java b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/PhpGeneratorTest.java
new file mode 100644
index 0000000..863c3c1
--- /dev/null
+++ b/sandbox/code-gen/src/test/java/org/apache/plc4x/codegen/version2/PhpGeneratorTest.java
@@ -0,0 +1,23 @@
+package org.apache.plc4x.codegen.version2;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class PhpGeneratorTest {
+
+    @Test
+    public void createSomeCode() {
+        final CodeWriter writer = new CodeWriter(4);
+
+        final DeclarationStatement stmt = new DeclarationStatement(new ParameterExpression(Primitive.DOUBLE, "a"), new ConstantNode(5.0));
+
+        final Generator generator = new PhpGenerator(writer);
+
+        stmt.write(generator);
+
+        final String code = writer.getCode();
+
+        assertEquals("$a = 5.0\n", code);
+    }
+}
\ No newline at end of file