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:37 UTC
[plc4x] 01/02: Code generator is able to build Classes.
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