Browse Source

Expansion Getters/Setters, expansion static fields and Array contains

kindlich 6 years ago
parent
commit
28c635f584
No known key found for this signature in database

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

17
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
17
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
18
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
18
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
19
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
19
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
20
+import org.openzen.zenscript.javabytecode.compiler.JavaModificationExpressionVisitor.PushOption;
20
 import org.openzen.zenscript.javashared.*;
21
 import org.openzen.zenscript.javashared.*;
21
 
22
 
22
 import java.io.FileOutputStream;
23
 import java.io.FileOutputStream;
26
 import java.util.Comparator;
27
 import java.util.Comparator;
27
 import java.util.Objects;
28
 import java.util.Objects;
28
 import java.util.StringJoiner;
29
 import java.util.StringJoiner;
29
-import org.openzen.zenscript.javabytecode.compiler.JavaModificationExpressionVisitor.PushOption;
30
 
30
 
31
 public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativeTranslator<Void> {
31
 public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativeTranslator<Void> {
32
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
32
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
392
 			case STRING_RANGEGET:
392
 			case STRING_RANGEGET:
393
 			case ARRAY_INDEXGETRANGE:
393
 			case ARRAY_INDEXGETRANGE:
394
 			case ARRAY_INDEXGET:
394
 			case ARRAY_INDEXGET:
395
+			case ARRAY_CONTAINS:
395
 				break;
396
 				break;
396
 			case BYTE_INC:
397
 			case BYTE_INC:
397
 				modify(expression.target, () -> {
398
 				modify(expression.target, () -> {
457
 			case UINT_INC:
458
 			case UINT_INC:
458
 			case USIZE_INC:
459
 			case USIZE_INC:
459
 				if (expression.target instanceof GetLocalVariableExpression) {
460
 				if (expression.target instanceof GetLocalVariableExpression) {
460
-					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
461
+					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
461
 					javaWriter.iinc(local.local);
462
 					javaWriter.iinc(local.local);
462
 					javaWriter.load(local);
463
 					javaWriter.load(local);
463
 				} else {
464
 				} else {
471
 			case UINT_DEC:
472
 			case UINT_DEC:
472
 			case USIZE_DEC:
473
 			case USIZE_DEC:
473
 				if (expression.target instanceof GetLocalVariableExpression) {
474
 				if (expression.target instanceof GetLocalVariableExpression) {
474
-					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
475
+					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
475
 					javaWriter.iinc(local.local, -1);
476
 					javaWriter.iinc(local.local, -1);
476
 					javaWriter.load(local);
477
 					javaWriter.load(local);
477
 				} else {
478
 				} else {
525
 				final Label isFalse = new Label();
526
 				final Label isFalse = new Label();
526
 				final Label end = new Label();
527
 				final Label end = new Label();
527
 
528
 
528
-				if(builtin == BuiltinID.OPTIONAL_IS_NULL)
529
+				if (builtin == BuiltinID.OPTIONAL_IS_NULL)
529
 					javaWriter.ifNonNull(isFalse);
530
 					javaWriter.ifNonNull(isFalse);
530
 				else
531
 				else
531
 					javaWriter.ifNull(isFalse);
532
 					javaWriter.ifNull(isFalse);
995
 				break;
996
 				break;
996
 			}
997
 			}
997
 			case ARRAY_CONTAINS:
998
 			case ARRAY_CONTAINS:
998
-				throw new UnsupportedOperationException("Not yet supported!");
999
+				expression.target.accept(this);
1000
+				final Label loopStart = new Label();
1001
+				final Label loopEnd = new Label();
1002
+				final Label isTrue = new Label();
1003
+				final Label expressionEnd = new Label();
1004
+
1005
+				final int counterLocation = javaWriter.local(int.class);
1006
+				javaWriter.iConst0();
1007
+				javaWriter.storeInt(counterLocation);
1008
+
1009
+				javaWriter.label(loopStart);
1010
+				javaWriter.dup();
1011
+				javaWriter.arrayLength();
1012
+
1013
+				javaWriter.loadInt(counterLocation);
1014
+
1015
+				javaWriter.ifICmpLE(loopEnd);
1016
+				javaWriter.dup();
1017
+				javaWriter.loadInt(counterLocation);
1018
+				final StoredType itemType = expression.arguments.arguments[0].type;
1019
+				javaWriter.arrayLoad(context.getType(itemType));
1020
+				javaWriter.iinc(counterLocation);
1021
+				expression.arguments.arguments[0].accept(this);
1022
+
1023
+
1024
+				if (CompilerUtils.isPrimitive(itemType.type)) {
1025
+					//Compare non-int types beforehand
1026
+					if (itemType.type == BasicTypeID.LONG || itemType.type == BasicTypeID.ULONG) {
1027
+						javaWriter.lCmp();
1028
+						javaWriter.ifNE(loopStart);
1029
+					} else if (itemType.type == BasicTypeID.FLOAT) {
1030
+						javaWriter.fCmp();
1031
+						javaWriter.ifNE(loopStart);
1032
+					} else if (itemType.type == BasicTypeID.DOUBLE) {
1033
+						javaWriter.dCmp();
1034
+						javaWriter.ifNE(loopStart);
1035
+					} else
1036
+						javaWriter.ifICmpNE(loopStart);
1037
+				} else {
1038
+					//If equals, use Object.equals in case of null
1039
+					javaWriter.invokeStatic(new JavaMethod(JavaClass.fromInternalName("java/util/Objects", JavaClass.Kind.CLASS), JavaMethod.Kind.STATIC, "equals", false, "(Ljava/lang/Object;Ljava/lang/Object;)Z", 0, false));
1040
+					javaWriter.ifNE(loopStart);
1041
+					// If ==
1042
+					// javaWriter.ifACmpNe(loopStart);
1043
+				}
1044
+
1045
+				javaWriter.label(isTrue);
1046
+
1047
+				javaWriter.pop();
1048
+				javaWriter.iConst1();
1049
+				javaWriter.goTo(expressionEnd);
1050
+
1051
+				javaWriter.label(loopEnd);
1052
+				javaWriter.pop();
1053
+				javaWriter.iConst0();
1054
+				javaWriter.label(expressionEnd);
1055
+
1056
+				break;
999
 			case ARRAY_EQUALS:
1057
 			case ARRAY_EQUALS:
1000
 			case ARRAY_NOTEQUALS: {
1058
 			case ARRAY_NOTEQUALS: {
1001
 				ArrayTypeID type = (ArrayTypeID) expression.target.type.type;
1059
 				ArrayTypeID type = (ArrayTypeID) expression.target.type.type;
3459
 		javaWriter.aThrow();
3517
 		javaWriter.aThrow();
3460
 		return null;
3518
 		return null;
3461
 	}
3519
 	}
3462
-	
3520
+
3463
 	private void modify(Expression source, Runnable modification, PushOption push) {
3521
 	private void modify(Expression source, Runnable modification, PushOption push) {
3464
 		source.accept(new JavaModificationExpressionVisitor(context, module, javaWriter, this, modification, push));
3522
 		source.accept(new JavaModificationExpressionVisitor(context, module, javaWriter, this, modification, push));
3465
 	}
3523
 	}
3532
 				case UINT_INC:
3590
 				case UINT_INC:
3533
 				case USIZE_INC:
3591
 				case USIZE_INC:
3534
 					if (expression.target instanceof GetLocalVariableExpression) {
3592
 					if (expression.target instanceof GetLocalVariableExpression) {
3535
-						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
3593
+						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
3536
 						javaWriter.load(local);
3594
 						javaWriter.load(local);
3537
 						javaWriter.iinc(local.local);
3595
 						javaWriter.iinc(local.local);
3538
 					} else {
3596
 					} else {
3546
 				case UINT_DEC:
3604
 				case UINT_DEC:
3547
 				case USIZE_DEC:
3605
 				case USIZE_DEC:
3548
 					if (expression.target instanceof GetLocalVariableExpression) {
3606
 					if (expression.target instanceof GetLocalVariableExpression) {
3549
-						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
3607
+						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
3550
 						javaWriter.load(local);
3608
 						javaWriter.load(local);
3551
 						javaWriter.iinc(local.local, -1);
3609
 						javaWriter.iinc(local.local, -1);
3552
 					} else {
3610
 					} else {
3598
 					throw new IllegalArgumentException("Unknown postcall builtin: " + expression.member.getBuiltin());
3656
 					throw new IllegalArgumentException("Unknown postcall builtin: " + expression.member.getBuiltin());
3599
 			}
3657
 			}
3600
 		}
3658
 		}
3601
-		
3659
+
3602
 		modify(expression.target, () -> {
3660
 		modify(expression.target, () -> {
3603
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
3661
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
3604
 				throw new IllegalStateException("Call target has no method info!");
3662
 				throw new IllegalStateException("Call target has no method info!");
3605
 		}, PushOption.BEFORE);
3663
 		}, PushOption.BEFORE);
3606
-		
3664
+
3607
 		return null;
3665
 		return null;
3608
 	}
3666
 	}
3609
 
3667
 
3694
 				javaWriter.getStaticField(context.getJavaField(expression.getter));
3752
 				javaWriter.getStaticField(context.getJavaField(expression.getter));
3695
 				return null;
3753
 				return null;
3696
 			}
3754
 			}
3697
-			
3755
+
3698
 			if (!checkAndExecuteMethodInfo(expression.getter, expression.type, expression))
3756
 			if (!checkAndExecuteMethodInfo(expression.getter, expression.type, expression))
3699
 				throw new IllegalStateException("Call target has no method info!");
3757
 				throw new IllegalStateException("Call target has no method info!");
3700
 
3758
 
3876
 
3934
 
3877
 	//Will return true if a JavaMethodInfo.class tag exists, and will compile that tag
3935
 	//Will return true if a JavaMethodInfo.class tag exists, and will compile that tag
3878
 	@SuppressWarnings({"Raw", "unchecked"})
3936
 	@SuppressWarnings({"Raw", "unchecked"})
3879
-	private boolean checkAndExecuteMethodInfo(DefinitionMemberRef member, StoredType resultType, Expression expression) {
3937
+	boolean checkAndExecuteMethodInfo(DefinitionMemberRef member, StoredType resultType, Expression expression) {
3880
 		JavaMethod methodInfo = context.getJavaMethod(member);
3938
 		JavaMethod methodInfo = context.getJavaMethod(member);
3881
 		if (methodInfo == null)
3939
 		if (methodInfo == null)
3882
 			return false;
3940
 			return false;

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

623
 
623
 
624
 	@Override
624
 	@Override
625
 	public Void visitSetter(SetterExpression expression) {
625
 	public Void visitSetter(SetterExpression expression) {
626
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
626
+		expression.target.accept(original);
627
+		expression.value.accept(original);
628
+		original.checkAndExecuteMethodInfo(expression.setter, expression.type, expression);
629
+		return null;
627
 	}
630
 	}
628
 
631
 
629
 	@Override
632
 	@Override

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

23
 	private final HighLevelDefinition definition;
23
 	private final HighLevelDefinition definition;
24
 	private final JavaCompiledModule javaModule;
24
 	private final JavaCompiledModule javaModule;
25
 
25
 
26
+	private final JavaStatementVisitor clinitStatementVisitor;
27
+
26
 	public JavaExpansionMemberVisitor(JavaBytecodeContext context, ClassWriter writer, StoredType expandedClass, HighLevelDefinition definition) {
28
 	public JavaExpansionMemberVisitor(JavaBytecodeContext context, ClassWriter writer, StoredType expandedClass, HighLevelDefinition definition) {
27
 		this.writer = writer;
29
 		this.writer = writer;
28
 		this.expandedClass = expandedClass;
30
 		this.expandedClass = expandedClass;
29
 		this.definition = definition;
31
 		this.definition = definition;
30
 		this.context = context;
32
 		this.context = context;
31
 		javaModule = context.getJavaModule(definition.module);
33
 		javaModule = context.getJavaModule(definition.module);
34
+
35
+		final JavaWriter javaWriter = new JavaWriter(definition.position, writer, new JavaMethod(context.getJavaClass(definition), JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
36
+		this.clinitStatementVisitor = new JavaStatementVisitor(context, javaModule, javaWriter);
37
+		this.clinitStatementVisitor.start();
38
+		CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
32
 	}
39
 	}
33
 
40
 
34
 	public void end() {
41
 	public void end() {
42
+		clinitStatementVisitor.end();
35
 	}
43
 	}
36
 
44
 
37
 	@Override
45
 	@Override
43
 
51
 
44
 	@Override
52
 	@Override
45
 	public Void visitField(FieldMember member) {
53
 	public Void visitField(FieldMember member) {
46
-		throw new IllegalStateException("Cannot add fields via expansions");
54
+		if (!member.isStatic())
55
+			throw new IllegalStateException("Cannot add fields via expansions");
56
+
57
+		JavaField field = context.getJavaField(member);
58
+		writer.visitField(CompilerUtils.calcAccess(member.getEffectiveModifiers()), field.name, field.descriptor, field.signature, null).visitEnd();
59
+
60
+		return null;
61
+
62
+
47
 	}
63
 	}
48
 
64
 
49
 	@Override
65
 	@Override
150
 
166
 
151
 	@Override
167
 	@Override
152
 	public Void visitStaticInitializer(StaticInitializerMember member) {
168
 	public Void visitStaticInitializer(StaticInitializerMember member) {
153
-		throw new IllegalStateException("Cannot add Static initializers via expansions");
169
+		member.body.accept(clinitStatementVisitor);
170
+		return null;
154
 	}
171
 	}
155
 }
172
 }

Loading…
Cancel
Save