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/25 14:20:18 UTC

[plc4x] 02/02: [CODE-GEN] Improvements in the code generation stuff.

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

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

commit ccc66617a0cd2edb7a45f6c9b78b1fee1a8ea283
Author: Julian Feinauer <j....@pragmaticminds.de>
AuthorDate: Sat May 25 16:20:10 2019 +0200

    [CODE-GEN] Improvements in the code generation stuff.
---
 .../java/org/apache/plc4x/codegen/api/Buffer.java  |  4 ++
 .../org/apache/plc4x/codegen/ast/Expressions.java  |  6 +-
 .../apache/plc4x/codegen/ast/JavaGenerator.java    |  6 +-
 .../apache/plc4x/codegen/ast/PythonGenerator.java  | 13 +++-
 .../org/apache/plc4x/codegen/ast/TypeUtil.java     |  2 +
 .../plugins/codegenerator/example/COTPPacket.java  | 18 ++++++
 .../plugins/codegenerator/example/Context.java     |  8 +++
 .../plugins/codegenerator/example/TPKTPacket.java  | 34 ++++++++++
 .../codegenerator/example/TPKTPacketFactory.java   | 17 +++++
 .../codegenerator/parser/MessageFormatParser.java  | 74 +++++++++++++++++++++-
 .../src/test/resources/specs/s7.spec               |  2 +-
 11 files changed, 173 insertions(+), 11 deletions(-)

diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
index 3cbf658..1896bcd 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/api/Buffer.java
@@ -28,4 +28,8 @@ public interface Buffer {
     Integer readUint16();
 
     Long readUint32();
+
+    void writeUint8(short n);
+
+    void writeUint16(int n);
 }
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
index cc9f505..1ec969e 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/Expressions.java
@@ -143,7 +143,7 @@ public class Expressions {
      * @param statements
      * @return
      */
-    public static Statement block(Node... statements) {
+    public static Block block(Node... statements) {
         return new Block(statements);
     }
 
@@ -259,9 +259,9 @@ public class Expressions {
     /**
      * Simple call to a method which throws no exception and that stuff.
      */
-    public static Expression call(Node target, String methodName, Node... arguments) {
+    public static Expression call(Node target, String methodName, TypeDefinition returnType, Node... arguments) {
         return new CallExpression(
-            new Method(UnknownType.INSTANCE, methodName, UnknownType.INSTANCE,
+            new Method(UnknownType.INSTANCE, methodName, returnType,
                 Collections.<TypeDefinition>emptyList(), Collections.<ExceptionType>emptyList()),
             target,
             arguments
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
index da87f90..9b04996 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/JavaGenerator.java
@@ -110,6 +110,8 @@ public class JavaGenerator implements Generator {
             // Dont to the wrapping for If Statements
             if (statement instanceof IfStatement) {
                 statement.write(this);
+            } else if (statement instanceof LineComment) { // Special handling of comments
+                statement.write(this);
             } else {
                 writer.startLine("");
                 statement.write(this);
@@ -313,7 +315,7 @@ public class JavaGenerator implements Generator {
     }
 
     @Override public void generateNoOp() {
-        writer.write(";");
+        //writer.write(";");
     }
 
     private String getOperator(BinaryExpression.Operation op) {
@@ -322,6 +324,8 @@ public class JavaGenerator implements Generator {
                 return "==";
             case PLUS:
                 return "+";
+            case NEQ:
+                return "!=";
         }
         throw new UnsupportedOperationException("The Operator " + op + " is currently not implemented!");
     }
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
index 9e4b17e..b026415 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/PythonGenerator.java
@@ -19,6 +19,7 @@ under the License.
 package org.apache.plc4x.codegen.ast;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 public class PythonGenerator implements Generator {
@@ -108,19 +109,23 @@ public class PythonGenerator implements Generator {
 
     @Override public void writeBlock(Block statements) {
         writer.startBlock();
-        if (statements.getStatements().isEmpty()) {
-            writer.writeLine("pass");
-        }
         for (Node statement : statements.getStatements()) {
             // Dont to the wrapping for If Statements
             if (statement instanceof IfStatement) {
                 statement.write(this);
+            } else if (statement instanceof LineComment) {
+                statement.write(this);
             } else {
                 writer.startLine("");
                 statement.write(this);
                 writer.endLine();
             }
         }
+        // Pass, if necessary
+        final long stmtCount = statements.getStatements().stream().filter(stmt -> !(stmt instanceof LineComment)).count();
+        if (stmtCount == 0) {
+            writer.writeLine("pass");
+        }
         writer.endBlock();
     }
 
@@ -312,6 +317,8 @@ public class PythonGenerator implements Generator {
                 return "==";
             case PLUS:
                 return "+";
+            case NEQ:
+                return "!=";
         }
         throw new UnsupportedOperationException("The Operator " + op + " is currently not implemented!");
     }
diff --git a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
index e27d2aa..28e185d 100644
--- a/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
+++ b/sandbox/code-gen/src/main/java/org/apache/plc4x/codegen/ast/TypeUtil.java
@@ -23,6 +23,8 @@ public class TypeUtil {
     public static TypeDefinition infer(Object o) {
         if (o instanceof Double) {
             return Primitive.DOUBLE;
+        } else if (o instanceof Integer) {
+            return Primitive.INTEGER;
         }
         throw new UnsupportedOperationException("No type available for object " + o);
     }
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java
new file mode 100644
index 0000000..76a458c
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/COTPPacket.java
@@ -0,0 +1,18 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+public class COTPPacket {
+
+    int getSize() {
+        return 0;
+    }
+
+    public static COTPPacket read(Buffer buffer, Context context) {
+        return null;
+    }
+
+    public void write(Buffer buffer) {
+
+    }
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java
new file mode 100644
index 0000000..bdc68b3
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/Context.java
@@ -0,0 +1,8 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+public class Context {
+
+    public void put(String key, Object value) {
+
+    }
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java
new file mode 100644
index 0000000..ede0f05
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacket.java
@@ -0,0 +1,34 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+/**
+ * Example... for
+ * <code>
+ *   [type 'TPKTPacket'
+ *     [const    uint8      'protocolId' '0x3']
+ *     [reserved uint8      '0x0']
+ *     [field    uint16     'len']
+ *     [field    COTPPacket 'payload'  {payloadLength: 'len - 4'}]
+ * ]
+ * </code>
+ */
+public class TPKTPacket {
+
+    public static final short PROTOCOL_ID = 0x3;
+    public static final short RESERVED_1 = 0x0;
+
+    private final COTPPacket payload;
+
+    public TPKTPacket(COTPPacket payload) {
+        this.payload = payload;
+    }
+
+    public void write(Buffer buffer) {
+        buffer.writeUint8(PROTOCOL_ID);
+        buffer.writeUint8(RESERVED_1);
+        buffer.writeUint16(payload.getSize() + 4);
+        payload.write(buffer);
+    }
+
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java
new file mode 100644
index 0000000..62837a3
--- /dev/null
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/example/TPKTPacketFactory.java
@@ -0,0 +1,17 @@
+package org.apache.plc4x.plugins.codegenerator.example;
+
+import org.apache.plc4x.codegen.api.Buffer;
+
+public class TPKTPacketFactory {
+
+    public TPKTPacket read(Buffer buffer) {
+        assert buffer.readUint8() == TPKTPacket.PROTOCOL_ID;
+        assert buffer.readUint8() == TPKTPacket.RESERVED_1;
+        int len = buffer.readUint16();
+        final Context context = new Context();
+        context.put("payloadLength", len - 4);
+        COTPPacket cotpPacket = COTPPacket.read(buffer, context);
+        return new TPKTPacket(cotpPacket);
+    }
+
+}
diff --git a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
index 9fa4f3c..202fa45 100644
--- a/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
+++ b/sandbox/plc4x-maven-plugin/src/main/java/org/apache/plc4x/plugins/codegenerator/parser/MessageFormatParser.java
@@ -23,13 +23,18 @@ import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
+import org.apache.plc4x.codegen.ast.BinaryExpression;
+import org.apache.plc4x.codegen.ast.BlockBuilder;
 import org.apache.plc4x.codegen.ast.ClassDeclaration;
 import org.apache.plc4x.codegen.ast.CodeWriter;
+import org.apache.plc4x.codegen.ast.Expression;
 import org.apache.plc4x.codegen.ast.Expressions;
 import org.apache.plc4x.codegen.ast.Generator;
 import org.apache.plc4x.codegen.ast.JavaGenerator;
+import org.apache.plc4x.codegen.ast.Method;
+import org.apache.plc4x.codegen.ast.ParameterExpression;
 import org.apache.plc4x.codegen.ast.Primitive;
-import org.apache.plc4x.codegen.ast.TypeDefinition;
+import org.apache.plc4x.codegen.ast.PythonGenerator;
 import org.apache.plc4x.codegen.util.PojoFactory;
 import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryLexer;
 import org.apache.plc4x.codegenerator.parser.imaginary.ImaginaryParser;
@@ -48,6 +53,7 @@ import org.apache.plc4x.plugins.codegenerator.model.fields.SwitchField;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -97,7 +103,7 @@ public class MessageFormatParser {
             final List<ClassBuilder> classes = new ArrayList<>();
             for (Map.Entry<String, ComplexType> entry : complexTypes.entrySet()) {
                 final CodeWriter writer = new CodeWriter(4);
-                final Generator generator = new JavaGenerator(writer);
+                final Generator generator = new PythonGenerator(writer);
                 System.out.println("// ----------------------");
                 System.out.println("//    " + entry.getKey() + "   ");
                 System.out.println("// ----------------------");
@@ -109,7 +115,7 @@ public class MessageFormatParser {
                     .collect(Collectors.toList());
                 final PojoFactory.PojoDescription pojoDesc = new PojoFactory.PojoDescription(entry.getKey(), fields);
                 final ClassDeclaration classDeclaration = factory.create(pojoDesc);
-                classDeclaration.write(generator);
+                // classDeclaration.write(generator);
                 // Output POJO
                 // System.out.println(writer.getCode());
 
@@ -120,14 +126,71 @@ public class MessageFormatParser {
                 classBuilder.withName(entry.getKey());
                 int constCount = 1;
                 int implicitCount = 1;
+                int tmpCount = 1;
+                BlockBuilder writerBuilder = new BlockBuilder();
+                BlockBuilder readerBuilder = new BlockBuilder();
+                final ParameterExpression _buffer = Expressions.parameter("buffer", Expressions.typeOf("Buffer"));
+                final Method _writeUint8 = Expressions.method(Expressions.typeOf("Buffer"), "writeUint8", Primitive.VOID, Collections.singletonList(Primitive.INTEGER), Collections.emptyList());
+                final Method _readUint8 = Expressions.method(Expressions.typeOf("Buffer"), "readUint8", Primitive.INTEGER, Collections.emptyList(), Collections.emptyList());
                 for (Field field : type.getFields()) {
                     if (field instanceof ArrayField) {
                         // do nothing
                         System.out.println("Skipping Array field...");
                     } else if (field instanceof ConstField) {
                         classBuilder.withConstant("CONST_" + constCount++, ((ConstField) field).getType().getName(), ((ConstField) field).getReferenceValue(), new ClassBuilder.Documentation("Constant expression"));
+
+                        String constString = ((ConstField) field).getReferenceValue().toString();
+                        constString = constString.replace("'", "");
+                        final Expression _const = Expressions.constant(Integer.decode(constString));
+
+                        // Writer
+                        writerBuilder.add(Expressions.comment("Constant"));
+                        writerBuilder.add(Expressions.call(
+                            _buffer,
+                            _writeUint8,
+                            _const
+                        ));
+
+                        // Reader
+                        readerBuilder.add(Expressions.comment("This should be a check on the expected value"));
+                        String tmpVar = "tmp" + tmpCount++;
+                        readerBuilder.add(Expressions.declaration(
+                            tmpVar,
+                            Expressions.call(_buffer, _readUint8)
+                        ));
+                        readerBuilder.add(Expressions.ifElse(
+                            Expressions.binaryExpression(Primitive.BOOLEAN, Expressions.parameter(tmpVar, Primitive.VOID), _const, BinaryExpression.Operation.NEQ),
+                            Expressions.block(
+                                Expressions.comment("We should throw an exception here")
+                            )
+                        ));
+
                     } else if (field instanceof SimpleField) {
                         classBuilder.withField(((SimpleField) field).getName(), ((SimpleField) field).getType().getName(), new ClassBuilder.Documentation("Simple Field..."));
+
+                        // Writer
+
+                        final ParameterExpression parameter = Expressions.parameter(
+                            ((SimpleField) field).getName(),
+                            Expressions.typeOf(((SimpleField) field).getType().getName())
+                        );
+                        if (((SimpleField) field).getType().getName().startsWith("uint")) {
+                            writerBuilder.add(Expressions.call(
+                                _buffer,
+                                _writeUint8,
+                                parameter
+                            ));
+                        } else {
+                            writerBuilder.add(Expressions.call(
+                                parameter,
+                                "write",
+                                Primitive.VOID,
+                                _buffer
+                            ));
+                        }
+
+                        // Reader
+
                     } else if (field instanceof ImplicitField) {
                         classBuilder.withField("implicit" + implicitCount, ((ImplicitField) field).getType().getName(), ((ImplicitField) field).getSerializationExpression(), new ClassBuilder.Documentation("Implicitly defined field"));
                     } else if (field instanceof DiscriminatorField) {
@@ -150,6 +213,11 @@ public class MessageFormatParser {
                 }
 
                 // System.out.println(classBuilder.toString());
+
+                // Print something here
+                writerBuilder.toBlock().write(generator);
+                readerBuilder.toBlock().write(generator);
+                System.out.println(writer.getCode());
             }
 
             // Now print all Classes
diff --git a/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
index f46d8a9..dcfd4ab 100644
--- a/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
+++ b/sandbox/plc4x-maven-plugin/src/test/resources/specs/s7.spec
@@ -5,7 +5,7 @@
 [type 'TPKTPacket'
     [const    uint8      'protocolId' '0x3']
     [reserved uint8      '0x0']
-    [implicit uint16     'len'     'payload.size + 4']
+    [field    uint16     'len']
     [field    COTPPacket 'payload'  {payloadLength: 'len - 4'}]
 ]