ソースを参照

Enums and this()

- Basic work on enumerations, they should work now
- this() constructor calls should work now
- Moved methods for calulcating descriptions and signatures to seperate utils class
kindlich 6年前
コミット
e202828906

+ 11
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaEnumInfo.java ファイルの表示

@@ -0,0 +1,11 @@
1
+package org.openzen.zenscript.javabytecode;
2
+
3
+import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
4
+
5
+public class JavaEnumInfo {
6
+    public final JavaStatementVisitor clinitVisitor;
7
+
8
+    public JavaEnumInfo(JavaStatementVisitor clinitVisitor) {
9
+        this.clinitVisitor = clinitVisitor;
10
+    }
11
+}

+ 28
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java ファイルの表示

@@ -0,0 +1,28 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.objectweb.asm.Type;
4
+import org.openzen.zenscript.codemodel.FunctionHeader;
5
+import org.openzen.zenscript.codemodel.FunctionParameter;
6
+
7
+public class CompilerUtils {
8
+    public static String calcDesc(FunctionHeader header, boolean isEnum) {
9
+        StringBuilder descBuilder = new StringBuilder("(");
10
+        if(isEnum)
11
+            descBuilder.append("Ljava/lang/String;I");
12
+        for (FunctionParameter parameter : header.parameters) {
13
+            descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
14
+        }
15
+        descBuilder.append(")");
16
+        descBuilder.append(Type.getDescriptor(header.returnType.accept(JavaTypeClassVisitor.INSTANCE)));
17
+        return descBuilder.toString();
18
+    }
19
+
20
+    public static String calcSign(FunctionHeader header, boolean isEnum) {
21
+        StringBuilder signatureBuilder = new StringBuilder("(");
22
+        for (FunctionParameter parameter : header.parameters) {
23
+            signatureBuilder.append(parameter.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
24
+        }
25
+        signatureBuilder.append(")").append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
26
+        return signatureBuilder.toString();
27
+    }
28
+}

+ 15
- 5
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java ファイルの表示

@@ -8,10 +8,7 @@ import org.openzen.zenscript.codemodel.expression.*;
8 8
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
9 9
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
10 10
 import org.openzen.zenscript.implementations.IntRange;
11
-import org.openzen.zenscript.javabytecode.JavaBytecodeImplementation;
12
-import org.openzen.zenscript.javabytecode.JavaFieldInfo;
13
-import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
14
-import org.openzen.zenscript.javabytecode.JavaMethodInfo;
11
+import org.openzen.zenscript.javabytecode.*;
15 12
 import org.openzen.zenscript.shared.CompileException;
16 13
 import org.openzen.zenscript.shared.CompileExceptionCode;
17 14
 
@@ -20,10 +17,16 @@ import java.util.Map;
20 17
 
21 18
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
22 19
     private final JavaWriter javaWriter;
20
+    private final boolean isInit;
23 21
 
24 22
 
25 23
     public JavaExpressionVisitor(final JavaWriter javaWriter) {
24
+        this(javaWriter, false);
25
+    }
26
+
27
+    public JavaExpressionVisitor(JavaWriter javaWriter, boolean isInit) {
26 28
         this.javaWriter = javaWriter;
29
+        this.isInit = isInit;
27 30
     }
28 31
 
29 32
     @Override
@@ -197,6 +200,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
197 200
 
198 201
     @Override
199 202
     public Void visitConstructorThisCall(ConstructorThisCallExpression expression) {
203
+        Type type = expression.objectType.accept(JavaTypeVisitor.INSTANCE);
204
+        //javaWriter.loadObject(0);
205
+        for (Expression argument : expression.arguments.arguments) {
206
+            argument.accept(this);
207
+        }
208
+        javaWriter.invokeSpecial(type.getInternalName(), "<init>", CompilerUtils.calcDesc(expression.constructor.header, expression.constructor.hasTag(JavaEnumInfo.class)));
200 209
         return null;
201 210
     }
202 211
 
@@ -352,7 +361,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
352 361
     @Override
353 362
     public Void visitSetField(SetFieldExpression expression) {
354 363
         javaWriter.loadObject(0);
355
-        if (expression.field.isFinal())
364
+        if (expression.field.isFinal() && !isInit)
356 365
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
357 366
         expression.value.accept(this);
358 367
         if (!checkAndPutFieldInfo(expression.field, false))
@@ -407,6 +416,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
407 416
 
408 417
     @Override
409 418
     public Void visitThis(ThisExpression expression) {
419
+        javaWriter.loadObject(0);
410 420
         return null;
411 421
     }
412 422
 

+ 11
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java ファイルの表示

@@ -8,10 +8,20 @@ import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
8 8
 public class JavaStatementVisitor implements StatementVisitor<Void> {
9 9
     private final JavaWriter javaWriter;
10 10
     public final JavaExpressionVisitor expressionVisitor;
11
+    private final boolean isInit;
11 12
 
12 13
     public JavaStatementVisitor(final JavaWriter javaWriter) {
14
+        this(javaWriter, false);
15
+    }
16
+
17
+    /**
18
+     * @param javaWriter the method writer that compiles the statement
19
+     * @param isInit is the method a class initializer
20
+     */
21
+    public JavaStatementVisitor(JavaWriter javaWriter, boolean isInit) {
13 22
         this.javaWriter = javaWriter;
14
-        this.expressionVisitor = new JavaExpressionVisitor(javaWriter);
23
+        this.expressionVisitor = new JavaExpressionVisitor(javaWriter, isInit);
24
+        this.isInit = isInit;
15 25
     }
16 26
 
17 27
     @Override

+ 136
- 28
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java ファイルの表示

@@ -4,12 +4,19 @@ import org.objectweb.asm.ClassWriter;
4 4
 import org.objectweb.asm.Opcodes;
5 5
 import org.objectweb.asm.Type;
6 6
 import org.openzen.zenscript.codemodel.definition.*;
7
+import org.openzen.zenscript.codemodel.expression.Expression;
8
+import org.openzen.zenscript.codemodel.expression.ExpressionVisitor;
7 9
 import org.openzen.zenscript.codemodel.member.ConstructorMember;
10
+import org.openzen.zenscript.codemodel.member.EnumConstantMember;
8 11
 import org.openzen.zenscript.codemodel.member.FieldMember;
9 12
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
10
-import org.openzen.zenscript.javabytecode.JavaClassInfo;
11
-import org.openzen.zenscript.javabytecode.JavaFieldInfo;
13
+import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
14
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
15
+import org.openzen.zenscript.javabytecode.JavaEnumInfo;
16
+import org.openzen.zenscript.javabytecode.compiler.JavaExpressionVisitor;
17
+import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
12 18
 import org.openzen.zenscript.javabytecode.compiler.JavaTypeClassVisitor;
19
+import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
13 20
 
14 21
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
15 22
 
@@ -18,58 +25,159 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
18 25
     public byte[] visitClass(ClassDefinition definition) {
19 26
 
20 27
 
21
-        Type superType;
28
+        final Type superType;
22 29
         if (definition.superType == null)
23 30
             superType = Type.getType(Object.class);
24 31
         else
25 32
             superType = Type.getType(definition.superType.accept(JavaTypeClassVisitor.INSTANCE));
26 33
 
27 34
         ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
28
-        String signature = null;
29
-        /* TODO: Calculate signature from generic parameters
30
-        if(!definition.genericParameters.isEmpty()) {
31
-            StringBuilder signatureBuilder = new StringBuilder();
32
-            for (TypeParameter genericParameter : definition.genericParameters) {
33 35
 
34
-            }
35
-        }
36
-        */
36
+        //TODO: Calculate signature from generic parameters
37
+        //TODO: Interfaces?
38
+        String signature = null;
37 39
 
38 40
 
41
+        writer.visit(Opcodes.V1_8, definition.modifiers, definition.name, signature, superType.getInternalName(), null);
39 42
         for (IDefinitionMember member : definition.members) {
40 43
             if (member instanceof ConstructorMember) {
41
-                for (IDefinitionMember member2 : definition.members) {
42
-                    if (member2 instanceof FieldMember) {
43
-                        if (!member2.hasTag(JavaClassInfo.class))
44
-                            member2.setTag(JavaFieldInfo.class, new JavaFieldInfo(new JavaClassInfo(definition.name), ((FieldMember) member2).name, Type.getDescriptor(((FieldMember) member2).type.accept(JavaTypeClassVisitor.INSTANCE))));
45
-                        if (!member.hasTag(JavaInitializedVariables.class))
46
-                            member.setTag(JavaInitializedVariables.class, new JavaInitializedVariables(definition.name));
47
-                        member.getTag(JavaInitializedVariables.class).fields.add((FieldMember) member2);
48
-
49
-
44
+                final ConstructorMember constructorMember = (ConstructorMember) member;
45
+
46
+
47
+                constructorMember.body.add(0, new ExpressionStatement(constructorMember.position, new Expression(constructorMember.position, BasicTypeID.VOID) {
48
+                    @Override
49
+                    public <T> T accept(ExpressionVisitor<T> visitor) {
50
+                        if (visitor instanceof JavaExpressionVisitor) {
51
+                            JavaWriter javaWriter = ((JavaExpressionVisitor) visitor).getJavaWriter();
52
+                            javaWriter.loadObject(0);
53
+                            //TODO Super constructor?
54
+                            javaWriter.invokeSpecial(Type.getInternalName(Object.class), "<init>", "()V");
55
+                            for (final IDefinitionMember definitionMember : definition.members) {
56
+                                if (definitionMember instanceof FieldMember && ((FieldMember) definitionMember).initializer != null) {
57
+                                    final FieldMember field = (FieldMember) definitionMember;
58
+                                    javaWriter.loadObject(0);
59
+                                    field.initializer.accept(visitor);
60
+                                    javaWriter.putField(definition.name, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
61
+                                }
62
+                            }
63
+                        }
64
+                        return null;
50 65
                     }
51
-                }
66
+                }));
52 67
             }
53
-        }
54
-
55
-        writer.visit(Opcodes.V1_8, definition.modifiers, definition.name, signature, superType.getInternalName(), null);
56
-        for (IDefinitionMember member : definition.members) {
57 68
             member.accept(new JavaMemberVisitor(writer, definition.name));
58
-        }
59 69
 
60 70
 
71
+        }
61 72
         writer.visitEnd();
62 73
         return writer.toByteArray();
63 74
     }
64 75
 
65 76
     @Override
66 77
     public byte[] visitInterface(InterfaceDefinition definition) {
67
-        return null;
78
+        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
79
+
80
+        //TODO: Calculate signature from generic parameters
81
+        //TODO: Extending Interfaces?
82
+        String signature = null;
83
+        writer.visit(Opcodes.V1_8, definition.modifiers | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, definition.name, signature, Type.getInternalName(Object.class), null);
84
+        for (IDefinitionMember member : definition.members) {
85
+            member.accept(new JavaMemberVisitor(writer, definition.name));
86
+        }
87
+        writer.visitEnd();
88
+        return writer.toByteArray();
68 89
     }
69 90
 
70 91
     @Override
71 92
     public byte[] visitEnum(EnumDefinition definition) {
72
-        return null;
93
+        final Type superType;
94
+        if (definition.superType == null)
95
+            superType = Type.getType(Object.class);
96
+        else
97
+            superType = Type.getType(definition.superType.accept(JavaTypeClassVisitor.INSTANCE));
98
+
99
+        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
100
+
101
+        writer.visit(Opcodes.V1_8, Opcodes.ACC_ENUM | Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL, definition.name, "Ljava/lang/Enum<L" + definition.name + ";>;", superType.getInternalName(), null);
102
+
103
+        for (IDefinitionMember member : definition.members) {
104
+            if (member instanceof EnumConstantMember) {
105
+                EnumConstantMember constantMember = (EnumConstantMember) member;
106
+                writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM, constantMember.name, "L" + definition.name + ";", null, null).visitEnd();
107
+            } else if (member instanceof ConstructorMember) {
108
+                member.setTag(JavaEnumInfo.class, null);
109
+            }
110
+        }
111
+
112
+        final JavaWriter clinitWriter = new JavaWriter(writer, true, Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
113
+        final JavaStatementVisitor clinitVisitor = new JavaStatementVisitor(clinitWriter, true);
114
+        clinitVisitor.start();
115
+        int constantCount = 0;
116
+        for (IDefinitionMember member : definition.members) {
117
+            if (member instanceof ConstructorMember) {
118
+                final ConstructorMember constructorMember = (ConstructorMember) member;
119
+
120
+
121
+                constructorMember.body.add(0, new ExpressionStatement(constructorMember.position, new Expression(constructorMember.position, BasicTypeID.VOID) {
122
+                    @Override
123
+                    public <T> T accept(ExpressionVisitor<T> visitor) {
124
+                        if (visitor instanceof JavaExpressionVisitor) {
125
+                            JavaWriter javaWriter = ((JavaExpressionVisitor) visitor).getJavaWriter();
126
+                            javaWriter.getVisitor().newLocal(Type.getType(String.class));
127
+                            javaWriter.getVisitor().newLocal(Type.getType(int.class));
128
+                            javaWriter.loadObject(0);
129
+                            javaWriter.loadObject(1);
130
+                            javaWriter.loadInt(2);
131
+                            //javaWriter.invokeSpecial(Type.getInternalName(Enum.class), "<init>", "(Ljava/lang/String;I)V");
132
+                        }
133
+                        return null;
134
+                    }
135
+                }));
136
+            } else if (member instanceof EnumConstantMember) {
137
+                ++constantCount;
138
+                member.setTag(JavaEnumInfo.class, new JavaEnumInfo(clinitVisitor));
139
+            }
140
+            member.accept(new JavaMemberVisitor(writer, definition.name));
141
+        }
142
+
143
+        clinitWriter.constant(constantCount);
144
+        clinitWriter.newArray(Type.getType("L" + definition.name + ";"));
145
+
146
+        for (IDefinitionMember member : definition.members) {
147
+            if(!(member instanceof EnumConstantMember)) continue;
148
+            final EnumConstantMember constantMember = (EnumConstantMember) member;
149
+            clinitWriter.dup();
150
+            clinitWriter.constant(constantMember.value);
151
+            clinitWriter.getStaticField(definition.name, constantMember.name, "L" + definition.name + ";");
152
+            clinitWriter.arrayStore(Type.getType("L" + definition.name + ";"));
153
+        }
154
+        clinitWriter.putStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
155
+        clinitVisitor.end();
156
+
157
+        //Enum Stuff(required!)
158
+        writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, "$VALUES", "[L" + definition.name + ";", null, null).visitEnd();
159
+
160
+        JavaWriter valuesWriter = new JavaWriter(writer, true, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, "values", "()[L" + definition.name + ";", null, null);
161
+        valuesWriter.start();
162
+        valuesWriter.getStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
163
+        valuesWriter.invokeVirtual("[L" + definition.name + ";", "clone", "()Ljava/lang/Object;");
164
+        valuesWriter.checkCast("[L" + definition.name + ";");
165
+        valuesWriter.returnObject();
166
+        valuesWriter.end();
167
+
168
+
169
+        JavaWriter valueOfWriter = new JavaWriter(writer, true, Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC, "valueOf", "(Ljava/lang/String;)L" + definition.name + ";", null, null);
170
+        valueOfWriter.start();
171
+        valueOfWriter.invokeStatic("java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
172
+        valueOfWriter.loadObject(0);
173
+        valueOfWriter.invokeStatic("java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
174
+        valueOfWriter.checkCast("L" + definition.name + ";");
175
+        valueOfWriter.returnObject();
176
+        valueOfWriter.end();
177
+
178
+
179
+        writer.visitEnd();
180
+        return writer.toByteArray();
73 181
     }
74 182
 
75 183
     @Override

+ 43
- 47
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java ファイルの表示

@@ -2,18 +2,20 @@ package org.openzen.zenscript.javabytecode.compiler.definitions;
2 2
 
3 3
 import org.objectweb.asm.ClassWriter;
4 4
 import org.objectweb.asm.Label;
5
+import org.objectweb.asm.Opcodes;
5 6
 import org.objectweb.asm.Type;
6
-import org.openzen.zenscript.codemodel.FunctionHeader;
7 7
 import org.openzen.zenscript.codemodel.FunctionParameter;
8 8
 import org.openzen.zenscript.codemodel.Modifiers;
9
+import org.openzen.zenscript.codemodel.expression.ConstructorThisCallExpression;
10
+import org.openzen.zenscript.codemodel.expression.Expression;
9 11
 import org.openzen.zenscript.codemodel.member.*;
12
+import org.openzen.zenscript.codemodel.statement.ExpressionStatement;
10 13
 import org.openzen.zenscript.codemodel.statement.Statement;
11 14
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
15
+import org.openzen.zenscript.javabytecode.JavaEnumInfo;
16
+import org.openzen.zenscript.javabytecode.JavaFieldInfo;
12 17
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
13
-import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
14
-import org.openzen.zenscript.javabytecode.compiler.JavaTypeClassVisitor;
15
-import org.openzen.zenscript.javabytecode.compiler.JavaTypeVisitor;
16
-import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
18
+import org.openzen.zenscript.javabytecode.compiler.*;
17 19
 
18 20
 public class JavaMemberVisitor implements MemberVisitor<Void> {
19 21
 
@@ -30,7 +32,9 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
30 32
 
31 33
         //TODO calc signature
32 34
         String signature = null;
33
-        writer.visitField(member.modifiers, member.name, Type.getDescriptor(member.type.accept(JavaTypeClassVisitor.INSTANCE)), signature, null).visitEnd();
35
+        final String descriptor = Type.getDescriptor(member.type.accept(JavaTypeClassVisitor.INSTANCE));
36
+        writer.visitField(member.modifiers, member.name, descriptor, signature, null).visitEnd();
37
+        member.setTag(JavaFieldInfo.class, new JavaFieldInfo(new JavaClassInfo(className), member.name, descriptor));
34 38
         return null;
35 39
     }
36 40
 
@@ -38,27 +42,17 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
38 42
     public Void visitConstructor(ConstructorMember member) {
39 43
         final Label constructorStart = new Label();
40 44
         final Label constructorEnd = new Label();
41
-        final JavaWriter constructorWriter = new JavaWriter(writer, member.modifiers, "<init>", calcDesc(member.header), calcSign(member.header), null);
45
+        final boolean isEnum = member.hasTag(JavaEnumInfo.class);
46
+        final JavaWriter constructorWriter = new JavaWriter(writer, isEnum ? Opcodes.ACC_PRIVATE : member.modifiers, "<init>", CompilerUtils.calcDesc(member.header, isEnum), CompilerUtils.calcSign(member.header, isEnum), null);
42 47
         constructorWriter.label(constructorStart);
43 48
         for (FunctionParameter parameter : member.header.parameters) {
49
+            if(isEnum)
50
+                parameter.index += 2;
44 51
             constructorWriter.nameVariable(parameter.index + 1, parameter.name, constructorStart, constructorEnd, Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
45 52
         }
46
-        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(constructorWriter);
53
+        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(constructorWriter, true);
47 54
         statementVisitor.start();
48 55
 
49
-        //TODO super constructor
50
-        constructorWriter.loadObject(0);
51
-        constructorWriter.invokeSpecial("java/lang/Object", "<init>", "()V");
52
-
53
-        if (member.hasTag(JavaInitializedVariables.class)) {
54
-            final JavaInitializedVariables tag = member.getTag(JavaInitializedVariables.class);
55
-            for (final FieldMember field : tag.fields) {
56
-                constructorWriter.loadObject(0);
57
-                field.initializer.accept(statementVisitor.expressionVisitor);
58
-                statementVisitor.getJavaWriter().putField(tag.owner, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
59
-            }
60
-        }
61
-
62 56
         for (Statement statement : member.body) {
63 57
             statement.accept(statementVisitor);
64 58
         }
@@ -71,23 +65,28 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
71 65
     public Void visitMethod(MethodMember member) {
72 66
         final Label methodStart = new Label();
73 67
         final Label methodEnd = new Label();
74
-        final JavaWriter methodWriter = new JavaWriter(writer, member.modifiers, member.name, calcDesc(member.header), calcSign(member.header), null);
68
+        final boolean isAbstract = member.body == null || member.body.isEmpty() || Modifiers.isAbstract(member.modifiers);
69
+        final JavaWriter methodWriter = new JavaWriter(writer, isAbstract ? member.modifiers | Opcodes.ACC_ABSTRACT : member.modifiers, member.name, CompilerUtils.calcDesc(member.header, false), CompilerUtils.calcSign(member.header, false), null);
75 70
         methodWriter.label(methodStart);
76 71
         for (final FunctionParameter parameter : member.header.parameters) {
77 72
             methodWriter.nameParameter(0, parameter.name);
78
-            methodWriter.nameVariable(parameter.index + (member.isStatic() ? 0 : 1), parameter.name, methodStart, methodEnd, Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
73
+            if (!isAbstract)
74
+                methodWriter.nameVariable(parameter.index + (member.isStatic() ? 0 : 1), parameter.name, methodStart, methodEnd, Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
79 75
         }
80 76
 
81 77
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(methodWriter);
82
-        statementVisitor.start();
83 78
 
84
-        for (Statement statement : member.body) {
85
-            statement.accept(statementVisitor);
79
+        if (!isAbstract) {
80
+            statementVisitor.start();
81
+            for (Statement statement : member.body) {
82
+                statement.accept(statementVisitor);
83
+            }
84
+
85
+            methodWriter.label(methodEnd);
86
+            statementVisitor.end();
86 87
         }
87 88
 
88
-        methodWriter.label(methodEnd);
89
-        statementVisitor.end();
90
-        member.setTag(JavaMethodInfo.class, new JavaMethodInfo(new JavaClassInfo(className), member.name, calcSign(member.header), member.isStatic()));
89
+        member.setTag(JavaMethodInfo.class, new JavaMethodInfo(new JavaClassInfo(className), member.name, CompilerUtils.calcSign(member.header, false), member.isStatic()));
91 90
 
92 91
         return null;
93 92
     }
@@ -104,6 +103,21 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
104 103
 
105 104
     @Override
106 105
     public Void visitEnumConstant(EnumConstantMember member) {
106
+        final JavaStatementVisitor clinitVisitor = member.getTag(JavaEnumInfo.class).clinitVisitor;
107
+        final JavaWriter clinitWriter = clinitVisitor.getJavaWriter();
108
+        final String internalName = member.constructor.type.accept(JavaTypeVisitor.INSTANCE).getInternalName();
109
+
110
+        clinitWriter.newObject(internalName);
111
+        clinitWriter.dup();
112
+        clinitWriter.constant(member.name);
113
+        clinitWriter.constant(member.value);
114
+        for (Expression argument : member.constructor.arguments.arguments) {
115
+            argument.accept(clinitVisitor.expressionVisitor);
116
+        }
117
+        clinitWriter.invokeSpecial(internalName, "<init>", CompilerUtils.calcDesc(member.constructor.constructor.header, true));
118
+        clinitWriter.putStaticField(internalName, member.name, "L" + internalName + ";");
119
+
120
+
107 121
         return null;
108 122
     }
109 123
 
@@ -137,22 +151,4 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
137 151
         return null;
138 152
     }
139 153
 
140
-    private String calcDesc(FunctionHeader header) {
141
-        StringBuilder descBuilder = new StringBuilder("(");
142
-        for (FunctionParameter parameter : header.parameters) {
143
-            descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
144
-        }
145
-        descBuilder.append(")");
146
-        descBuilder.append(Type.getDescriptor(header.returnType.accept(JavaTypeClassVisitor.INSTANCE)));
147
-        return descBuilder.toString();
148
-    }
149
-
150
-    private String calcSign(FunctionHeader header) {
151
-        StringBuilder signatureBuilder = new StringBuilder("(");
152
-        for (FunctionParameter parameter : header.parameters) {
153
-            signatureBuilder.append(parameter.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
154
-        }
155
-        signatureBuilder.append(")").append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
156
-        return signatureBuilder.toString();
157
-    }
158 154
 }

+ 57
- 1
ScriptingExample/scripts/classes.zs ファイルの表示

@@ -20,4 +20,60 @@ public class myTestClass {
20 20
 
21 21
 
22 22
 val tt = new myTestClass(666);
23
-println(tt.test());
23
+println(tt.test());
24
+
25
+public interface myTestInterface {
26
+	test() as string;
27
+}
28
+
29
+
30
+public enum myTestEnum {
31
+	ADD(6),
32
+    SUB(6),
33
+    MUL(7),
34
+    DIV(7),
35
+    MOD(7),
36
+    CAT(6),
37
+    OR(4),
38
+    AND(4),
39
+    XOR(4),
40
+    NEG(8),
41
+    NOT(8),
42
+    INVERT(8),
43
+    CONTAINS(5),
44
+    COMPARE(5),
45
+    ASSIGN(0),
46
+    ADDASSIGN(0),
47
+    SUBASSIGN(0),
48
+    MULASSIGN(0),
49
+    DIVASSIGN(0),
50
+    MODASSIGN(0),
51
+    CATASSIGN(0),
52
+    ORASSIGN(0),
53
+    ANDASSIGN(0),
54
+    XORASSIGN(0),
55
+    ANDAND(3),
56
+    OROR(2),
57
+    TERNARY(1),
58
+    COALESCE(2),
59
+    INCREMENT(8),
60
+    DECREMENT(8),
61
+    MEMBER(9),
62
+    RANGE(9),
63
+    INDEX(9),
64
+    CALL(9),
65
+    CAST(9),
66
+    PRIMARY(10);
67
+
68
+	private val priority as int;
69
+	private val isCommutative as bool;
70
+
71
+	this(i as int) {
72
+		this(i, false);
73
+	}
74
+
75
+	this(i as int, isCommutative as bool) {
76
+		this.priority = i;
77
+		this.isCommutative = isCommutative;
78
+		}
79
+}

読み込み中…
キャンセル
保存