Browse Source

Merge branch 'development_kindlich' into development

# Conflicts:
#	JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
#	JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
Stan Hebben 6 years ago
parent
commit
c367e51ea6

+ 5
- 5
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/implementations/IntRange.java View File

1
 package org.openzen.zenscript.implementations;
1
 package org.openzen.zenscript.implementations;
2
 
2
 
3
 public class IntRange {
3
 public class IntRange {
4
-    public final int min;
5
-    public final int max;
4
+    public final int from;
5
+    public final int to;
6
 
6
 
7
 
7
 
8
-    public IntRange(int min, int max) {
9
-        this.min = min;
10
-        this.max = max;
8
+    public IntRange(int from, int to) {
9
+        this.from = from;
10
+        this.to = to;
11
     }
11
     }
12
 }
12
 }

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaModule.java View File

43
 		}
43
 		}
44
 	}
44
 	}
45
 	
45
 	
46
-	private class ScriptClassLoader extends ClassLoader {
46
+	public class ScriptClassLoader extends ClassLoader {
47
 		private final Map<String, Class> customClasses = new HashMap<>();
47
 		private final Map<String, Class> customClasses = new HashMap<>();
48
 
48
 
49
 		@Override
49
 		@Override

+ 54
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java View File

1
 package org.openzen.zenscript.javabytecode.compiler;
1
 package org.openzen.zenscript.javabytecode.compiler;
2
 
2
 
3
+import org.objectweb.asm.ClassWriter;
3
 import org.objectweb.asm.Opcodes;
4
 import org.objectweb.asm.Opcodes;
4
 import org.objectweb.asm.Type;
5
 import org.objectweb.asm.Type;
5
 import org.openzen.zencode.shared.CodePosition;
6
 import org.openzen.zencode.shared.CodePosition;
18
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
19
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
19
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
20
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
20
 import org.openzen.zenscript.codemodel.type.ITypeID;
21
 import org.openzen.zenscript.codemodel.type.ITypeID;
22
+import org.openzen.zenscript.javabytecode.JavaModule;
21
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
23
 import org.openzen.zenscript.javabytecode.JavaParameterInfo;
22
 
24
 
25
+import java.io.FileNotFoundException;
26
+import java.io.FileOutputStream;
27
+import java.io.IOException;
28
+import java.util.HashMap;
29
+import java.util.Map;
30
+
23
 public class CompilerUtils {
31
 public class CompilerUtils {
24
     public static String calcDesc(FunctionHeader header, boolean isEnum) {
32
     public static String calcDesc(FunctionHeader header, boolean isEnum) {
25
         StringBuilder descBuilder = new StringBuilder("(");
33
         StringBuilder descBuilder = new StringBuilder("(");
26
         if (isEnum)
34
         if (isEnum)
27
             descBuilder.append("Ljava/lang/String;I");
35
             descBuilder.append("Ljava/lang/String;I");
28
         for (FunctionParameter parameter : header.parameters) {
36
         for (FunctionParameter parameter : header.parameters) {
29
-            descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
37
+            //descBuilder.append(Type.getDescriptor(parameter.type.accept(JavaTypeClassVisitor.INSTANCE)));
38
+            descBuilder.append(parameter.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
30
         }
39
         }
31
         descBuilder.append(")");
40
         descBuilder.append(")");
32
-        descBuilder.append(Type.getDescriptor(header.returnType.accept(JavaTypeClassVisitor.INSTANCE)));
41
+        descBuilder.append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
33
         return descBuilder.toString();
42
         return descBuilder.toString();
34
     }
43
     }
35
 
44
 
121
         }
130
         }
122
     }
131
     }
123
 
132
 
133
+    private static final Map<String, String> lambdas = new HashMap<>();
134
+    private static int lambdaCounter = 0;
135
+    private static int lambdaICounter = 0;
136
+    public static String getLambdaInterface(final FunctionHeader header) {
137
+        StringBuilder builder = new StringBuilder("(");
138
+        for (FunctionParameter parameter : header.parameters) {
139
+            builder.append(parameter.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
140
+        }
141
+
142
+        //final String identifier = header.toString();
143
+        final String identifier = builder.append(")").append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor()).toString();
144
+        if(!lambdas.containsKey(identifier)) {
145
+            final String name = "lambdaInterface" + ++lambdaICounter;
146
+            lambdas.put(identifier, name);
147
+            createLambdaInterface(header, name);
148
+        }
149
+        return lambdas.get(identifier);
150
+    }
151
+
152
+    private static void createLambdaInterface(FunctionHeader header, String name) {
153
+        ClassWriter ifaceWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
154
+        ifaceWriter.visitAnnotation("java/lang/FunctionalInterface", true).visitEnd();
155
+        ifaceWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, name, null, "java/lang/Object", null);
156
+
157
+        ifaceWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "accept", calcDesc(header, false), calcSign(header, false), null).visitEnd();
158
+
159
+        ifaceWriter.visitEnd();
160
+
161
+        JavaModule.classes.putIfAbsent(name, ifaceWriter.toByteArray());
162
+
163
+        try (FileOutputStream out = new FileOutputStream(name + ".class")){
164
+            out.write(ifaceWriter.toByteArray());
165
+        } catch (IOException e) {
166
+            e.printStackTrace();
167
+        }
168
+    }
169
+
170
+
171
+    public static String getLambdaCounter() {
172
+        return "lambda" + ++lambdaCounter;
173
+    }
174
+
175
+
124
 
176
 
125
     public static int getKeyForSwitch(SwitchValue expression) {
177
     public static int getKeyForSwitch(SwitchValue expression) {
126
 		return expression.accept(new SwitchKeyVisitor());
178
 		return expression.accept(new SwitchKeyVisitor());

+ 2
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaCapturedExpressionVisitor.java View File

17
 
17
 
18
     @Override
18
     @Override
19
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
19
     public Void visitCapturedParameter(CapturedParameterExpression expression) {
20
-        return null;
20
+        return new GetFunctionParameterExpression(expression.position, expression.parameter).accept(expressionVisitor);
21
     }
21
     }
22
 
22
 
23
     @Override
23
     @Override
24
     public Void visitCapturedLocal(CapturedLocalVariableExpression expression) {
24
     public Void visitCapturedLocal(CapturedLocalVariableExpression expression) {
25
-        new GetLocalVariableExpression(expression.position, expression.variable)
25
+        return new GetLocalVariableExpression(expression.position, expression.variable)
26
                 .accept(expressionVisitor);
26
                 .accept(expressionVisitor);
27
-        return null;
28
     }
27
     }
29
 
28
 
30
     @Override
29
     @Override

+ 140
- 68
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java View File

5
 import java.util.Comparator;
5
 import java.util.Comparator;
6
 import java.util.Map;
6
 import java.util.Map;
7
 import java.util.StringJoiner;
7
 import java.util.StringJoiner;
8
+import org.objectweb.asm.ClassWriter;
8
 import org.objectweb.asm.Label;
9
 import org.objectweb.asm.Label;
9
 import org.objectweb.asm.Opcodes;
10
 import org.objectweb.asm.Opcodes;
10
 import org.objectweb.asm.Type;
11
 import org.objectweb.asm.Type;
11
 import org.openzen.zencode.shared.CompileException;
12
 import org.openzen.zencode.shared.CompileException;
12
 import org.openzen.zencode.shared.CompileExceptionCode;
13
 import org.openzen.zencode.shared.CompileExceptionCode;
13
 import org.openzen.zenscript.codemodel.CompareType;
14
 import org.openzen.zenscript.codemodel.CompareType;
15
+import org.openzen.zenscript.codemodel.FunctionHeader;
16
+import org.openzen.zenscript.codemodel.FunctionParameter;
14
 import org.openzen.zenscript.codemodel.expression.*;
17
 import org.openzen.zenscript.codemodel.expression.*;
15
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
18
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
16
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
19
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
21
 import org.openzen.zenscript.implementations.IntRange;
24
 import org.openzen.zenscript.implementations.IntRange;
22
 import org.openzen.zenscript.javabytecode.*;
25
 import org.openzen.zenscript.javabytecode.*;
23
 
26
 
27
+import java.io.FileOutputStream;
28
+import java.io.IOException;
29
+import java.util.*;
30
+
24
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
31
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
25
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
32
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
26
 	private static final int STATIC = Opcodes.ACC_STATIC;
33
 	private static final int STATIC = Opcodes.ACC_STATIC;
27
 	private static final int PUBLIC_STATIC = PUBLIC | STATIC;
34
 	private static final int PUBLIC_STATIC = PUBLIC | STATIC;
28
-	
35
+
29
 	private static final JavaClassInfo BOOLEAN = JavaClassInfo.get(Boolean.class);
36
 	private static final JavaClassInfo BOOLEAN = JavaClassInfo.get(Boolean.class);
30
 	private static final JavaMethodInfo BOOLEAN_PARSE = new JavaMethodInfo(BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z", PUBLIC_STATIC);
37
 	private static final JavaMethodInfo BOOLEAN_PARSE = new JavaMethodInfo(BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z", PUBLIC_STATIC);
31
 	private static final JavaMethodInfo BOOLEAN_TO_STRING = new JavaMethodInfo(BOOLEAN, "toString", "(Z)Ljava/lang/String;", PUBLIC_STATIC);
38
 	private static final JavaMethodInfo BOOLEAN_TO_STRING = new JavaMethodInfo(BOOLEAN, "toString", "(Z)Ljava/lang/String;", PUBLIC_STATIC);
285
 		} else {
292
 		} else {
286
 			if (!checkAndExecuteMethodInfo(expression.operator))
293
 			if (!checkAndExecuteMethodInfo(expression.operator))
287
 				throw new IllegalStateException("Call target has no method info!");
294
 				throw new IllegalStateException("Call target has no method info!");
288
-			
295
+
289
 			expression.left.accept(this);
296
 			expression.left.accept(this);
290
 			expression.right.accept(this);
297
 			expression.right.accept(this);
291
 			compareGeneric(expression.comparison);
298
 			compareGeneric(expression.comparison);
293
 
300
 
294
         return null;
301
         return null;
295
     }
302
     }
296
-	
303
+
297
 	private void compareInt(CompareType comparator) {
304
 	private void compareInt(CompareType comparator) {
298
 		Label exit = new Label();
305
 		Label exit = new Label();
299
 		Label isTrue = new Label();
306
 		Label isTrue = new Label();
312
 		javaWriter.iConst1();
319
 		javaWriter.iConst1();
313
 		javaWriter.label(exit);
320
 		javaWriter.label(exit);
314
 	}
321
 	}
315
-	
322
+
316
 	private void compareGeneric(CompareType comparator) {
323
 	private void compareGeneric(CompareType comparator) {
317
 		Label exit = new Label();
324
 		Label exit = new Label();
318
 		Label isTrue = new Label();
325
 		Label isTrue = new Label();
343
 
350
 
344
 			if (!checkAndExecuteMethodInfo(expression.member))
351
 			if (!checkAndExecuteMethodInfo(expression.member))
345
 	            throw new IllegalStateException("Call target has no method info!");
352
 	            throw new IllegalStateException("Call target has no method info!");
346
-			
353
+
347
 			return null;
354
 			return null;
348
 		}
355
 		}
349
-		
356
+
350
 		switch (builtin) {
357
 		switch (builtin) {
351
 			case STRING_RANGEGET:
358
 			case STRING_RANGEGET:
352
 			case ARRAY_INDEXGETRANGE:
359
 			case ARRAY_INDEXGETRANGE:
357
 					argument.accept(this);
364
 					argument.accept(this);
358
 				}
365
 				}
359
 		}
366
 		}
360
-		
367
+
361
 		switch (builtin) {
368
 		switch (builtin) {
362
 			case BOOL_NOT:
369
 			case BOOL_NOT:
363
 				javaWriter.iConst1();
370
 				javaWriter.iConst1();
652
 			case ASSOC_INDEXGET:
659
 			case ASSOC_INDEXGET:
653
 			case ASSOC_GETORDEFAULT: {
660
 			case ASSOC_GETORDEFAULT: {
654
 				javaWriter.invokeVirtual(MAP_GET);
661
 				javaWriter.invokeVirtual(MAP_GET);
655
-				
662
+
656
 				AssocTypeID type = (AssocTypeID) expression.target.type;
663
 				AssocTypeID type = (AssocTypeID) expression.target.type;
657
 				Type cls = type.valueType.accept(JavaTypeVisitor.INSTANCE);
664
 				Type cls = type.valueType.accept(JavaTypeVisitor.INSTANCE);
658
 				javaWriter.checkCast(cls.getInternalName());
665
 				javaWriter.checkCast(cls.getInternalName());
721
 			}
728
 			}
722
 			case ARRAY_INDEXGETRANGE: {
729
 			case ARRAY_INDEXGETRANGE: {
723
 				ArrayTypeID type = (ArrayTypeID) expression.target.type;
730
 				ArrayTypeID type = (ArrayTypeID) expression.target.type;
724
-				
731
+
725
 				expression.target.accept(this);
732
 				expression.target.accept(this);
726
 				Expression argument = expression.arguments.arguments[0];
733
 				Expression argument = expression.arguments.arguments[0];
727
 				if (argument instanceof RangeExpression) {
734
 				if (argument instanceof RangeExpression) {
737
 					javaWriter.loadInt(tmp);
744
 					javaWriter.loadInt(tmp);
738
 					javaWriter.getField("zsynthetic/IntRange", "to", "I");
745
 					javaWriter.getField("zsynthetic/IntRange", "to", "I");
739
 				}
746
 				}
740
-				
747
+
741
 				if (type.elementType instanceof BasicTypeID) {
748
 				if (type.elementType instanceof BasicTypeID) {
742
 					switch ((BasicTypeID) type.elementType) {
749
 					switch ((BasicTypeID) type.elementType) {
743
 						case BOOL:
750
 						case BOOL:
825
 				} else {
832
 				} else {
826
 					javaWriter.invokeStatic(ARRAYS_EQUALS_OBJECTS);
833
 					javaWriter.invokeStatic(ARRAYS_EQUALS_OBJECTS);
827
 				}
834
 				}
828
-				
835
+
829
 				if (builtin == BuiltinID.ARRAY_NOTEQUALS) {
836
 				if (builtin == BuiltinID.ARRAY_NOTEQUALS) {
830
 					javaWriter.iConst1();
837
 					javaWriter.iConst1();
831
 					javaWriter.iXor();
838
 					javaWriter.iXor();
833
 				break;
840
 				break;
834
 			}
841
 			}
835
 			case FUNCTION_CALL:
842
 			case FUNCTION_CALL:
836
-				throw new UnsupportedOperationException("Not yet supported!");
843
+				//expression.target.accept(this);
844
+				//for (Expression argument : expression.arguments.arguments) {
845
+				//	argument.accept(this);
846
+				//}
847
+				javaWriter.invokeInterface(new JavaMethodInfo(new JavaClassInfo(expression.target.type.accept(JavaTypeVisitor.INSTANCE).getInternalName()), "accept", CompilerUtils.calcSign(expression.instancedHeader, false), Opcodes.ACC_PUBLIC));
848
+				break;
849
+				//throw new UnsupportedOperationException("Not yet supported!");
837
 			case AUTOOP_NOTEQUALS:
850
 			case AUTOOP_NOTEQUALS:
838
 				throw new UnsupportedOperationException("Not yet supported!");
851
 				throw new UnsupportedOperationException("Not yet supported!");
839
 			default:
852
 			default:
843
         return null;
856
         return null;
844
     }
857
     }
845
 
858
 
846
-    @Override
859
+	@Override
847
     public Void visitCallStatic(CallStaticExpression expression) {
860
     public Void visitCallStatic(CallStaticExpression expression) {
848
 		for (Expression argument : expression.arguments.arguments)
861
 		for (Expression argument : expression.arguments.arguments)
849
 			argument.accept(this);
862
 			argument.accept(this);
850
-		
863
+
851
 		BuiltinID builtin = expression.member.getBuiltin();
864
 		BuiltinID builtin = expression.member.getBuiltin();
852
 		if (builtin == null) {
865
 		if (builtin == null) {
853
 			if (!checkAndExecuteMethodInfo(expression.member))
866
 			if (!checkAndExecuteMethodInfo(expression.member))
854
 	            throw new IllegalStateException("Call target has no method info!");
867
 	            throw new IllegalStateException("Call target has no method info!");
855
-			
868
+
856
 			return null;
869
 			return null;
857
 		}
870
 		}
858
-		
871
+
859
 		switch (builtin) {
872
 		switch (builtin) {
860
 			case BOOL_PARSE:
873
 			case BOOL_PARSE:
861
 				javaWriter.invokeStatic(BOOLEAN_PARSE);
874
 				javaWriter.invokeStatic(BOOLEAN_PARSE);
954
     @Override
967
     @Override
955
     public Void visitCast(CastExpression expression) {
968
     public Void visitCast(CastExpression expression) {
956
         expression.target.accept(this);
969
         expression.target.accept(this);
957
-		
970
+
958
 		BuiltinID builtin = expression.member.member.builtin;
971
 		BuiltinID builtin = expression.member.member.builtin;
959
 		if (builtin == null) {
972
 		if (builtin == null) {
960
 			if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
973
 			if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
961
 				throw new IllegalStateException("Call target has no method info!");
974
 				throw new IllegalStateException("Call target has no method info!");
962
-			
975
+
963
 			return null;
976
 			return null;
964
 		}
977
 		}
965
-		
978
+
966
 		switch (builtin) {
979
 		switch (builtin) {
967
 			case BOOL_TO_STRING:
980
 			case BOOL_TO_STRING:
968
 				javaWriter.invokeStatic(BOOLEAN_TO_STRING);
981
 				javaWriter.invokeStatic(BOOLEAN_TO_STRING);
1289
 			default:
1302
 			default:
1290
 				throw new UnsupportedOperationException("Unknown builtin cast: " + builtin);
1303
 				throw new UnsupportedOperationException("Unknown builtin cast: " + builtin);
1291
 		}
1304
 		}
1292
-		
1305
+
1293
 		return null;
1306
 		return null;
1294
     }
1307
     }
1295
 
1308
 
1335
         javaWriter.label(end);
1348
         javaWriter.label(end);
1336
         return null;
1349
         return null;
1337
     }
1350
     }
1338
-	
1351
+
1339
 	@Override
1352
 	@Override
1340
 	public Void visitConst(ConstExpression expression) {
1353
 	public Void visitConst(ConstExpression expression) {
1341
 		BuiltinID builtin = expression.constant.member.builtin;
1354
 		BuiltinID builtin = expression.constant.member.builtin;
1342
 		if (builtin == null) {
1355
 		if (builtin == null) {
1343
 			if (!checkAndGetFieldInfo(expression.constant, true))
1356
 			if (!checkAndGetFieldInfo(expression.constant, true))
1344
 	            throw new IllegalStateException("Call target has no field info!");
1357
 	            throw new IllegalStateException("Call target has no field info!");
1345
-			
1358
+
1346
 			return null;
1359
 			return null;
1347
 		}
1360
 		}
1348
-		
1361
+
1349
 		switch (builtin) {
1362
 		switch (builtin) {
1350
 			case BYTE_GET_MIN_VALUE:
1363
 			case BYTE_GET_MIN_VALUE:
1351
 				javaWriter.iConst0();
1364
 				javaWriter.iConst0();
1422
 			default:
1435
 			default:
1423
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
1436
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
1424
 		}
1437
 		}
1425
-		
1438
+
1426
 		return null;
1439
 		return null;
1427
 	}
1440
 	}
1428
 
1441
 
1546
 
1559
 
1547
     @Override
1560
     @Override
1548
     public Void visitFunction(FunctionExpression expression) {
1561
     public Void visitFunction(FunctionExpression expression) {
1562
+		CompilerUtils.tagMethodParameters(expression.header, false);
1563
+
1549
         if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
1564
         if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
1550
             ((ReturnStatement) expression.body).value.accept(this);
1565
             ((ReturnStatement) expression.body).value.accept(this);
1551
             return null;
1566
             return null;
1552
         }
1567
         }
1553
-        final String signature = calcFunctionSignature(expression.closure, expression.header.returnType);
1554
-        final String name = "lambda" + expression.hashCode();
1568
+        final String signature = CompilerUtils.calcSign(expression.header, false);
1569
+        //final String name = CompilerUtils.getLambdaInterface(expression.header);
1570
+		final String name = CompilerUtils.getLambdaCounter();
1555
 
1571
 
1556
-        final JavaMethodInfo methodInfo = new JavaMethodInfo(javaWriter.method.javaClass, name, signature, Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);
1557
-        JavaWriter functionWriter = new JavaWriter(javaWriter.clazzVisitor, methodInfo, null, signature, null);
1572
+        final JavaMethodInfo methodInfo = new JavaMethodInfo(javaWriter.method.javaClass, "accept", signature, Opcodes.ACC_PUBLIC);
1573
+		final ClassWriter lambdaCW = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
1574
+		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", new String[]{CompilerUtils.getLambdaInterface(expression.header)});
1575
+		final JavaWriter functionWriter = new JavaWriter(lambdaCW, methodInfo, null, signature, null, "java/lang/Override");
1576
+
1577
+
1578
+
1579
+		javaWriter.newObject(name);
1580
+		javaWriter.dup();
1581
+
1582
+		final String constructorDesc = calcFunctionSignature(expression.closure);
1583
+
1584
+
1585
+		final JavaWriter constructorWriter = new JavaWriter(lambdaCW, new JavaMethodInfo(javaWriter.method.javaClass, "<init>", constructorDesc, Opcodes.ACC_PUBLIC), null, null, null);
1586
+		constructorWriter.start();
1587
+		constructorWriter.loadObject(0);
1588
+		constructorWriter.dup();
1589
+		constructorWriter.invokeSpecial(Object.class, "<init>", "()V");
1590
+
1591
+		int i = 0;
1592
+		for (CapturedExpression capture : expression.closure.captures) {
1593
+			constructorWriter.dup();
1594
+			final Type type = capture.type.accept(JavaTypeVisitor.INSTANCE);
1595
+			lambdaCW.visitField(Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE, "captured" + ++i, type.getDescriptor(), null, null).visitEnd();
1596
+
1597
+			capture.accept(this);
1598
+
1599
+			constructorWriter.load(type, i);
1600
+			constructorWriter.putField(name, "captured" + i, type.getDescriptor());
1601
+		}
1602
+
1603
+		constructorWriter.pop();
1604
+
1605
+		javaWriter.invokeSpecial(name, "<init>", constructorDesc);
1606
+
1607
+		constructorWriter.ret();
1608
+		constructorWriter.end();
1558
 
1609
 
1559
-        for (CapturedExpression capture : expression.closure.captures) {
1560
-            capture.accept(new JavaCapturedExpressionVisitor(this));
1561
-        }
1562
 
1610
 
1563
-        javaWriter.invokeStatic(methodInfo);
1564
 
1611
 
1565
         functionWriter.start();
1612
         functionWriter.start();
1566
-        expression.body.accept(new JavaStatementVisitor(new JavaExpressionVisitor(functionWriter) {
1567
-            @Override
1568
-            public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
1569
-                final int position = calculateMemberPosition(varExpression, expression);
1570
-                if (position < 0)
1571
-                    throw new CompileException(varExpression.position, CompileExceptionCode.INTERNAL_ERROR, "Captured Statement error");
1572
-                functionWriter.load(varExpression.variable.type.accept(JavaTypeVisitor.INSTANCE), position);
1573
-                return null;
1574
-            }
1575
-        }));
1613
+
1614
+
1615
+		final JavaStatementVisitor CSV = new JavaStatementVisitor(new JavaExpressionVisitor(functionWriter) {
1616
+			//@Override
1617
+			public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
1618
+				final int position = calculateMemberPosition(varExpression, expression) ;
1619
+				if (position < 0)
1620
+					throw new CompileException(varExpression.position, CompileExceptionCode.INTERNAL_ERROR, "Captured Statement error");
1621
+				functionWriter.loadObject(0);
1622
+				functionWriter.getField(name, "captured" + position, varExpression.variable.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
1623
+				return null;
1624
+			}
1625
+		});
1626
+
1627
+
1628
+		expression.body.accept(CSV);
1576
 
1629
 
1577
 
1630
 
1578
         functionWriter.ret();
1631
         functionWriter.ret();
1579
-        functionWriter.end();
1580
 
1632
 
1581
-        return null;
1633
+
1634
+
1635
+		functionWriter.end();
1636
+        lambdaCW.visitEnd();
1637
+
1638
+        JavaModule.classes.putIfAbsent(name, lambdaCW.toByteArray());
1639
+
1640
+        try (FileOutputStream out = new FileOutputStream(name + ".class")){
1641
+        	out.write(lambdaCW.toByteArray());
1642
+		} catch (IOException e) {
1643
+			e.printStackTrace();
1644
+		}
1645
+
1646
+		return null;
1582
     }
1647
     }
1583
 
1648
 
1584
     //TODO replace with visitor?
1649
     //TODO replace with visitor?
1585
     private static int calculateMemberPosition(GetLocalVariableExpression localVariableExpression, FunctionExpression expression) {
1650
     private static int calculateMemberPosition(GetLocalVariableExpression localVariableExpression, FunctionExpression expression) {
1586
-        int h = expression.header.parameters.length;
1651
+        int h = 1;//expression.header.parameters.length;
1587
         for (CapturedExpression capture : expression.closure.captures) {
1652
         for (CapturedExpression capture : expression.closure.captures) {
1588
             if (capture instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) capture).variable == localVariableExpression.variable)
1653
             if (capture instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) capture).variable == localVariableExpression.variable)
1589
                 return h;
1654
                 return h;
1594
         return -1;
1659
         return -1;
1595
     }
1660
     }
1596
 
1661
 
1597
-    private String calcFunctionSignature(LambdaClosure closure, ITypeID type) {
1598
-        StringJoiner joiner = new StringJoiner("", "(", ")");
1662
+    private String calcFunctionSignature(LambdaClosure closure) {
1663
+        StringJoiner joiner = new StringJoiner("", "(", ")V");
1599
 
1664
 
1600
         for (CapturedExpression capture : closure.captures) {
1665
         for (CapturedExpression capture : closure.captures) {
1601
             String descriptor = capture.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1666
             String descriptor = capture.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1602
             joiner.add(descriptor);
1667
             joiner.add(descriptor);
1603
         }
1668
         }
1604
-        return joiner.toString() + type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1669
+        return joiner.toString();
1605
     }
1670
     }
1606
 
1671
 
1607
     @Override
1672
     @Override
1615
     @Override
1680
     @Override
1616
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1681
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1617
         JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1682
         JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1618
-        javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), parameter.index);
1683
+
1684
+        if(parameter == null) {
1685
+			System.err.println("NULL PARAMETER!!!");
1686
+			//FIXME
1687
+			parameter = new JavaParameterInfo(1, Type.INT_TYPE);
1688
+		}
1689
+
1690
+        javaWriter.load(expression.parameter.type.accept(JavaTypeVisitor.INSTANCE), parameter.index);
1619
         return null;
1691
         return null;
1620
     }
1692
     }
1621
 
1693
 
1639
     @Override
1711
     @Override
1640
     public Void visitGetter(GetterExpression expression) {
1712
     public Void visitGetter(GetterExpression expression) {
1641
 		expression.target.accept(this);
1713
 		expression.target.accept(this);
1642
-		
1714
+
1643
 		BuiltinID builtin = expression.getter.member.builtin;
1715
 		BuiltinID builtin = expression.getter.member.builtin;
1644
 		if (builtin == null) {
1716
 		if (builtin == null) {
1645
 			if (!checkAndExecuteMethodInfo(expression.getter))
1717
 			if (!checkAndExecuteMethodInfo(expression.getter))
1646
 	            throw new IllegalStateException("Call target has no method info!");
1718
 	            throw new IllegalStateException("Call target has no method info!");
1647
-			
1719
+
1648
 			return null;
1720
 			return null;
1649
 		}
1721
 		}
1650
-		
1722
+
1651
 		switch (builtin) {
1723
 		switch (builtin) {
1652
 			case INT_HIGHEST_ONE_BIT:
1724
 			case INT_HIGHEST_ONE_BIT:
1653
 			case UINT_HIGHEST_ONE_BIT:
1725
 			case UINT_HIGHEST_ONE_BIT:
1718
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1790
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1719
 				ArrayTypeID result = new ArrayTypeID(type.keyType, 1);
1791
 				ArrayTypeID result = new ArrayTypeID(type.keyType, 1);
1720
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1792
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1721
-				
1793
+
1722
 				javaWriter.invokeVirtual(MAP_KEYS);
1794
 				javaWriter.invokeVirtual(MAP_KEYS);
1723
 				javaWriter.dup();
1795
 				javaWriter.dup();
1724
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
1796
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
1731
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1803
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1732
 				ArrayTypeID result = new ArrayTypeID(type.valueType, 1);
1804
 				ArrayTypeID result = new ArrayTypeID(type.valueType, 1);
1733
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1805
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1734
-				
1806
+
1735
 				javaWriter.invokeVirtual(MAP_VALUES);
1807
 				javaWriter.invokeVirtual(MAP_VALUES);
1736
 				javaWriter.dup();
1808
 				javaWriter.dup();
1737
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
1809
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
1797
 			case ARRAY_ISEMPTY:
1869
 			case ARRAY_ISEMPTY:
1798
 				Label isTrue = new Label();
1870
 				Label isTrue = new Label();
1799
 				Label exit = new Label();
1871
 				Label exit = new Label();
1800
-				
1872
+
1801
 				javaWriter.arrayLength();
1873
 				javaWriter.arrayLength();
1802
 				javaWriter.ifEQ(isTrue);
1874
 				javaWriter.ifEQ(isTrue);
1803
 				javaWriter.iConst0();
1875
 				javaWriter.iConst0();
1982
 
2054
 
1983
         return null;
2055
         return null;
1984
     }
2056
     }
1985
-	
2057
+
1986
 	@Override
2058
 	@Override
1987
 	public Void visitPanic(PanicExpression expression) {
2059
 	public Void visitPanic(PanicExpression expression) {
1988
 		// TODO: compile to: throw new AssertionError(expression.value)
2060
 		// TODO: compile to: throw new AssertionError(expression.value)
1989
 		throw new UnsupportedOperationException("Not yet supported");
2061
 		throw new UnsupportedOperationException("Not yet supported");
1990
 	}
2062
 	}
1991
-	
2063
+
1992
 	@Override
2064
 	@Override
1993
 	public Void visitPostCall(PostCallExpression expression) {
2065
 	public Void visitPostCall(PostCallExpression expression) {
1994
 		expression.target.accept(this);
2066
 		expression.target.accept(this);
2015
         return null;
2087
         return null;
2016
     }
2088
     }
2017
 
2089
 
2018
-	
2090
+
2019
 	@Override
2091
 	@Override
2020
 	public Void visitSameObject(SameObjectExpression expression) {
2092
 	public Void visitSameObject(SameObjectExpression expression) {
2021
 		expression.left.accept(this);
2093
 		expression.left.accept(this);
2022
 		expression.right.accept(this);
2094
 		expression.right.accept(this);
2023
-		
2095
+
2024
 		Label end = new Label();
2096
 		Label end = new Label();
2025
 		Label equal = new Label();
2097
 		Label equal = new Label();
2026
-		
2098
+
2027
 		if (expression.inverted)
2099
 		if (expression.inverted)
2028
 			javaWriter.ifACmpNe(equal);
2100
 			javaWriter.ifACmpNe(equal);
2029
 		else
2101
 		else
2030
 			javaWriter.ifACmpEq(equal);
2102
 			javaWriter.ifACmpEq(equal);
2031
-		
2103
+
2032
 		javaWriter.iConst0();
2104
 		javaWriter.iConst0();
2033
 		javaWriter.goTo(end);
2105
 		javaWriter.goTo(end);
2034
 		javaWriter.label(equal);
2106
 		javaWriter.label(equal);
2071
     public Void visitSetStaticField(SetStaticFieldExpression expression) {
2143
     public Void visitSetStaticField(SetStaticFieldExpression expression) {
2072
         if (expression.field.isFinal())
2144
         if (expression.field.isFinal())
2073
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
2145
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
2074
-		
2146
+
2075
         expression.value.accept(this);
2147
         expression.value.accept(this);
2076
         if (!checkAndPutFieldInfo(expression.field, true))
2148
         if (!checkAndPutFieldInfo(expression.field, true))
2077
             throw new IllegalStateException("Missing field info on a field member!");
2149
             throw new IllegalStateException("Missing field info on a field member!");
2089
 		if (builtin == null) {
2161
 		if (builtin == null) {
2090
 			if (!checkAndExecuteMethodInfo(expression.getter))
2162
 			if (!checkAndExecuteMethodInfo(expression.getter))
2091
 	            throw new IllegalStateException("Call target has no method info!");
2163
 	            throw new IllegalStateException("Call target has no method info!");
2092
-			
2164
+
2093
 			return null;
2165
 			return null;
2094
 		}
2166
 		}
2095
-		
2167
+
2096
 		switch (builtin) {
2168
 		switch (builtin) {
2097
 			case BYTE_GET_MIN_VALUE:
2169
 			case BYTE_GET_MIN_VALUE:
2098
 				javaWriter.iConst0();
2170
 				javaWriter.iConst0();
2169
 			default:
2241
 			default:
2170
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2242
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2171
 		}
2243
 		}
2172
-		
2244
+
2173
 		throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2245
 		throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2174
     }
2246
     }
2175
 
2247
 
2244
         JavaMethodInfo methodInfo = member.getTag(JavaMethodInfo.class);
2316
         JavaMethodInfo methodInfo = member.getTag(JavaMethodInfo.class);
2245
         if (methodInfo == null)
2317
         if (methodInfo == null)
2246
             return false;
2318
             return false;
2247
-		
2319
+
2248
         if (methodInfo.isStatic()) {
2320
         if (methodInfo.isStatic()) {
2249
             getJavaWriter().invokeStatic(methodInfo);
2321
             getJavaWriter().invokeStatic(methodInfo);
2250
         } else {
2322
         } else {
2272
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2344
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2273
         if (fieldInfo == null)
2345
         if (fieldInfo == null)
2274
             return false;
2346
             return false;
2275
-		
2347
+
2276
         getJavaWriter().getStaticField(fieldInfo);
2348
         getJavaWriter().getStaticField(fieldInfo);
2277
         return true;
2349
         return true;
2278
     }
2350
     }
2281
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2353
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2282
         if (fieldInfo == null)
2354
         if (fieldInfo == null)
2283
             return false;
2355
             return false;
2284
-		
2356
+
2285
         //TODO Remove isStatic
2357
         //TODO Remove isStatic
2286
         if (field.isStatic() || isStatic) {
2358
         if (field.isStatic() || isStatic) {
2287
             getJavaWriter().getStaticField(fieldInfo);
2359
             getJavaWriter().getStaticField(fieldInfo);

+ 2
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachVisitor.java View File

27
     @Override
27
     @Override
28
     public Void visitIntRange() {
28
     public Void visitIntRange() {
29
         javaWriter.dup();
29
         javaWriter.dup();
30
-        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "max", "I");
30
+        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "to", "I");
31
         javaWriter.swap();
31
         javaWriter.swap();
32
-        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "min", "I");
32
+        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "from", "I");
33
 
33
 
34
         final int z = variables[0].getTag(JavaLocalVariableInfo.class).local;
34
         final int z = variables[0].getTag(JavaLocalVariableInfo.class).local;
35
         javaWriter.storeInt(z);
35
         javaWriter.storeInt(z);

+ 6
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java View File

271
 
271
 
272
     @Override
272
     @Override
273
     public Boolean visitVar(VarStatement statement) {
273
     public Boolean visitVar(VarStatement statement) {
274
-        Type type = statement.type.accept(JavaTypeVisitor.INSTANCE);
275
-        int local = javaWriter.local(type);
274
+
276
         if (statement.initializer != null) {
275
         if (statement.initializer != null) {
277
             statement.initializer.accept(expressionVisitor);
276
             statement.initializer.accept(expressionVisitor);
278
-            javaWriter.store(type, local);
279
         }
277
         }
278
+
279
+        Type type = statement.type.accept(JavaTypeVisitor.INSTANCE);
280
+        int local = javaWriter.local(type);
281
+        if (statement.initializer != null)
282
+            javaWriter.store(type, local);
280
         final Label variableStart = new Label();
283
         final Label variableStart = new Label();
281
         javaWriter.label(variableStart);
284
         javaWriter.label(variableStart);
282
         final JavaLocalVariableInfo info = new JavaLocalVariableInfo(type, local, variableStart, statement.name);
285
         final JavaLocalVariableInfo info = new JavaLocalVariableInfo(type, local, variableStart, statement.name);

+ 7
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeClassVisitor.java View File

1
 package org.openzen.zenscript.javabytecode.compiler;
1
 package org.openzen.zenscript.javabytecode.compiler;
2
 
2
 
3
 import org.openzen.zenscript.codemodel.type.*;
3
 import org.openzen.zenscript.codemodel.type.*;
4
+import org.openzen.zenscript.javabytecode.JavaModule;
4
 
5
 
5
 import java.lang.reflect.Array;
6
 import java.lang.reflect.Array;
6
 import java.util.Iterator;
7
 import java.util.Iterator;
62
 
63
 
63
     @Override
64
     @Override
64
     public Class visitFunction(FunctionTypeID function) {
65
     public Class visitFunction(FunctionTypeID function) {
65
-        return null;
66
+        try {
67
+            return new JavaModule().new ScriptClassLoader().loadClass(CompilerUtils.getLambdaInterface(function.header));
68
+        } catch (ClassNotFoundException e) {
69
+            return null;
70
+        }
71
+        //return function.header.returnType.accept(this);
66
     }
72
     }
67
 
73
 
68
     @Override
74
     @Override

+ 2
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeVisitor.java View File

28
 
28
 
29
     @Override
29
     @Override
30
     public Type visitFunction(FunctionTypeID function) {
30
     public Type visitFunction(FunctionTypeID function) {
31
-        return Type.getType(function.accept(JavaTypeClassVisitor.INSTANCE));
31
+        Class clazz = function.accept(JavaTypeClassVisitor.INSTANCE);
32
+        return clazz != null ? Type.getType(clazz) : Type.getType("L" + CompilerUtils.getLambdaInterface(function.header) + ";");
32
     }
33
     }
33
 
34
 
34
     @Override
35
     @Override

+ 6
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java View File

1
 package org.openzen.zenscript.javabytecode.compiler;
1
 package org.openzen.zenscript.javabytecode.compiler;
2
 
2
 
3
+import org.objectweb.asm.*;
4
+import org.objectweb.asm.commons.LocalVariablesSorter;
5
+import org.openzen.zencode.shared.CodePosition;
6
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
7
+import org.openzen.zenscript.javabytecode.*;
8
+
3
 import java.lang.reflect.Field;
9
 import java.lang.reflect.Field;
4
 import java.util.ArrayList;
10
 import java.util.ArrayList;
5
 import java.util.HashMap;
11
 import java.util.HashMap;

+ 2
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java View File

3
 import org.objectweb.asm.ClassWriter;
3
 import org.objectweb.asm.ClassWriter;
4
 import org.objectweb.asm.Opcodes;
4
 import org.objectweb.asm.Opcodes;
5
 import org.objectweb.asm.Type;
5
 import org.objectweb.asm.Type;
6
+import org.openzen.zenscript.codemodel.FunctionParameter;
6
 import org.openzen.zenscript.codemodel.definition.*;
7
 import org.openzen.zenscript.codemodel.definition.*;
7
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
8
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
8
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
9
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
10
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
11
 import org.openzen.zenscript.javabytecode.JavaClassInfo;
11
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
12
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
12
 import org.openzen.zenscript.javabytecode.JavaModule;
13
 import org.openzen.zenscript.javabytecode.JavaModule;
14
+import org.openzen.zenscript.javabytecode.JavaParameterInfo;
13
 import org.openzen.zenscript.javabytecode.compiler.*;
15
 import org.openzen.zenscript.javabytecode.compiler.*;
14
 
16
 
15
 
17
 

+ 1
- 1
Shared/src/main/java/zsynthetic/ArrayHelpers.java View File

3
 public class ArrayHelpers {
3
 public class ArrayHelpers {
4
     public static <T> boolean contains(T[] haystack, T needle) {
4
     public static <T> boolean contains(T[] haystack, T needle) {
5
         for (int i = 0; i < haystack.length; i++)
5
         for (int i = 0; i < haystack.length; i++)
6
-            if (haystack[i].equals(needle))
6
+            if (java.util.Objects.equals(haystack[i], needle))
7
                 return true;
7
                 return true;
8
         return false;
8
         return false;
9
     }
9
     }

Loading…
Cancel
Save