Переглянути джерело

More work on Java

- Variable and parameter names should in most cases be stored in the generated code, toggleable with a boolean in JavaWriter
- TryCatch should work, except for returns or jumps outside the block as no finally's will be applied then, also, didnt yet start with Try with resources
- Started with classes, constructors, fields and methods
kindlich 6 роки тому
джерело
коміт
88cde8fb59
Не вдалося знайти GPG ключ що відповідає даному підпису
15 змінених файлів з 673 додано та 179 видалено
  1. 2
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/IDefinitionMember.java
  2. 5
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java
  3. 8
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaLocalVariableInfo.java
  4. 30
    14
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  5. 0
    1
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachVisitor.java
  6. 58
    4
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java
  7. 58
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeVisitor.java
  8. 190
    154
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
  9. 94
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaDefinitionVisitor.java
  10. 21
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaInitializedVariables.java
  11. 161
    0
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaMemberVisitor.java
  12. 23
    0
      ScriptingExample/scripts/classes.zs
  13. 15
    5
      ScriptingExample/scripts/moreHellos.zs
  14. 4
    0
      Shared/src/main/java/org/openzen/zenscript/shared/TagDictionary.java
  15. 4
    0
      Shared/src/main/java/org/openzen/zenscript/shared/Taggable.java

+ 2
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/IDefinitionMember.java Переглянути файл

@@ -31,4 +31,6 @@ public interface IDefinitionMember {
31 31
 	public <T> T getTag(Class<T> tag);
32 32
 	
33 33
 	public <T> void setTag(Class<T> tag, T value);
34
+
35
+	boolean hasTag(Class<?> tag);
34 36
 }

+ 5
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java Переглянути файл

@@ -14,6 +14,8 @@ import org.openzen.zenscript.codemodel.ScriptBlock;
14 14
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
15 15
 import org.openzen.zenscript.codemodel.statement.Statement;
16 16
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
17
+
18
+import org.openzen.zenscript.javabytecode.compiler.classes_structs.JavaDefinitionVisitor;
17 19
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
18 20
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
19 21
 import org.openzen.zenscript.shared.SourceFile;
@@ -149,6 +151,8 @@ public class JavaCompiler {
149 151
 	
150 152
 	public void addDefinition(HighLevelDefinition definition) {
151 153
 		// convert definition into java class
154
+		target.register(definition.name, definition.accept(new JavaDefinitionVisitor()));
155
+
152 156
 	}
153 157
 	
154 158
 	public void addScriptBlock(ScriptBlock script) {
@@ -170,6 +174,7 @@ public class JavaCompiler {
170 174
 		for (Statement statement : script.statements) {
171 175
 			statement.accept(statementVisitor);
172 176
 		}
177
+		target.register("Scripts", scriptsClassWriter.toByteArray());
173 178
 		statementVisitor.end();
174 179
 	}
175 180
 	

+ 8
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaLocalVariableInfo.java Переглянути файл

@@ -1,13 +1,20 @@
1 1
 package org.openzen.zenscript.javabytecode;
2 2
 
3
+import org.objectweb.asm.Label;
3 4
 import org.objectweb.asm.Type;
4 5
 
5 6
 public class JavaLocalVariableInfo {
6 7
     public final Type type;
7 8
     public final int local;
9
+    public final Label start;
10
+    public final String name;
11
+    public Label end;
8 12
 
9
-    public JavaLocalVariableInfo(Type type, int local) {
13
+    public JavaLocalVariableInfo(Type type, int local, Label start, String name) {
10 14
         this.type = type;
11 15
         this.local = local;
16
+        this.start = start;
17
+        this.end = start;
18
+        this.name = name;
12 19
     }
13 20
 }

+ 30
- 14
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Переглянути файл

@@ -1,11 +1,12 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3
-import com.sun.javafx.image.IntPixelGetter;
3
+import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5 5
 import org.openzen.zenscript.codemodel.definition.ZSPackage;
6 6
 import org.objectweb.asm.Type;
7 7
 import org.openzen.zenscript.codemodel.expression.*;
8 8
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
9
+import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
9 10
 import org.openzen.zenscript.implementations.IntRange;
10 11
 import org.openzen.zenscript.javabytecode.JavaBytecodeImplementation;
11 12
 import org.openzen.zenscript.javabytecode.JavaFieldInfo;
@@ -83,6 +84,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
83 84
 
84 85
     @Override
85 86
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
87
+
86 88
         return null;
87 89
     }
88 90
 
@@ -216,26 +218,31 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
216 218
 
217 219
     @Override
218 220
     public Void visitGetField(GetFieldExpression expression) {
219
-        if (!checkAndGetFieldInfo(expression.field))
221
+        javaWriter.loadObject(0);
222
+        if (!checkAndGetFieldInfo(expression.field, false))
220 223
             throw new IllegalStateException("Missing field info on a field member!");
221 224
         return null;
222 225
     }
223 226
 
224 227
     @Override
225 228
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
229
+        javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), expression.parameter.index + 1);
226 230
         return null;
227 231
     }
228 232
 
229 233
     @Override
230 234
     public Void visitGetLocalVariable(GetLocalVariableExpression expression) {
235
+        final Label label = new Label();
231 236
         final JavaLocalVariableInfo tag = expression.variable.getTag(JavaLocalVariableInfo.class);
237
+        tag.end = label;
232 238
         javaWriter.load(tag.type, tag.local);
239
+        javaWriter.label(label);
233 240
         return null;
234 241
     }
235 242
 
236 243
     @Override
237 244
     public Void visitGetStaticField(GetStaticFieldExpression expression) {
238
-        if (!checkAndGetFieldInfo(expression.field))
245
+        if (!checkAndGetFieldInfo(expression.field, true))
239 246
             throw new IllegalStateException("Missing field info on a field member!");
240 247
         return null;
241 248
     }
@@ -260,8 +267,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
260 267
     }
261 268
 
262 269
     @Override
263
-    public Void visitMakeConst(MakeConstExpression expression)
264
-    {
270
+    public Void visitMakeConst(MakeConstExpression expression) {
265 271
 
266 272
         return null;
267 273
     }
@@ -283,7 +289,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
283 289
 
284 290
     @Override
285 291
     public Void visitNew(NewExpression expression) {
286
-        String type = Type.getDescriptor(expression.type.accept(JavaTypeClassVisitor.INSTANCE));
292
+        final String type;
293
+        if(expression.type instanceof DefinitionTypeID)
294
+            type = ((DefinitionTypeID) expression.type).definition.name;
295
+        else
296
+            type = Type.getDescriptor(expression.type.accept(JavaTypeClassVisitor.INSTANCE));
297
+
287 298
         javaWriter.newObject(type);
288 299
         javaWriter.dup();
289 300
         StringBuilder signatureBuilder = new StringBuilder("(");
@@ -317,7 +328,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
317 328
 
318 329
     @Override
319 330
     public Void visitRange(RangeExpression expression) {
320
-        if(expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
331
+        if (expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
321 332
             throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Only integer ranges supported");
322 333
         javaWriter.newObject(IntRange.class);
323 334
         javaWriter.dup();
@@ -331,10 +342,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
331 342
 
332 343
     @Override
333 344
     public Void visitSetField(SetFieldExpression expression) {
345
+        javaWriter.loadObject(0);
334 346
         if (expression.field.isFinal)
335 347
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
336 348
         expression.value.accept(this);
337
-        if (!checkAndPutFieldInfo(expression.field))
349
+        if (!checkAndPutFieldInfo(expression.field, false))
338 350
             throw new IllegalStateException("Missing field info on a field member!");
339 351
         return null;
340 352
     }
@@ -349,7 +361,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
349 361
         if (expression.variable.isFinal)
350 362
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final variable!");
351 363
         expression.value.accept(this);
364
+        Label label = new Label();
365
+        javaWriter.label(label);
352 366
         final JavaLocalVariableInfo tag = expression.variable.getTag(JavaLocalVariableInfo.class);
367
+        tag.end = label;
353 368
 
354 369
         javaWriter.store(tag.type, tag.local);
355 370
 
@@ -361,7 +376,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
361 376
         if (expression.field.isFinal)
362 377
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
363 378
         expression.value.accept(this);
364
-        if (!checkAndPutFieldInfo(expression.field))
379
+        if (!checkAndPutFieldInfo(expression.field, true))
365 380
             throw new IllegalStateException("Missing field info on a field member!");
366 381
         return null;
367 382
     }
@@ -426,13 +441,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
426 441
     }
427 442
 
428 443
 
429
-    //TODO: Should isStatic go to the fieldInfo or stay here?
430 444
     //Will return true if a JavaFieldInfo.class tag exists, and will compile that tag
431
-    private boolean checkAndPutFieldInfo(DefinitionMember field) {
445
+    private boolean checkAndPutFieldInfo(DefinitionMember field, boolean isStatic) {
432 446
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
433 447
         if (fieldInfo == null)
434 448
             return false;
435
-        if (field.isStatic()) {
449
+        //TODO Remove isStatic
450
+        if (field.isStatic() || isStatic) {
436 451
             getJavaWriter().putStaticField(fieldInfo.javaClass.internalClassName, fieldInfo.name, fieldInfo.signature);
437 452
         } else {
438 453
             getJavaWriter().putField(fieldInfo.javaClass.internalClassName, fieldInfo.name, fieldInfo.signature);
@@ -440,11 +455,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
440 455
         return true;
441 456
     }
442 457
 
443
-    private boolean checkAndGetFieldInfo(DefinitionMember field) {
458
+    private boolean checkAndGetFieldInfo(DefinitionMember field, boolean isStatic) {
444 459
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
445 460
         if (fieldInfo == null)
446 461
             return false;
447
-        if (field.isStatic()) {
462
+        //TODO Remove isStatic
463
+        if (field.isStatic() || isStatic) {
448 464
             getJavaWriter().getStaticField(fieldInfo.javaClass.internalClassName, fieldInfo.name, fieldInfo.signature);
449 465
         } else {
450 466
             getJavaWriter().getField(fieldInfo.javaClass.internalClassName, fieldInfo.name, fieldInfo.signature);

+ 0
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachVisitor.java Переглянути файл

@@ -2,7 +2,6 @@ package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.Label;
4 4
 import org.openzen.zenscript.codemodel.iterator.ForeachIteratorVisitor;
5
-import org.openzen.zenscript.codemodel.member.CustomIteratorMember;
6 5
 import org.openzen.zenscript.codemodel.statement.Statement;
7 6
 import org.openzen.zenscript.codemodel.statement.VarStatement;
8 7
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;

+ 58
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java Переглянути файл

@@ -7,7 +7,7 @@ import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
7 7
 
8 8
 public class JavaStatementVisitor implements StatementVisitor<Void> {
9 9
     private final JavaWriter javaWriter;
10
-    private final JavaExpressionVisitor expressionVisitor;
10
+    public final JavaExpressionVisitor expressionVisitor;
11 11
 
12 12
     public JavaStatementVisitor(final JavaWriter javaWriter) {
13 13
         this.javaWriter = javaWriter;
@@ -83,7 +83,11 @@ public class JavaStatementVisitor implements StatementVisitor<Void> {
83 83
         //Create local variables
84 84
         for (VarStatement variable : statement.loopVariables) {
85 85
             final Type type = Type.getType(variable.type.accept(JavaTypeClassVisitor.INSTANCE));
86
-            variable.setTag(JavaLocalVariableInfo.class, new JavaLocalVariableInfo(type, javaWriter.local(type)));
86
+            final Label variableStart = new Label();
87
+            final JavaLocalVariableInfo info = new JavaLocalVariableInfo(type, javaWriter.local(type), variableStart, variable.name);
88
+            info.end = end;
89
+            variable.setTag(JavaLocalVariableInfo.class, info);
90
+            javaWriter.addVariableInfo(info);
87 91
         }
88 92
 
89 93
         //javaWriter.label(min);
@@ -136,18 +140,68 @@ public class JavaStatementVisitor implements StatementVisitor<Void> {
136 140
 
137 141
     @Override
138 142
     public Void visitTryCatch(TryCatchStatement statement) {
143
+        final Label tryCatchStart = new Label();
144
+        final Label tryFinish = new Label();
145
+        final Label tryCatchFinish = new Label();
146
+        final Label finallyStart = new Label();
147
+
148
+        javaWriter.label(tryCatchStart);
149
+        //TODO Check for returns or breaks out of the try-catch and inject finally block before them
150
+        statement.content.accept(this);
151
+        javaWriter.label(tryFinish);
152
+        if (statement.finallyClause != null)
153
+            statement.finallyClause.accept(this);
154
+        javaWriter.goTo(tryCatchFinish);
155
+
156
+        for (CatchClause catchClause : statement.catchClauses) {
157
+            final Label catchStart = new Label();
158
+            javaWriter.label(catchStart);
159
+
160
+            //final Type exceptionType = Type.getType(RuntimeException.class);
161
+            final Type exceptionType = Type.getType(catchClause.exceptionType.accept(JavaTypeClassVisitor.INSTANCE));
162
+            final int local = javaWriter.local(exceptionType);
163
+            javaWriter.store(exceptionType, local);
164
+
165
+            catchClause.content.accept(this);
166
+            final Label catchFinish = new Label();
167
+            javaWriter.label(catchFinish);
168
+
169
+            if (statement.finallyClause != null) {
170
+                statement.finallyClause.accept(this);
171
+                javaWriter.tryCatch(catchStart, catchFinish, finallyStart, null);
172
+            }
173
+
174
+            javaWriter.tryCatch(tryCatchStart, tryFinish, catchStart, exceptionType.getInternalName());
175
+            javaWriter.goTo(tryCatchFinish);
176
+        }
177
+
178
+        if (statement.finallyClause != null) {
179
+            javaWriter.label(finallyStart);
180
+            final int local = javaWriter.local(Object.class);
181
+            javaWriter.storeObject(local);
182
+            statement.finallyClause.accept(this);
183
+            javaWriter.loadObject(local);
184
+            javaWriter.aThrow();
185
+            javaWriter.tryCatch(tryCatchStart, tryFinish, finallyStart, null);
186
+        }
187
+        javaWriter.label(tryCatchFinish);
188
+
139 189
         return null;
140 190
     }
141 191
 
142 192
     @Override
143 193
     public Void visitVar(VarStatement statement) {
144
-        Type type = Type.getType(statement.type.accept(JavaTypeClassVisitor.INSTANCE));
194
+        Type type = statement.type.accept(JavaTypeVisitor.INSTANCE);
145 195
         int local = javaWriter.local(type);
146 196
         if (statement.initializer != null) {
147 197
             statement.initializer.accept(expressionVisitor);
148 198
             javaWriter.store(type, local);
149 199
         }
150
-        statement.setTag(JavaLocalVariableInfo.class, new JavaLocalVariableInfo(type, local));
200
+        final Label variableStart = new Label();
201
+        javaWriter.label(variableStart);
202
+        final JavaLocalVariableInfo info = new JavaLocalVariableInfo(type, local, variableStart, statement.name);
203
+        statement.setTag(JavaLocalVariableInfo.class, info);
204
+        javaWriter.addVariableInfo(info);
151 205
         return null;
152 206
     }
153 207
 

+ 58
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeVisitor.java Переглянути файл

@@ -0,0 +1,58 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.objectweb.asm.Type;
4
+import org.openzen.zenscript.codemodel.type.*;
5
+
6
+public class JavaTypeVisitor implements ITypeVisitor<Type> {
7
+    public static final JavaTypeVisitor INSTANCE = new JavaTypeVisitor();
8
+
9
+    @Override
10
+    public Type visitBasic(BasicTypeID basic) {
11
+        return Type.getType(basic.accept(JavaTypeClassVisitor.INSTANCE));
12
+    }
13
+
14
+    @Override
15
+    public Type visitArray(ArrayTypeID array) {
16
+        return Type.getType(array.accept(JavaTypeClassVisitor.INSTANCE));
17
+    }
18
+
19
+    @Override
20
+    public Type visitAssoc(AssocTypeID assoc) {
21
+        return Type.getType(assoc.accept(JavaTypeClassVisitor.INSTANCE));
22
+    }
23
+
24
+    @Override
25
+    public Type visitIterator(IteratorTypeID iterator) {
26
+        return Type.getType(iterator.accept(JavaTypeClassVisitor.INSTANCE));
27
+    }
28
+
29
+    @Override
30
+    public Type visitFunction(FunctionTypeID function) {
31
+        return Type.getType(function.accept(JavaTypeClassVisitor.INSTANCE));
32
+    }
33
+
34
+    @Override
35
+    public Type visitDefinition(DefinitionTypeID definition) {
36
+        return Type.getType("L" + definition + ";");
37
+    }
38
+
39
+    @Override
40
+    public Type visitGeneric(GenericTypeID generic) {
41
+        return Type.getType(generic.accept(JavaTypeClassVisitor.INSTANCE));
42
+    }
43
+
44
+    @Override
45
+    public Type visitRange(RangeTypeID range) {
46
+        return Type.getType(range.accept(JavaTypeClassVisitor.INSTANCE));
47
+    }
48
+
49
+    @Override
50
+    public Type visitConst(ConstTypeID type) {
51
+        return Type.getType(type.accept(JavaTypeClassVisitor.INSTANCE));
52
+    }
53
+
54
+    @Override
55
+    public Type visitOptional(OptionalTypeID optional) {
56
+        return Type.getType(optional.accept(JavaTypeClassVisitor.INSTANCE));
57
+    }
58
+}

+ 190
- 154
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 94
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaDefinitionVisitor.java Переглянути файл

@@ -0,0 +1,94 @@
1
+package org.openzen.zenscript.javabytecode.compiler.classes_structs;
2
+
3
+import org.objectweb.asm.ClassWriter;
4
+import org.objectweb.asm.Opcodes;
5
+import org.objectweb.asm.Type;
6
+import org.openzen.zenscript.codemodel.definition.*;
7
+import org.openzen.zenscript.codemodel.member.ConstructorMember;
8
+import org.openzen.zenscript.codemodel.member.FieldMember;
9
+import org.openzen.zenscript.codemodel.member.IDefinitionMember;
10
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
11
+import org.openzen.zenscript.javabytecode.JavaFieldInfo;
12
+import org.openzen.zenscript.javabytecode.compiler.JavaTypeClassVisitor;
13
+
14
+public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
15
+
16
+
17
+    @Override
18
+    public byte[] visitClass(ClassDefinition definition) {
19
+
20
+
21
+        Type superType;
22
+        if (definition.superType == null)
23
+            superType = Type.getType(Object.class);
24
+        else
25
+            superType = Type.getType(definition.superType.accept(JavaTypeClassVisitor.INSTANCE));
26
+
27
+        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
+
34
+            }
35
+        }
36
+        */
37
+
38
+
39
+        for (IDefinitionMember member : definition.members) {
40
+            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
+
50
+                    }
51
+                }
52
+            }
53
+        }
54
+
55
+        writer.visit(Opcodes.V1_8, definition.modifiers, definition.name, signature, superType.getInternalName(), null);
56
+        for (IDefinitionMember member : definition.members) {
57
+            member.accept(new JavaMemberVisitor(writer, definition.name));
58
+        }
59
+
60
+
61
+        writer.visitEnd();
62
+        return writer.toByteArray();
63
+    }
64
+
65
+    @Override
66
+    public byte[] visitInterface(InterfaceDefinition definition) {
67
+        return null;
68
+    }
69
+
70
+    @Override
71
+    public byte[] visitEnum(EnumDefinition definition) {
72
+        return null;
73
+    }
74
+
75
+    @Override
76
+    public byte[] visitStruct(StructDefinition definition) {
77
+        return null;
78
+    }
79
+
80
+    @Override
81
+    public byte[] visitFunction(FunctionDefinition definition) {
82
+        return null;
83
+    }
84
+
85
+    @Override
86
+    public byte[] visitExpansion(ExpansionDefinition definition) {
87
+        return null;
88
+    }
89
+
90
+    @Override
91
+    public byte[] visitAlias(AliasDefinition definition) {
92
+        return null;
93
+    }
94
+}

+ 21
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaInitializedVariables.java Переглянути файл

@@ -0,0 +1,21 @@
1
+package org.openzen.zenscript.javabytecode.compiler.classes_structs;
2
+
3
+import org.openzen.zenscript.codemodel.member.FieldMember;
4
+
5
+import java.util.ArrayList;
6
+import java.util.List;
7
+
8
+public class JavaInitializedVariables {
9
+    public final List<FieldMember> fields;
10
+    public final String owner;
11
+
12
+    public JavaInitializedVariables(String owner) {
13
+        this.owner = owner;
14
+        fields = new ArrayList<>();
15
+    }
16
+
17
+    public JavaInitializedVariables(List<FieldMember> fields, String owner) {
18
+        this.fields = fields;
19
+        this.owner = owner;
20
+    }
21
+}

+ 161
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/classes_structs/JavaMemberVisitor.java Переглянути файл

@@ -0,0 +1,161 @@
1
+package org.openzen.zenscript.javabytecode.compiler.classes_structs;
2
+
3
+import org.objectweb.asm.ClassWriter;
4
+import org.objectweb.asm.Label;
5
+import org.objectweb.asm.Type;
6
+import org.openzen.zenscript.codemodel.FunctionHeader;
7
+import org.openzen.zenscript.codemodel.FunctionParameter;
8
+import org.openzen.zenscript.codemodel.Modifiers;
9
+import org.openzen.zenscript.codemodel.member.*;
10
+import org.openzen.zenscript.codemodel.statement.Statement;
11
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
12
+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;
17
+
18
+public class JavaMemberVisitor implements MemberVisitor<Void> {
19
+
20
+    private final ClassWriter writer;
21
+    private final String className;
22
+
23
+    public JavaMemberVisitor(ClassWriter writer, String className) {
24
+        this.writer = writer;
25
+        this.className = className;
26
+    }
27
+
28
+    @Override
29
+    public Void visitField(FieldMember member) {
30
+
31
+        //TODO calc signature
32
+        String signature = null;
33
+        int modifier = member.modifiers;
34
+        if(member.isFinal)
35
+            modifier |= Modifiers.MODIFIER_FINAL;
36
+        writer.visitField(modifier, member.name, Type.getDescriptor(member.type.accept(JavaTypeClassVisitor.INSTANCE)), signature, null).visitEnd();
37
+        return null;
38
+    }
39
+
40
+    @Override
41
+    public Void visitConstructor(ConstructorMember member) {
42
+        final Label constructorStart = new Label();
43
+        final Label constructorEnd = new Label();
44
+        final JavaWriter constructorWriter = new JavaWriter(writer, member.modifiers, "<init>", calcDesc(member.header), calcSign(member.header), null);
45
+        constructorWriter.label(constructorStart);
46
+        for (FunctionParameter parameter : member.header.parameters) {
47
+            constructorWriter.nameVariable(parameter.index + 1, parameter.name, constructorStart, constructorEnd, Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
48
+        }
49
+        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(constructorWriter);
50
+        statementVisitor.start();
51
+
52
+        //TODO super constructor
53
+        constructorWriter.loadObject(0);
54
+        constructorWriter.invokeSpecial("java/lang/Object", "<init>", "()V");
55
+
56
+        if (member.hasTag(JavaInitializedVariables.class)) {
57
+            final JavaInitializedVariables tag = member.getTag(JavaInitializedVariables.class);
58
+            for (final FieldMember field : tag.fields) {
59
+                constructorWriter.loadObject(0);
60
+                field.initializer.accept(statementVisitor.expressionVisitor);
61
+                statementVisitor.getJavaWriter().putField(tag.owner, field.name, Type.getDescriptor(field.type.accept(JavaTypeClassVisitor.INSTANCE)));
62
+            }
63
+        }
64
+
65
+        for (Statement statement : member.body) {
66
+            statement.accept(statementVisitor);
67
+        }
68
+        constructorWriter.label(constructorEnd);
69
+        statementVisitor.end();
70
+        return null;
71
+    }
72
+
73
+    @Override
74
+    public Void visitMethod(MethodMember member) {
75
+        final Label methodStart = new Label();
76
+        final Label methodEnd = new Label();
77
+        final JavaWriter methodWriter = new JavaWriter(writer, member.modifiers, member.name, calcDesc(member.header), calcSign(member.header), null);
78
+        methodWriter.label(methodStart);
79
+        for (final FunctionParameter parameter : member.header.parameters) {
80
+            methodWriter.nameParameter(0, parameter.name);
81
+            methodWriter.nameVariable(parameter.index + (member.isStatic() ? 0 : 1), parameter.name, methodStart, methodEnd, Type.getType(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
82
+        }
83
+
84
+        final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(methodWriter);
85
+        statementVisitor.start();
86
+
87
+        for (Statement statement : member.body) {
88
+            statement.accept(statementVisitor);
89
+        }
90
+
91
+        methodWriter.label(methodEnd);
92
+        statementVisitor.end();
93
+        member.setTag(JavaMethodInfo.class, new JavaMethodInfo(new JavaClassInfo(className), member.name, calcSign(member.header), member.isStatic()));
94
+
95
+        return null;
96
+    }
97
+
98
+    @Override
99
+    public Void visitGetter(GetterMember member) {
100
+        return null;
101
+    }
102
+
103
+    @Override
104
+    public Void visitSetter(SetterMember member) {
105
+        return null;
106
+    }
107
+
108
+    @Override
109
+    public Void visitEnumConstant(EnumConstantMember member) {
110
+        return null;
111
+    }
112
+
113
+    @Override
114
+    public Void visitOperator(OperatorMember member) {
115
+        return null;
116
+    }
117
+
118
+    @Override
119
+    public Void visitCaster(CasterMember member) {
120
+        return null;
121
+    }
122
+
123
+    @Override
124
+    public Void visitCustomIterator(CustomIteratorMember member) {
125
+        return null;
126
+    }
127
+
128
+    @Override
129
+    public Void visitCaller(CallerMember member) {
130
+        return null;
131
+    }
132
+
133
+    @Override
134
+    public Void visitImplementation(ImplementationMember member) {
135
+        return null;
136
+    }
137
+
138
+    @Override
139
+    public Void visitInnerDefinition(InnerDefinitionMember member) {
140
+        return null;
141
+    }
142
+
143
+    private String calcDesc(FunctionHeader header) {
144
+        StringBuilder descBuilder = new StringBuilder("(");
145
+        for (FunctionParameter parameter : header.parameters) {
146
+            descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
147
+        }
148
+        descBuilder.append(")");
149
+        descBuilder.append(Type.getDescriptor(header.returnType.accept(JavaTypeClassVisitor.INSTANCE)));
150
+        return descBuilder.toString();
151
+    }
152
+
153
+    private String calcSign(FunctionHeader header) {
154
+        StringBuilder signatureBuilder = new StringBuilder("(");
155
+        for (FunctionParameter parameter : header.parameters) {
156
+            signatureBuilder.append(parameter.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
157
+        }
158
+        signatureBuilder.append(")").append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
159
+        return signatureBuilder.toString();
160
+    }
161
+}

+ 23
- 0
ScriptingExample/scripts/classes.zs Переглянути файл

@@ -0,0 +1,23 @@
1
+public class myTestClass {
2
+
3
+	var nonFinalInt as int = 10;
4
+	val finalInt as int = 20;
5
+
6
+	public this() {
7
+
8
+	}
9
+
10
+	public this(nonfinalInt as int) {
11
+		this.nonFinalInt = nonfinalInt;
12
+		println(nonfinalInt);
13
+	}
14
+
15
+	public test() as string {
16
+		return "TEST";
17
+	}
18
+}
19
+
20
+
21
+
22
+val tt = new myTestClass(666);
23
+println(tt.test());

+ 15
- 5
ScriptingExample/scripts/moreHellos.zs Переглянути файл

@@ -52,9 +52,9 @@ if (true) {
52 52
     } while true;
53 53
 }
54 54
 
55
-var test = ["1", "2", "3"];
55
+var testArray = ["1", "2", "3"];
56 56
 
57
-for item in test {
57
+for item in testArray {
58 58
 	println("test");
59 59
 	println(item);
60 60
 }
@@ -75,10 +75,20 @@ for i, item in [1, 5, 7] {
75 75
 	println(item + i);
76 76
 }
77 77
 
78
-for i in 10 .. 20 {
79
-	println(i);
78
+for myI in 10 .. 20 {
79
+	println(myI);
80 80
 }
81 81
 
82 82
 var lateInit as string;
83 83
 lateInit = "initialized later";
84
-println(lateInit);
84
+println(lateInit);
85
+
86
+
87
+
88
+
89
+
90
+/*
91
+catch e as string {
92
+	println("noLuv");
93
+}
94
+*/

+ 4
- 0
Shared/src/main/java/org/openzen/zenscript/shared/TagDictionary.java Переглянути файл

@@ -31,4 +31,8 @@ public class TagDictionary {
31 31
     public <T> T get(Class<T> cls) {
32 32
         return (T) tags.get(cls);
33 33
     }
34
+
35
+    public boolean hasTag(Class<?> cls) {
36
+        return tags.containsKey(cls);
37
+    }
34 38
 }

+ 4
- 0
Shared/src/main/java/org/openzen/zenscript/shared/Taggable.java Переглянути файл

@@ -19,4 +19,8 @@ public abstract class Taggable {
19 19
 	public final <T> T getTag(Class<T> cls) {
20 20
 		return tags.get(cls);
21 21
 	}
22
+
23
+	public final boolean hasTag(Class<?> cls) {
24
+		return tags.hasTag(cls);
25
+	}
22 26
 }

Завантаження…
Відмінити
Зберегти