Selaa lähdekoodia

More work on functions, only commited to merge Stans latest changes

kindlich 6 vuotta sitten
vanhempi
commit
89c4221b53
No known key found for this signature in database

+ 4
- 1
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java Näytä tiedosto

@@ -76,6 +76,7 @@ import org.openzen.zenscript.codemodel.expression.TryRethrowAsExceptionExpressio
76 76
 import org.openzen.zenscript.codemodel.expression.TryRethrowAsResultExpression;
77 77
 import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
78 78
 import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
79
+import org.openzen.zenscript.formattershared.FormattableOperator;
79 80
 
80 81
 /**
81 82
  *
@@ -428,7 +429,9 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
428 429
 
429 430
 	@Override
430 431
 	public ExpressionString visitFunction(FunctionExpression expression) {
431
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
432
+		//FIXME
433
+		return new ExpressionString("asdfghj", ZenScriptOperator.PRIMARY);
434
+		//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
432 435
 	}
433 436
 
434 437
 	@Override

+ 2
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/member/ref/FunctionalMemberRef.java Näytä tiedosto

@@ -79,7 +79,8 @@ public class FunctionalMemberRef implements DefinitionMemberRef {
79 79
 	}
80 80
 	
81 81
 	public String getMethodName() {
82
-		return ((MethodMember) target).name;
82
+		//FIXME
83
+		return (target).name;
83 84
 	}
84 85
 	
85 86
 	public Expression call(CodePosition position, Expression target, FunctionHeader instancedHeader, CallArguments arguments, TypeScope scope) {

+ 5
- 5
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/implementations/IntRange.java Näytä tiedosto

@@ -1,12 +1,12 @@
1 1
 package org.openzen.zenscript.implementations;
2 2
 
3 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 Näytä tiedosto

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

+ 53
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java Näytä tiedosto

@@ -1,5 +1,6 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3
+import org.objectweb.asm.ClassWriter;
3 4
 import org.objectweb.asm.Opcodes;
4 5
 import org.objectweb.asm.Type;
5 6
 import org.openzen.zencode.shared.CodePosition;
@@ -18,18 +19,26 @@ import org.openzen.zenscript.codemodel.member.FieldMember;
18 19
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
19 20
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
20 21
 import org.openzen.zenscript.codemodel.type.ITypeID;
22
+import org.openzen.zenscript.javabytecode.JavaModule;
21 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 31
 public class CompilerUtils {
24 32
     public static String calcDesc(FunctionHeader header, boolean isEnum) {
25 33
         StringBuilder descBuilder = new StringBuilder("(");
26 34
         if (isEnum)
27 35
             descBuilder.append("Ljava/lang/String;I");
28 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 40
         descBuilder.append(")");
32
-        descBuilder.append(Type.getDescriptor(header.returnType.accept(JavaTypeClassVisitor.INSTANCE)));
41
+        descBuilder.append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
33 42
         return descBuilder.toString();
34 43
     }
35 44
 
@@ -121,6 +130,48 @@ public class CompilerUtils {
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.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, name, null, "java/lang/Object", null);
155
+
156
+        ifaceWriter.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_ABSTRACT, "accept", calcDesc(header, false), calcSign(header, false), null).visitEnd();
157
+
158
+        ifaceWriter.visitEnd();
159
+
160
+        JavaModule.classes.putIfAbsent(name, ifaceWriter.toByteArray());
161
+
162
+        try (FileOutputStream out = new FileOutputStream(name + ".class")){
163
+            out.write(ifaceWriter.toByteArray());
164
+        } catch (IOException e) {
165
+            e.printStackTrace();
166
+        }
167
+    }
168
+
169
+
170
+    public static String getLambdaCounter() {
171
+        return "lambda" + ++lambdaCounter;
172
+    }
173
+
174
+
124 175
 
125 176
     public static int getKeyForSwitch(SwitchValue expression) {
126 177
 		return expression.accept(new SwitchKeyVisitor());

+ 1
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaCapturedExpressionVisitor.java Näytä tiedosto

@@ -22,9 +22,8 @@ public class JavaCapturedExpressionVisitor implements CapturedExpressionVisitor<
22 22
 
23 23
     @Override
24 24
     public Void visitCapturedLocal(CapturedLocalVariableExpression expression) {
25
-        new GetLocalVariableExpression(expression.position, expression.variable)
25
+        return new GetLocalVariableExpression(expression.position, expression.variable)
26 26
                 .accept(expressionVisitor);
27
-        return null;
28 27
     }
29 28
 
30 29
     @Override

+ 140
- 79
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Näytä tiedosto

@@ -1,9 +1,14 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3
+import org.objectweb.asm.ClassWriter;
3 4
 import org.objectweb.asm.Label;
4 5
 import org.objectweb.asm.Opcodes;
5 6
 import org.objectweb.asm.Type;
7
+import org.openzen.zencode.shared.CompileException;
8
+import org.openzen.zencode.shared.CompileExceptionCode;
6 9
 import org.openzen.zenscript.codemodel.CompareType;
10
+import org.openzen.zenscript.codemodel.FunctionHeader;
11
+import org.openzen.zenscript.codemodel.FunctionParameter;
7 12
 import org.openzen.zenscript.codemodel.expression.*;
8 13
 import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
9 14
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
@@ -14,24 +19,15 @@ import org.openzen.zenscript.codemodel.type.member.BuiltinID;
14 19
 import org.openzen.zenscript.implementations.IntRange;
15 20
 import org.openzen.zenscript.javabytecode.*;
16 21
 
22
+import java.io.FileOutputStream;
23
+import java.io.IOException;
17 24
 import java.util.*;
18
-import java.util.Map;
19
-import org.objectweb.asm.Opcodes;
20
-import org.openzen.zencode.shared.CompileException;
21
-import org.openzen.zencode.shared.CompileExceptionCode;
22
-import org.openzen.zenscript.codemodel.member.ref.ConstMemberRef;
23
-import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
24
-import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
25
-import org.openzen.zenscript.codemodel.type.ArrayTypeID;
26
-import org.openzen.zenscript.codemodel.type.AssocTypeID;
27
-import org.openzen.zenscript.codemodel.type.BasicTypeID;
28
-import org.openzen.zenscript.codemodel.type.member.BuiltinID;
29 25
 
30 26
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
31 27
 	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
32 28
 	private static final int STATIC = Opcodes.ACC_STATIC;
33 29
 	private static final int PUBLIC_STATIC = PUBLIC | STATIC;
34
-	
30
+
35 31
 	private static final JavaClassInfo BOOLEAN = JavaClassInfo.get(Boolean.class);
36 32
 	private static final JavaMethodInfo BOOLEAN_PARSE = new JavaMethodInfo(BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z", PUBLIC_STATIC);
37 33
 	private static final JavaMethodInfo BOOLEAN_TO_STRING = new JavaMethodInfo(BOOLEAN, "toString", "(Z)Ljava/lang/String;", PUBLIC_STATIC);
@@ -291,7 +287,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
291 287
 		} else {
292 288
 			if (!checkAndExecuteMethodInfo(expression.operator))
293 289
 				throw new IllegalStateException("Call target has no method info!");
294
-			
290
+
295 291
 			expression.left.accept(this);
296 292
 			expression.right.accept(this);
297 293
 			compareGeneric(expression.comparison);
@@ -299,7 +295,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
299 295
 
300 296
         return null;
301 297
     }
302
-	
298
+
303 299
 	private void compareInt(CompareType comparator) {
304 300
 		Label exit = new Label();
305 301
 		Label isTrue = new Label();
@@ -318,7 +314,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
318 314
 		javaWriter.iConst1();
319 315
 		javaWriter.label(exit);
320 316
 	}
321
-	
317
+
322 318
 	private void compareGeneric(CompareType comparator) {
323 319
 		Label exit = new Label();
324 320
 		Label isTrue = new Label();
@@ -349,10 +345,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
349 345
 
350 346
 			if (!checkAndExecuteMethodInfo(expression.member))
351 347
 	            throw new IllegalStateException("Call target has no method info!");
352
-			
348
+
353 349
 			return null;
354 350
 		}
355
-		
351
+
356 352
 		switch (builtin) {
357 353
 			case STRING_RANGEGET:
358 354
 			case ARRAY_INDEXGETRANGE:
@@ -363,7 +359,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
363 359
 					argument.accept(this);
364 360
 				}
365 361
 		}
366
-		
362
+
367 363
 		switch (builtin) {
368 364
 			case BOOL_NOT:
369 365
 				javaWriter.iConst1();
@@ -658,7 +654,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
658 654
 			case ASSOC_INDEXGET:
659 655
 			case ASSOC_GETORDEFAULT: {
660 656
 				javaWriter.invokeVirtual(MAP_GET);
661
-				
657
+
662 658
 				AssocTypeID type = (AssocTypeID) expression.target.type;
663 659
 				Type cls = type.valueType.accept(JavaTypeVisitor.INSTANCE);
664 660
 				javaWriter.checkCast(cls.getInternalName());
@@ -727,7 +723,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
727 723
 			}
728 724
 			case ARRAY_INDEXGETRANGE: {
729 725
 				ArrayTypeID type = (ArrayTypeID) expression.target.type;
730
-				
726
+
731 727
 				expression.target.accept(this);
732 728
 				Expression argument = expression.arguments.arguments[0];
733 729
 				if (argument instanceof RangeExpression) {
@@ -743,7 +739,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
743 739
 					javaWriter.loadInt(tmp);
744 740
 					javaWriter.getField("zsynthetic/IntRange", "to", "I");
745 741
 				}
746
-				
742
+
747 743
 				if (type.elementType instanceof BasicTypeID) {
748 744
 					switch ((BasicTypeID) type.elementType) {
749 745
 						case BOOL:
@@ -836,7 +832,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
836 832
 				} else {
837 833
 					javaWriter.invokeStatic(ARRAYS_EQUALS_OBJECTS);
838 834
 				}
839
-				
835
+
840 836
 				if (builtin == BuiltinID.ARRAY_NOTEQUALS) {
841 837
 					javaWriter.iConst1();
842 838
 					javaWriter.iXor();
@@ -844,7 +840,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
844 840
 				break;
845 841
 			}
846 842
 			case FUNCTION_CALL:
847
-				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!");
848 850
 			case AUTOOP_NOTEQUALS:
849 851
 				throw new UnsupportedOperationException("Not yet supported!");
850 852
 			default:
@@ -854,19 +856,19 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
854 856
         return null;
855 857
     }
856 858
 
857
-    @Override
859
+	@Override
858 860
     public Void visitCallStatic(CallStaticExpression expression) {
859 861
 		for (Expression argument : expression.arguments.arguments)
860 862
 			argument.accept(this);
861
-		
863
+
862 864
 		BuiltinID builtin = expression.member.getBuiltin();
863 865
 		if (builtin == null) {
864 866
 			if (!checkAndExecuteMethodInfo(expression.member))
865 867
 	            throw new IllegalStateException("Call target has no method info!");
866
-			
868
+
867 869
 			return null;
868 870
 		}
869
-		
871
+
870 872
 		switch (builtin) {
871 873
 			case BOOL_PARSE:
872 874
 				javaWriter.invokeStatic(BOOLEAN_PARSE);
@@ -965,15 +967,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
965 967
     @Override
966 968
     public Void visitCast(CastExpression expression) {
967 969
         expression.target.accept(this);
968
-		
970
+
969 971
 		BuiltinID builtin = expression.member.member.builtin;
970 972
 		if (builtin == null) {
971 973
 			if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
972 974
 				throw new IllegalStateException("Call target has no method info!");
973
-			
975
+
974 976
 			return null;
975 977
 		}
976
-		
978
+
977 979
 		switch (builtin) {
978 980
 			case BOOL_TO_STRING:
979 981
 				javaWriter.invokeStatic(BOOLEAN_TO_STRING);
@@ -1300,7 +1302,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1300 1302
 			default:
1301 1303
 				throw new UnsupportedOperationException("Unknown builtin cast: " + builtin);
1302 1304
 		}
1303
-		
1305
+
1304 1306
 		return null;
1305 1307
     }
1306 1308
 
@@ -1346,17 +1348,17 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1346 1348
         javaWriter.label(end);
1347 1349
         return null;
1348 1350
     }
1349
-	
1351
+
1350 1352
 	@Override
1351 1353
 	public Void visitConst(ConstExpression expression) {
1352 1354
 		BuiltinID builtin = expression.constant.member.builtin;
1353 1355
 		if (builtin == null) {
1354 1356
 			if (!checkAndGetFieldInfo(expression.constant, true))
1355 1357
 	            throw new IllegalStateException("Call target has no field info!");
1356
-			
1358
+
1357 1359
 			return null;
1358 1360
 		}
1359
-		
1361
+
1360 1362
 		switch (builtin) {
1361 1363
 			case BYTE_GET_MIN_VALUE:
1362 1364
 				javaWriter.iConst0();
@@ -1433,7 +1435,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1433 1435
 			default:
1434 1436
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
1435 1437
 		}
1436
-		
1438
+
1437 1439
 		return null;
1438 1440
 	}
1439 1441
 
@@ -1557,44 +1559,96 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1557 1559
 
1558 1560
     @Override
1559 1561
     public Void visitFunction(FunctionExpression expression) {
1562
+		CompilerUtils.tagMethodParameters(expression.header, false);
1563
+
1560 1564
         if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
1561 1565
             ((ReturnStatement) expression.body).value.accept(this);
1562 1566
             return null;
1563 1567
         }
1564
-        final String signature = calcFunctionSignature(expression.closure, expression.header.returnType);
1565
-        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();
1566 1571
 
1567
-        final JavaMethodInfo methodInfo = new JavaMethodInfo(javaWriter.method.javaClass, name, signature, Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);
1568
-        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();
1569 1609
 
1570
-        for (CapturedExpression capture : expression.closure.captures) {
1571
-            capture.accept(new JavaCapturedExpressionVisitor(this));
1572
-        }
1573 1610
 
1574
-        javaWriter.invokeStatic(methodInfo);
1575 1611
 
1576 1612
         functionWriter.start();
1577
-        expression.body.accept(new JavaStatementVisitor(new JavaExpressionVisitor(functionWriter) {
1578
-            @Override
1579
-            public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
1580
-                final int position = calculateMemberPosition(varExpression, expression);
1581
-                if (position < 0)
1582
-                    throw new CompileException(varExpression.position, CompileExceptionCode.INTERNAL_ERROR, "Captured Statement error");
1583
-                functionWriter.load(varExpression.variable.type.accept(JavaTypeVisitor.INSTANCE), position);
1584
-                return null;
1585
-            }
1586
-        }));
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);
1587 1629
 
1588 1630
 
1589 1631
         functionWriter.ret();
1590
-        functionWriter.end();
1591 1632
 
1592
-        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;
1593 1647
     }
1594 1648
 
1595 1649
     //TODO replace with visitor?
1596 1650
     private static int calculateMemberPosition(GetLocalVariableExpression localVariableExpression, FunctionExpression expression) {
1597
-        int h = expression.header.parameters.length;
1651
+        int h = 1;//expression.header.parameters.length;
1598 1652
         for (CapturedExpression capture : expression.closure.captures) {
1599 1653
             if (capture instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) capture).variable == localVariableExpression.variable)
1600 1654
                 return h;
@@ -1605,14 +1659,14 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1605 1659
         return -1;
1606 1660
     }
1607 1661
 
1608
-    private String calcFunctionSignature(LambdaClosure closure, ITypeID type) {
1609
-        StringJoiner joiner = new StringJoiner("", "(", ")");
1662
+    private String calcFunctionSignature(LambdaClosure closure) {
1663
+        StringJoiner joiner = new StringJoiner("", "(", ")V");
1610 1664
 
1611 1665
         for (CapturedExpression capture : closure.captures) {
1612 1666
             String descriptor = capture.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1613 1667
             joiner.add(descriptor);
1614 1668
         }
1615
-        return joiner.toString() + type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
1669
+        return joiner.toString();
1616 1670
     }
1617 1671
 
1618 1672
     @Override
@@ -1626,7 +1680,14 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1626 1680
     @Override
1627 1681
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
1628 1682
         JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
1629
-        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);
1630 1691
         return null;
1631 1692
     }
1632 1693
 
@@ -1650,15 +1711,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1650 1711
     @Override
1651 1712
     public Void visitGetter(GetterExpression expression) {
1652 1713
 		expression.target.accept(this);
1653
-		
1714
+
1654 1715
 		BuiltinID builtin = expression.getter.member.builtin;
1655 1716
 		if (builtin == null) {
1656 1717
 			if (!checkAndExecuteMethodInfo(expression.getter))
1657 1718
 	            throw new IllegalStateException("Call target has no method info!");
1658
-			
1719
+
1659 1720
 			return null;
1660 1721
 		}
1661
-		
1722
+
1662 1723
 		switch (builtin) {
1663 1724
 			case INT_HIGHEST_ONE_BIT:
1664 1725
 			case UINT_HIGHEST_ONE_BIT:
@@ -1729,7 +1790,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1729 1790
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1730 1791
 				ArrayTypeID result = new ArrayTypeID(type.keyType, 1);
1731 1792
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1732
-				
1793
+
1733 1794
 				javaWriter.invokeVirtual(MAP_KEYS);
1734 1795
 				javaWriter.dup();
1735 1796
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
@@ -1742,7 +1803,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1742 1803
 				AssocTypeID type = (AssocTypeID) expression.target.type;
1743 1804
 				ArrayTypeID result = new ArrayTypeID(type.valueType, 1);
1744 1805
 				Type resultType = result.accept(JavaTypeVisitor.INSTANCE);
1745
-				
1806
+
1746 1807
 				javaWriter.invokeVirtual(MAP_VALUES);
1747 1808
 				javaWriter.dup();
1748 1809
 				javaWriter.invokeVirtual(COLLECTION_SIZE);
@@ -1809,7 +1870,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1809 1870
 			case ARRAY_ISEMPTY:
1810 1871
 				Label isTrue = new Label();
1811 1872
 				Label exit = new Label();
1812
-				
1873
+
1813 1874
 				javaWriter.arrayLength();
1814 1875
 				javaWriter.ifEQ(isTrue);
1815 1876
 				javaWriter.iConst0();
@@ -1994,13 +2055,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1994 2055
 
1995 2056
         return null;
1996 2057
     }
1997
-	
2058
+
1998 2059
 	@Override
1999 2060
 	public Void visitPanic(PanicExpression expression) {
2000 2061
 		// TODO: compile to: throw new AssertionError(expression.value)
2001 2062
 		throw new UnsupportedOperationException("Not yet supported");
2002 2063
 	}
2003
-	
2064
+
2004 2065
 	@Override
2005 2066
 	public Void visitPostCall(PostCallExpression expression) {
2006 2067
 		expression.target.accept(this);
@@ -2027,20 +2088,20 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2027 2088
         return null;
2028 2089
     }
2029 2090
 
2030
-	
2091
+
2031 2092
 	@Override
2032 2093
 	public Void visitSameObject(SameObjectExpression expression) {
2033 2094
 		expression.left.accept(this);
2034 2095
 		expression.right.accept(this);
2035
-		
2096
+
2036 2097
 		Label end = new Label();
2037 2098
 		Label equal = new Label();
2038
-		
2099
+
2039 2100
 		if (expression.inverted)
2040 2101
 			javaWriter.ifACmpNe(equal);
2041 2102
 		else
2042 2103
 			javaWriter.ifACmpEq(equal);
2043
-		
2104
+
2044 2105
 		javaWriter.iConst0();
2045 2106
 		javaWriter.goTo(end);
2046 2107
 		javaWriter.label(equal);
@@ -2083,7 +2144,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2083 2144
     public Void visitSetStaticField(SetStaticFieldExpression expression) {
2084 2145
         if (expression.field.isFinal())
2085 2146
             throw new CompileException(expression.position, CompileExceptionCode.CANNOT_SET_FINAL_VARIABLE, "Cannot set a final field!");
2086
-		
2147
+
2087 2148
         expression.value.accept(this);
2088 2149
         if (!checkAndPutFieldInfo(expression.field, true))
2089 2150
             throw new IllegalStateException("Missing field info on a field member!");
@@ -2101,10 +2162,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2101 2162
 		if (builtin == null) {
2102 2163
 			if (!checkAndExecuteMethodInfo(expression.getter))
2103 2164
 	            throw new IllegalStateException("Call target has no method info!");
2104
-			
2165
+
2105 2166
 			return null;
2106 2167
 		}
2107
-		
2168
+
2108 2169
 		switch (builtin) {
2109 2170
 			case BYTE_GET_MIN_VALUE:
2110 2171
 				javaWriter.iConst0();
@@ -2181,7 +2242,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2181 2242
 			default:
2182 2243
 				throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2183 2244
 		}
2184
-		
2245
+
2185 2246
 		throw new UnsupportedOperationException("Unknown builtin: " + builtin);
2186 2247
     }
2187 2248
 
@@ -2256,7 +2317,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2256 2317
         JavaMethodInfo methodInfo = member.getTag(JavaMethodInfo.class);
2257 2318
         if (methodInfo == null)
2258 2319
             return false;
2259
-		
2320
+
2260 2321
         if (methodInfo.isStatic()) {
2261 2322
             getJavaWriter().invokeStatic(methodInfo);
2262 2323
         } else {
@@ -2284,7 +2345,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2284 2345
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2285 2346
         if (fieldInfo == null)
2286 2347
             return false;
2287
-		
2348
+
2288 2349
         getJavaWriter().getStaticField(fieldInfo);
2289 2350
         return true;
2290 2351
     }
@@ -2293,7 +2354,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2293 2354
         JavaFieldInfo fieldInfo = field.getTag(JavaFieldInfo.class);
2294 2355
         if (fieldInfo == null)
2295 2356
             return false;
2296
-		
2357
+
2297 2358
         //TODO Remove isStatic
2298 2359
         if (field.isStatic() || isStatic) {
2299 2360
             getJavaWriter().getStaticField(fieldInfo);

+ 2
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachVisitor.java Näytä tiedosto

@@ -27,9 +27,9 @@ public class JavaForeachVisitor implements ForeachIteratorVisitor<Void> {
27 27
     @Override
28 28
     public Void visitIntRange() {
29 29
         javaWriter.dup();
30
-        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "max", "I");
30
+        javaWriter.getField("org/openzen/zenscript/implementations/IntRange", "to", "I");
31 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 34
         final int z = variables[0].getTag(JavaLocalVariableInfo.class).local;
35 35
         javaWriter.storeInt(z);

+ 6
- 3
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java Näytä tiedosto

@@ -271,12 +271,15 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
271 271
 
272 272
     @Override
273 273
     public Boolean visitVar(VarStatement statement) {
274
-        Type type = statement.type.accept(JavaTypeVisitor.INSTANCE);
275
-        int local = javaWriter.local(type);
274
+
276 275
         if (statement.initializer != null) {
277 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 283
         final Label variableStart = new Label();
281 284
         javaWriter.label(variableStart);
282 285
         final JavaLocalVariableInfo info = new JavaLocalVariableInfo(type, local, variableStart, statement.name);

+ 7
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeClassVisitor.java Näytä tiedosto

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

+ 2
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeVisitor.java Näytä tiedosto

@@ -28,7 +28,8 @@ public class JavaTypeVisitor implements ITypeVisitor<Type> {
28 28
 
29 29
     @Override
30 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 35
     @Override

+ 2
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java Näytä tiedosto

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

+ 1
- 1
Shared/src/main/java/zsynthetic/ArrayHelpers.java Näytä tiedosto

@@ -3,7 +3,7 @@ package zsynthetic;
3 3
 public class ArrayHelpers {
4 4
     public static <T> boolean contains(T[] haystack, T needle) {
5 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 7
                 return true;
8 8
         return false;
9 9
     }

Loading…
Peruuta
Tallenna