Quellcode durchsuchen

Merge branch 'development' of git.openzen.org:kindlich/ZenScript into development

Stan Hebben vor 6 Jahren
Ursprung
Commit
9221f0b8e4

+ 90
- 33
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java Datei anzeigen

@@ -6,6 +6,7 @@ import org.openzen.zenscript.codemodel.FunctionHeader;
6 6
 import org.openzen.zenscript.codemodel.FunctionParameter;
7 7
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 8
 import org.openzen.zenscript.codemodel.Modifiers;
9
+import org.openzen.zenscript.codemodel.expression.*;
9 10
 import org.openzen.zenscript.codemodel.member.FieldMember;
10 11
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
11 12
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -76,37 +77,93 @@ public class CompilerUtils {
76 77
     public static String calcClasName(CodePosition position) {
77 78
         return position.filename.substring(0, position.filename.lastIndexOf('.')).replace("/", "_");
78 79
     }
79
-	
80
-	public static void tagMethodParameters(FunctionHeader header, boolean isStatic) {
81
-		JavaTypeVisitor typeVisitor = new JavaTypeVisitor();
82
-		for (int i = 0; i < header.parameters.length; i++) {
83
-			FunctionParameter parameter = header.parameters[i];
84
-			Type parameterType = parameter.type.accept(typeVisitor);
85
-			parameter.setTag(JavaParameterInfo.class, new JavaParameterInfo(isStatic ? i : i + 1, parameterType));
86
-		}
87
-	}
88
-	
89
-	public static void tagConstructorParameters(FunctionHeader header, boolean isEnum) {
90
-		JavaTypeVisitor typeVisitor = new JavaTypeVisitor();
91
-		for (int i = 0; i < header.parameters.length; i++) {
92
-			FunctionParameter parameter = header.parameters[i];
93
-			Type parameterType = parameter.type.accept(typeVisitor);
94
-			parameter.setTag(JavaParameterInfo.class, new JavaParameterInfo(isEnum ? i + 3 : i + 1, parameterType));
95
-		}
96
-	}
97
-	
98
-	public static void writeDefaultFieldInitializers(JavaWriter constructorWriter, HighLevelDefinition definition, boolean staticFields) {
99
-		JavaExpressionVisitor expressionVisitor = new JavaExpressionVisitor(constructorWriter);
100
-		for (final IDefinitionMember definitionMember : definition.members) {
101
-			if (!(definitionMember instanceof FieldMember))
102
-				continue;
103
-			
104
-			FieldMember field = (FieldMember) definitionMember;
105
-			if (field.isStatic() == staticFields && field.initializer != null) {
106
-				constructorWriter.loadObject(0);
107
-				field.initializer.accept(expressionVisitor);
108
-				constructorWriter.putField(definition.name, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
109
-			}
110
-		}
111
-	}
80
+
81
+    public static void tagMethodParameters(FunctionHeader header, boolean isStatic) {
82
+        JavaTypeVisitor typeVisitor = new JavaTypeVisitor();
83
+        for (int i = 0; i < header.parameters.length; i++) {
84
+            FunctionParameter parameter = header.parameters[i];
85
+            Type parameterType = parameter.type.accept(typeVisitor);
86
+            parameter.setTag(JavaParameterInfo.class, new JavaParameterInfo(isStatic ? i : i + 1, parameterType));
87
+        }
88
+    }
89
+
90
+    public static void tagConstructorParameters(FunctionHeader header, boolean isEnum) {
91
+        JavaTypeVisitor typeVisitor = new JavaTypeVisitor();
92
+        for (int i = 0; i < header.parameters.length; i++) {
93
+            FunctionParameter parameter = header.parameters[i];
94
+            Type parameterType = parameter.type.accept(typeVisitor);
95
+            parameter.setTag(JavaParameterInfo.class, new JavaParameterInfo(isEnum ? i + 3 : i + 1, parameterType));
96
+        }
97
+    }
98
+
99
+    public static void writeDefaultFieldInitializers(JavaWriter constructorWriter, HighLevelDefinition definition, boolean staticFields) {
100
+        JavaExpressionVisitor expressionVisitor = new JavaExpressionVisitor(constructorWriter);
101
+        for (final IDefinitionMember definitionMember : definition.members) {
102
+            if (!(definitionMember instanceof FieldMember))
103
+                continue;
104
+
105
+            FieldMember field = (FieldMember) definitionMember;
106
+            if (field.isStatic() == staticFields && field.initializer != null) {
107
+                if (!staticFields)
108
+                    constructorWriter.loadObject(0);
109
+                field.initializer.accept(expressionVisitor);
110
+                if (staticFields)
111
+                    constructorWriter.putStaticField(definition.name, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
112
+                else
113
+                    constructorWriter.putField(definition.name, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
114
+            }
115
+        }
116
+    }
117
+
118
+
119
+    public static int getKeyForSwitch(Expression expression) {
120
+        if (expression.type instanceof BasicTypeID)
121
+            switch ((BasicTypeID) expression.type) {
122
+                case BOOL:
123
+                    if (expression instanceof ConstantBoolExpression)
124
+                        return ((ConstantBoolExpression) expression).value ? 1 : 0;
125
+                    break;
126
+                case BYTE:
127
+                    if (expression instanceof ConstantByteExpression)
128
+                        return ((ConstantByteExpression) expression).value;
129
+                    break;
130
+                case SBYTE:
131
+                    if (expression instanceof ConstantSByteExpression)
132
+                        return ((ConstantSByteExpression) expression).value;
133
+                    break;
134
+                case SHORT:
135
+                    if(expression instanceof ConstantShortExpression)
136
+                        return ((ConstantShortExpression) expression).value;
137
+                    break;
138
+                case USHORT:
139
+                    if (expression instanceof ConstantUShortExpression)
140
+                        return ((ConstantUShortExpression) expression).value;
141
+                    break;
142
+                case INT:
143
+                    if (expression instanceof ConstantIntExpression)
144
+                        return ((ConstantIntExpression) expression).value;
145
+                    break;
146
+                case UINT:
147
+                    if (expression instanceof ConstantUIntExpression)
148
+                        return ((ConstantUIntExpression) expression).value;
149
+                    break;
150
+                case LONG:
151
+                    if(expression instanceof ConstantLongExpression)
152
+                        return (int)((ConstantLongExpression) expression).value;
153
+                    break;
154
+                case ULONG:
155
+                    if(expression instanceof ConstantULongExpression)
156
+                        return (int)((ConstantULongExpression) expression).value;
157
+                    break;
158
+                case CHAR:
159
+                    if(expression instanceof ConstantCharExpression)
160
+                        return ((ConstantCharExpression) expression).value;
161
+                    break;
162
+                case STRING:
163
+                    if(expression instanceof ConstantStringExpression)
164
+                        return ((ConstantStringExpression) expression).value.hashCode();
165
+                    break;
166
+            }
167
+            throw new RuntimeException("Cannot switch over expression " + expression);
168
+    }
112 169
 }

+ 72
- 7
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java Datei anzeigen

@@ -3,12 +3,18 @@ package org.openzen.zenscript.javabytecode.compiler;
3 3
 import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5 5
 import org.openzen.zenscript.codemodel.statement.*;
6
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
7
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
6 8
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
9
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
10
+
11
+import java.util.Arrays;
12
+import java.util.List;
7 13
 
8 14
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
9 15
     private final JavaWriter javaWriter;
10 16
     public final JavaExpressionVisitor expressionVisitor;
11
-	
17
+
12 18
     /**
13 19
      * @param javaWriter the method writer that compiles the statement
14 20
      */
@@ -19,7 +25,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
19 25
 
20 26
     @Override
21 27
     public Boolean visitBlock(BlockStatement statement) {
22
-		Boolean returns = false;
28
+        Boolean returns = false;
23 29
         for (Statement statement1 : statement.statements) {
24 30
             returns = statement1.accept(this);
25 31
         }
@@ -134,11 +140,70 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
134 140
         javaWriter.returnType(Type.getType(statement.value.type.accept(JavaTypeClassVisitor.INSTANCE)));
135 141
         return true;
136 142
     }
137
-	
138
-	@Override
139
-	public Boolean visitSwitch(SwitchStatement statement) {
140
-		throw new UnsupportedOperationException("Not yet implemented!");
141
-	}
143
+
144
+    @Override
145
+    public Boolean visitSwitch(SwitchStatement statement) {
146
+
147
+        final Label start = new Label();
148
+        final Label end = new Label();
149
+
150
+        if (statement.label == null)
151
+            statement.label = javaWriter.createLabelName() + "Switch";
152
+
153
+        javaWriter.putNamedLabel(start, statement.label + "_start");
154
+        javaWriter.putNamedLabel(end, statement.label + "_end");
155
+
156
+
157
+        javaWriter.label(start);
158
+        statement.value.accept(expressionVisitor);
159
+        if(statement.value.type == BasicTypeID.STRING)
160
+            javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
161
+        boolean out = false;
162
+
163
+        final boolean hasNoDefault = hasNoDefault(statement);
164
+
165
+        final List<SwitchCase> cases = statement.cases;
166
+
167
+        final int[] keys = new int[hasNoDefault ? cases.size() : cases.size() - 1];
168
+        final Label[] labels = new Label[keys.length];
169
+        final Label defaultLabel = new Label();
170
+
171
+        Arrays.parallelSetAll(labels, value -> new Label());
172
+
173
+        int i = 0;
174
+        for (final SwitchCase switchCase : cases)
175
+            if (switchCase.value != null)
176
+                keys[i++] = CompilerUtils.getKeyForSwitch(switchCase.value);
177
+
178
+        javaWriter.lookupSwitch(defaultLabel, keys, labels);
179
+
180
+        i = 0;
181
+        for (final SwitchCase switchCase : cases) {
182
+            if (hasNoDefault || switchCase.value != null) {
183
+                javaWriter.label(labels[i++]);
184
+            } else {
185
+                javaWriter.label(defaultLabel);
186
+            }
187
+            for (Statement statement1 : switchCase.statements) {
188
+                out |= statement1.accept(this);
189
+            }
190
+        }
191
+
192
+        if(hasNoDefault)
193
+            javaWriter.label(defaultLabel);
194
+
195
+        javaWriter.label(end);
196
+
197
+
198
+        //throw new UnsupportedOperationException("Not yet implemented!");
199
+        return out;
200
+    }
201
+
202
+    private boolean hasNoDefault(SwitchStatement switchStatement) {
203
+        for (SwitchCase switchCase : switchStatement.cases)
204
+            if (switchCase.value == null) return false;
205
+        return true;
206
+    }
142 207
 
143 208
     @Override
144 209
     public Boolean visitThrow(ThrowStatement statement) {

+ 4
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java Datei anzeigen

@@ -1128,6 +1128,10 @@ public class JavaWriter {
1128 1128
             visitor.visitParameter(name, modifier);
1129 1129
     }
1130 1130
 
1131
+    public void lookupSwitch(Label defaultLabel, int[] keys, Label[] labels) {
1132
+        visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1133
+    }
1134
+
1131 1135
     public void addVariableInfo(JavaLocalVariableInfo info) {
1132 1136
         localVariableInfos.add(info);
1133 1137
     }

+ 3
- 44
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java Datei anzeigen

@@ -97,21 +97,14 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
97 97
 
98 98
         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);
99 99
 
100
-        for (IDefinitionMember member : definition.members) {
101
-            if (member instanceof EnumConstantMember) {
102
-                EnumConstantMember constantMember = (EnumConstantMember) member;
103
-                writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM, constantMember.name, "L" + definition.name + ";", null, null).visitEnd();
104
-            }
105
-        }
106
-
107 100
 		JavaClassInfo toClass = new JavaClassInfo(definition.name, true);
108
-		writeEnumStaticInitializer(definition, toClass, writer);
109 101
 
110 102
         //Enum Stuff(required!)
111 103
         writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, "$VALUES", "[L" + definition.name + ";", null, null).visitEnd();
112
-		
104
+
105
+        final JavaMemberVisitor visitor = new JavaMemberVisitor(writer, toClass, definition);
113 106
         for (IDefinitionMember member : definition.members) {
114
-            member.accept(new JavaMemberVisitor(writer, toClass, definition));
107
+            member.accept(visitor);
115 108
         }
116 109
 		
117 110
 		JavaClassInfo arrayClass = new JavaClassInfo("[L" + definition.name + ";");
@@ -140,40 +133,6 @@ public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
140 133
         writer.visitEnd();
141 134
         return writer.toByteArray();
142 135
     }
143
-	
144
-	private void writeEnumStaticInitializer(EnumDefinition definition, JavaClassInfo toClass, ClassWriter writer) {
145
-		JavaMethodInfo clinitInfo = new JavaMethodInfo(toClass, "<clinit>", "()V", Opcodes.ACC_STATIC);
146
-        final JavaWriter clinitWriter = new JavaWriter(writer, clinitInfo, definition, null, null);
147
-        final JavaStatementVisitor clinitVisitor = new JavaStatementVisitor(clinitWriter);
148
-        clinitVisitor.start();
149
-		
150
-		List<EnumConstantMember> enumConstants = definition.getEnumConstants();
151
-		for (EnumConstantMember enumConstant : enumConstants) {
152
-			final String internalName = enumConstant.constructor.type.accept(JavaTypeVisitor.INSTANCE).getInternalName();
153
-
154
-			clinitWriter.newObject(internalName);
155
-			clinitWriter.dup();
156
-			clinitWriter.constant(enumConstant.name);
157
-			clinitWriter.constant(enumConstant.value);
158
-			for (Expression argument : enumConstant.constructor.arguments.arguments) {
159
-				argument.accept(clinitVisitor.expressionVisitor);
160
-			}
161
-			clinitWriter.invokeSpecial(internalName, "<init>", CompilerUtils.calcDesc(enumConstant.constructor.constructor.header, true));
162
-			clinitWriter.putStaticField(internalName, enumConstant.name, "L" + internalName + ";");
163
-		}
164
-
165
-        clinitWriter.constant(enumConstants.size());
166
-        clinitWriter.newArray(Type.getType("L" + definition.name + ";"));
167
-
168
-        for (EnumConstantMember enumConstant : enumConstants) {
169
-            clinitWriter.dup();
170
-            clinitWriter.constant(enumConstant.value);
171
-            clinitWriter.getStaticField(definition.name, enumConstant.name, "L" + definition.name + ";");
172
-            clinitWriter.arrayStore(Type.getType("L" + definition.name + ";"));
173
-        }
174
-        clinitWriter.putStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
175
-        clinitVisitor.end();
176
-	}
177 136
 
178 137
     @Override
179 138
     public byte[] visitStruct(StructDefinition definition) {

+ 100
- 76
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaMemberVisitor.java Datei anzeigen

@@ -1,7 +1,5 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler.definitions;
2 2
 
3
-import java.util.ArrayList;
4
-import java.util.List;
5 3
 import org.objectweb.asm.ClassWriter;
6 4
 import org.objectweb.asm.Label;
7 5
 import org.objectweb.asm.Opcodes;
@@ -10,6 +8,7 @@ import org.openzen.zenscript.codemodel.FunctionParameter;
10 8
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 9
 import org.openzen.zenscript.codemodel.Modifiers;
12 10
 import org.openzen.zenscript.codemodel.definition.EnumDefinition;
11
+import org.openzen.zenscript.codemodel.expression.Expression;
13 12
 import org.openzen.zenscript.codemodel.member.*;
14 13
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
15 14
 import org.openzen.zenscript.javabytecode.JavaFieldInfo;
@@ -17,17 +16,25 @@ import org.openzen.zenscript.javabytecode.JavaMethodInfo;
17 16
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
18 17
 import org.openzen.zenscript.javabytecode.compiler.*;
19 18
 
19
+import java.util.List;
20
+
20 21
 public class JavaMemberVisitor implements MemberVisitor<Void> {
21 22
 
22 23
     private final ClassWriter writer;
23
-	private final JavaClassInfo toClass;
24
-	private final HighLevelDefinition definition;
25
-	private final List<StaticInitializerMember> staticInitializers = new ArrayList<>();
24
+    private final JavaClassInfo toClass;
25
+    private final HighLevelDefinition definition;
26
+    private final JavaStatementVisitor clinitStatementVisitor;
27
+    private EnumDefinition enumDefinition = null;
26 28
 
27 29
     public JavaMemberVisitor(ClassWriter writer, JavaClassInfo toClass, HighLevelDefinition definition) {
28 30
         this.writer = writer;
29
-		this.toClass = toClass;
30
-		this.definition = definition;
31
+        this.toClass = toClass;
32
+        this.definition = definition;
33
+
34
+        final JavaWriter javaWriter = new JavaWriter(writer, new JavaMethodInfo(toClass, "<clinit>", "()V", 0), definition, null, null);
35
+        this.clinitStatementVisitor = new JavaStatementVisitor(javaWriter);
36
+        this.clinitStatementVisitor.start();
37
+        CompilerUtils.writeDefaultFieldInitializers(javaWriter, definition, true);
31 38
     }
32 39
 
33 40
     @Override
@@ -36,52 +43,52 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
36 43
         //TODO calc signature
37 44
         String signature = null;
38 45
         final String descriptor = Type.getDescriptor(member.type.accept(JavaTypeClassVisitor.INSTANCE));
39
-        writer.visitField(member.modifiers, member.name, descriptor, signature, null).visitEnd();
46
+        writer.visitField(CompilerUtils.calcAccess(member.modifiers), member.name, descriptor, signature, null).visitEnd();
40 47
         member.setTag(JavaFieldInfo.class, new JavaFieldInfo(toClass, member.name, descriptor));
41 48
         return null;
42 49
     }
43 50
 
44 51
     @Override
45 52
     public Void visitConstructor(ConstructorMember member) {
46
-		final boolean isEnum = definition instanceof EnumDefinition;
47
-		String descriptor = CompilerUtils.calcDesc(member.header, isEnum);
48
-		final JavaMethodInfo method = new JavaMethodInfo(toClass, "<init>", descriptor, isEnum ? Opcodes.ACC_PRIVATE : CompilerUtils.calcAccess(member.modifiers));
49
-		
53
+        final boolean isEnum = definition instanceof EnumDefinition;
54
+        String descriptor = CompilerUtils.calcDesc(member.header, isEnum);
55
+        final JavaMethodInfo method = new JavaMethodInfo(toClass, "<init>", descriptor, isEnum ? Opcodes.ACC_PRIVATE : CompilerUtils.calcAccess(member.modifiers));
56
+
50 57
         final Label constructorStart = new Label();
51 58
         final Label constructorEnd = new Label();
52 59
         final JavaWriter constructorWriter = new JavaWriter(writer, method, definition, CompilerUtils.calcSign(member.header, isEnum), null);
53 60
         constructorWriter.label(constructorStart);
54
-		CompilerUtils.tagConstructorParameters(member.header, isEnum);
61
+        CompilerUtils.tagConstructorParameters(member.header, isEnum);
55 62
         for (FunctionParameter parameter : member.header.parameters) {
56 63
             constructorWriter.nameVariable(
57
-					parameter.getTag(JavaParameterInfo.class).index,
58
-					parameter.name,
59
-					constructorStart,
60
-					constructorEnd,
61
-					Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
64
+                    parameter.getTag(JavaParameterInfo.class).index,
65
+                    parameter.name,
66
+                    constructorStart,
67
+                    constructorEnd,
68
+                    Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
62 69
         }
63
-		
70
+
64 71
         final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(constructorWriter);
65 72
         statementVisitor.start();
66
-		
67
-		if (!member.isConstructorForwarded()) {
68
-			if (isEnum) {
69
-				System.out.println("Writing enum constructor");
70
-				constructorWriter.getVisitor().newLocal(Type.getType(String.class));
71
-				constructorWriter.getVisitor().newLocal(Type.getType(int.class));
72
-				constructorWriter.loadObject(0);
73
-				constructorWriter.loadObject(1);
74
-				constructorWriter.loadInt(2);
75
-				constructorWriter.invokeSpecial(Type.getInternalName(Enum.class), "<init>", "(Ljava/lang/String;I)V");
76
-			} else if (definition.superType == null) {
77
-				System.out.println("Writing regular constructor");
78
-				constructorWriter.load(Type.getType(Object.class), 0);
79
-				constructorWriter.invokeSpecial(Type.getInternalName(Object.class), "<init>", "()V");
80
-			}
81
-			
82
-			CompilerUtils.writeDefaultFieldInitializers(constructorWriter, definition, false);
83
-		}
84
-		
73
+
74
+        if (!member.isConstructorForwarded()) {
75
+            if (isEnum) {
76
+                System.out.println("Writing enum constructor");
77
+                constructorWriter.getVisitor().newLocal(Type.getType(String.class));
78
+                constructorWriter.getVisitor().newLocal(Type.getType(int.class));
79
+                constructorWriter.loadObject(0);
80
+                constructorWriter.loadObject(1);
81
+                constructorWriter.loadInt(2);
82
+                constructorWriter.invokeSpecial(Type.getInternalName(Enum.class), "<init>", "(Ljava/lang/String;I)V");
83
+            } else if (definition.superType == null) {
84
+                System.out.println("Writing regular constructor");
85
+                constructorWriter.load(Type.getType(Object.class), 0);
86
+                constructorWriter.invokeSpecial(Type.getInternalName(Object.class), "<init>", "()V");
87
+            }
88
+
89
+            CompilerUtils.writeDefaultFieldInitializers(constructorWriter, definition, false);
90
+        }
91
+
85 92
         member.body.accept(statementVisitor);
86 93
         constructorWriter.label(constructorEnd);
87 94
         statementVisitor.end();
@@ -90,18 +97,18 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
90 97
 
91 98
     @Override
92 99
     public Void visitMethod(MethodMember member) {
93
-		CompilerUtils.tagMethodParameters(member.header, member.isStatic());
94
-		
100
+        CompilerUtils.tagMethodParameters(member.header, member.isStatic());
101
+
95 102
         final boolean isAbstract = member.body == null || Modifiers.isAbstract(member.modifiers);
96
-		int modifiers = (isAbstract ? Opcodes.ACC_ABSTRACT : 0)
97
-				| (member.isStatic() ? Opcodes.ACC_STATIC : 0)
98
-				| CompilerUtils.calcAccess(member.modifiers);
99
-		final JavaMethodInfo method = new JavaMethodInfo(
100
-				toClass,
101
-				member.name,
102
-				CompilerUtils.calcSign(member.header, false),
103
-				modifiers);
104
-		
103
+        int modifiers = (isAbstract ? Opcodes.ACC_ABSTRACT : 0)
104
+                | (member.isStatic() ? Opcodes.ACC_STATIC : 0)
105
+                | CompilerUtils.calcAccess(member.modifiers);
106
+        final JavaMethodInfo method = new JavaMethodInfo(
107
+                toClass,
108
+                member.name,
109
+                CompilerUtils.calcSign(member.header, false),
110
+                modifiers);
111
+
105 112
         final Label methodStart = new Label();
106 113
         final Label methodEnd = new Label();
107 114
         final JavaWriter methodWriter = new JavaWriter(writer, method, definition, CompilerUtils.calcSign(member.header, false), null);
@@ -116,7 +123,7 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
116 123
 
117 124
         if (!isAbstract) {
118 125
             statementVisitor.start();
119
-			member.body.accept(statementVisitor);
126
+            member.body.accept(statementVisitor);
120 127
             methodWriter.label(methodEnd);
121 128
             statementVisitor.end();
122 129
         }
@@ -137,6 +144,23 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
137 144
 
138 145
     @Override
139 146
     public Void visitEnumConstant(EnumConstantMember member) {
147
+        writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM, member.name, "L" + definition.name + ";", null, null).visitEnd();
148
+        final String internalName = member.constructor.type.accept(JavaTypeVisitor.INSTANCE).getInternalName();
149
+        final JavaWriter clinitWriter = clinitStatementVisitor.getJavaWriter();
150
+        clinitWriter.newObject(internalName);
151
+        clinitWriter.dup();
152
+        clinitWriter.constant(member.name);
153
+        clinitWriter.constant(member.value);
154
+        for (Expression argument : member.constructor.arguments.arguments) {
155
+            argument.accept(clinitStatementVisitor.expressionVisitor);
156
+        }
157
+
158
+        clinitWriter.invokeSpecial(internalName, "<init>", CompilerUtils.calcDesc(member.constructor.constructor.header, true));
159
+        clinitWriter.putStaticField(internalName, member.name, "L" + internalName + ";");
160
+
161
+
162
+        enumDefinition = (EnumDefinition) member.definition;
163
+
140 164
         return null;
141 165
     }
142 166
 
@@ -170,30 +194,30 @@ public class JavaMemberVisitor implements MemberVisitor<Void> {
170 194
         return null;
171 195
     }
172 196
 
173
-	@Override
174
-	public Void visitStaticInitializer(StaticInitializerMember member) {
175
-		staticInitializers.add(member);
176
-		return null;
177
-	}
178
-	
179
-	public void end() {
180
-		final JavaMethodInfo method = new JavaMethodInfo(toClass, "<clinit>", "()V", 0);
181
-		
182
-        final Label constructorStart = new Label();
183
-        final Label constructorEnd = new Label();
184
-        final JavaWriter constructorWriter = new JavaWriter(writer, method, definition, null, null);
185
-        constructorWriter.label(constructorStart);
186
-		
187
-        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(constructorWriter);
188
-        statementVisitor.start();
189
-		
190
-		CompilerUtils.writeDefaultFieldInitializers(constructorWriter, definition, true);
191
-		
192
-		for (StaticInitializerMember member : staticInitializers) {
193
-	        member.body.accept(statementVisitor);
194
-		}
195
-		
196
-        constructorWriter.label(constructorEnd);
197
-        statementVisitor.end();
198
-	}
197
+    @Override
198
+    public Void visitStaticInitializer(StaticInitializerMember member) {
199
+        member.body.accept(clinitStatementVisitor);
200
+        return null;
201
+    }
202
+
203
+    public void end() {
204
+
205
+        if (enumDefinition != null) {
206
+            final JavaWriter clinitWriter = clinitStatementVisitor.getJavaWriter();
207
+            final List<EnumConstantMember> enumConstants = enumDefinition.getEnumConstants();
208
+            clinitWriter.constant(enumConstants.size());
209
+            clinitWriter.newArray(Type.getType("L" + definition.name + ";"));
210
+
211
+            for (EnumConstantMember enumConstant : enumConstants) {
212
+                clinitWriter.dup();
213
+                clinitWriter.constant(enumConstant.value);
214
+                clinitWriter.getStaticField(definition.name, enumConstant.name, "L" + definition.name + ";");
215
+                clinitWriter.arrayStore(Type.getType("L" + definition.name + ";"));
216
+            }
217
+            clinitWriter.putStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
218
+        }
219
+
220
+
221
+        clinitStatementVisitor.end();
222
+    }
199 223
 }

+ 4
- 0
ScriptingExample/scripts/classes.zs Datei anzeigen

@@ -3,6 +3,8 @@ public class myTestClass {
3 3
 	var nonFinalInt as int = 10;
4 4
 	val finalInt as int = 20;
5 5
 
6
+	static var staticNonFinalInt as int = 10;
7
+
6 8
 	public this() {
7 9
 
8 10
 	}
@@ -68,6 +70,8 @@ public enum myTestEnum {
68 70
 	private val priority as int;
69 71
 	private val isCommutative as bool;
70 72
 
73
+	public static val test as int = 10;
74
+
71 75
 	this(i as int) {
72 76
 		this(i, false);
73 77
 	}

+ 18
- 0
ScriptingExample/scripts/switch.zs Datei anzeigen

@@ -0,0 +1,18 @@
1
+val test as int = 10;
2
+
3
+
4
+switch test {
5
+	case 1 : println("yay"); break;
6
+	case 10 : println("yo");
7
+	case 100 : println("y");
8
+	default: println("yup");
9
+}
10
+
11
+
12
+val test2 as string = "hello";
13
+
14
+switch test2 {
15
+	case "bye" : println("hello");
16
+	case "hello" : println("goodbye");
17
+	default: println("hellogoodbye");
18
+}

Laden…
Abbrechen
Speichern