瀏覽代碼

Fixed more bugs in the new type system; fixed bugs in function calls; fixed normalization bugs.

Stan Hebben 6 年之前
父節點
當前提交
cabd7bab44
共有 18 個檔案被更改,包括 131 行新增32 行删除
  1. 5
    2
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java
  2. 5
    3
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/ScriptBlock.java
  3. 1
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ConditionalExpression.java
  4. 8
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/LambdaScope.java
  5. 16
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/VariableID.java
  6. 5
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java
  7. 9
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/StoredType.java
  8. 9
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/TypeID.java
  9. 1
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinID.java
  10. 0
    1
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  11. 3
    0
      Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java
  12. 20
    7
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  13. 15
    2
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java
  14. 1
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java
  15. 3
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java
  16. 21
    9
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java
  17. 6
    1
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java
  18. 3
    3
      Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java

+ 5
- 2
CodeModel/src/main/java/org/openzen/zenscript/codemodel/HighLevelDefinition.java 查看文件

@@ -117,8 +117,11 @@ public abstract class HighLevelDefinition extends Taggable {
117 117
 		for (IDefinitionMember member : members) {
118 118
 			if (member instanceof DestructorMember)
119 119
 				isDestructible = true;
120
-			if ((member instanceof FieldMember) && ((FieldMember)member).type.isDestructible())
121
-				isDestructible = true;
120
+			if (member instanceof FieldMember) {
121
+				FieldMember field = (FieldMember)member;
122
+				if (!field.type.isDefinition(this) && field.type.isDestructible())
123
+					isDestructible = true;
124
+			}
122 125
 			if ((member instanceof ImplementationMember) && ((ImplementationMember)member).type.isDestructible())
123 126
 				isDestructible = true;
124 127
 		}

+ 5
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/ScriptBlock.java 查看文件

@@ -34,10 +34,12 @@ public class ScriptBlock extends Taggable {
34 34
 	}
35 35
 	
36 36
 	public ScriptBlock normalize(TypeScope scope) {
37
-		List<Statement> result = new ArrayList<>();
37
+		List<Statement> normalized = new ArrayList<>();
38 38
 		for (Statement statement : statements) {
39
-			result.add(statement.normalize(scope, ConcatMap.empty(LoopStatement.class, LoopStatement.class)));
39
+			normalized.add(statement.normalize(scope, ConcatMap.empty(LoopStatement.class, LoopStatement.class)));
40 40
 		}
41
-		return new ScriptBlock(pkg, result);
41
+		ScriptBlock result = new ScriptBlock(pkg, normalized);
42
+		result.addAllTagsFrom(this);
43
+		return result;
42 44
 	}
43 45
 }

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/ConditionalExpression.java 查看文件

@@ -26,7 +26,7 @@ public class ConditionalExpression extends Expression {
26 26
 			StoredType type) {
27 27
 		super(position, type, binaryThrow(position, condition.thrownType, binaryThrow(position, ifThen.thrownType, ifElse.thrownType)));
28 28
 		
29
-		if (ifThen.type != ifElse.type)
29
+		if (!ifThen.type.equals(ifElse.type))
30 30
 			throw new AssertionError();
31 31
 		
32 32
 		this.condition = condition;

+ 8
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/scope/LambdaScope.java 查看文件

@@ -8,14 +8,17 @@ package org.openzen.zenscript.codemodel.scope;
8 8
 import java.util.List;
9 9
 import org.openzen.zencode.shared.CodePosition;
10 10
 import org.openzen.zencode.shared.CompileException;
11
+import org.openzen.zencode.shared.CompileExceptionCode;
11 12
 import org.openzen.zenscript.codemodel.annotations.AnnotationDefinition;
12 13
 import org.openzen.zenscript.codemodel.FunctionHeader;
13 14
 import org.openzen.zenscript.codemodel.FunctionParameter;
14 15
 import org.openzen.zenscript.codemodel.GenericMapper;
15 16
 import org.openzen.zenscript.codemodel.expression.GetFunctionParameterExpression;
17
+import org.openzen.zenscript.codemodel.expression.InvalidExpression;
16 18
 import org.openzen.zenscript.codemodel.expression.LambdaClosure;
17 19
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
18 20
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
21
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
19 22
 import org.openzen.zenscript.codemodel.type.GenericName;
20 23
 import org.openzen.zenscript.codemodel.type.StoredType;
21 24
 import org.openzen.zenscript.codemodel.type.TypeID;
@@ -49,8 +52,12 @@ public class LambdaScope extends StatementScope {
49 52
 		if (outer == null) {
50 53
 			if (name.hasNoArguments()) {
51 54
 				for (FunctionParameter parameter : header.parameters) {
52
-					if (parameter.name.equals(name.name))
55
+					if (parameter.name.equals(name.name)) {
56
+						if (parameter.type.isBasic(BasicTypeID.UNDETERMINED))
57
+							throw new CompileException(position, CompileExceptionCode.CALL_NO_VALID_METHOD, "parameter with undetermined type");
58
+						
53 59
 						return new GetFunctionParameterExpression(position, parameter);
60
+					}
54 61
 				}
55 62
 			}
56 63
 

+ 16
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/VariableID.java 查看文件

@@ -0,0 +1,16 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.codemodel.statement;
7
+
8
+import org.openzen.zencode.shared.Taggable;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class VariableID extends Taggable {
15
+	
16
+}

+ 5
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/GenericTypeID.java 查看文件

@@ -59,6 +59,11 @@ public class GenericTypeID implements TypeID {
59 59
 	public boolean isDestructible() {
60 60
 		return false; // TODO: actually depends on the type..?
61 61
 	}
62
+	
63
+	@Override
64
+	public boolean isGeneric() {
65
+		return true;
66
+	}
62 67
 
63 68
 	@Override
64 69
 	public boolean hasInferenceBlockingTypeParameters(TypeParameter[] parameters) {

+ 9
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/StoredType.java 查看文件

@@ -8,10 +8,10 @@ package org.openzen.zenscript.codemodel.type;
8 8
 import java.util.Map;
9 9
 import java.util.Objects;
10 10
 import org.openzen.zenscript.codemodel.GenericMapper;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 13
 import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
13 14
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
14
-import org.openzen.zenscript.codemodel.type.storage.ValueStorageTag;
15 15
 
16 16
 /**
17 17
  *
@@ -66,6 +66,10 @@ public class StoredType {
66 66
 		return this.type == type;
67 67
 	}
68 68
 	
69
+	public boolean isGeneric() {
70
+		return type.isGeneric();
71
+	}
72
+	
69 73
 	public StoredType withoutOptional() {
70 74
 		return new StoredType(type.withoutOptional(), storage);
71 75
 	}
@@ -96,6 +100,10 @@ public class StoredType {
96 100
 		return type.isEnum();
97 101
 	}
98 102
 	
103
+	public boolean isDefinition(HighLevelDefinition definition) {
104
+		return type.isDefinition(definition);
105
+	}
106
+	
99 107
 	public DefinitionTypeID asDefinition() {
100 108
 		return (DefinitionTypeID)type;
101 109
 	}

+ 9
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/TypeID.java 查看文件

@@ -8,6 +8,7 @@ package org.openzen.zenscript.codemodel.type;
8 8
 import java.util.List;
9 9
 import java.util.Map;
10 10
 import org.openzen.zenscript.codemodel.GenericMapper;
11
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
11 12
 import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 13
 import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
13 14
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
@@ -62,6 +63,10 @@ public interface TypeID {
62 63
 		return false;
63 64
 	}
64 65
 	
66
+	default boolean isGeneric() {
67
+		return false;
68
+	}
69
+	
65 70
 	default TypeID withoutOptional() {
66 71
 		throw new UnsupportedOperationException("Not an optional type");
67 72
 	}
@@ -82,6 +87,10 @@ public interface TypeID {
82 87
 		return false;
83 88
 	}
84 89
 	
90
+	default boolean isDefinition(HighLevelDefinition definition) {
91
+		return false;
92
+	}
93
+	
85 94
 	default String toString(StorageTag storage) {
86 95
 		if (storage == ValueStorageTag.INSTANCE)
87 96
 			return toString();

+ 1
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinID.java 查看文件

@@ -152,6 +152,7 @@ public enum BuiltinID {
152 152
 	INT_INC,
153 153
 	INT_DEC,
154 154
 	INT_ADD_INT,
155
+	INT_ADD_USIZE,
155 156
 	INT_SUB_INT,
156 157
 	INT_MUL_INT,
157 158
 	INT_DIV_INT,

+ 0
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java 查看文件

@@ -771,7 +771,6 @@ public class TypeMemberBuilder implements TypeVisitorWithContext<Void, Void, Run
771 771
 		dec(builtin, INT_INC, INT);
772 772
 
773 773
 		add(builtin, INT_ADD_INT, INT, INT);
774
-		add(builtin, LONG_ADD_LONG, USIZE, LONG, INT_TO_LONG);
775 774
 		add(builtin, LONG_ADD_LONG, LONG, LONG, INT_TO_LONG);
776 775
 		add(builtin, FLOAT_ADD_FLOAT, FLOAT, FLOAT, INT_TO_FLOAT);
777 776
 		add(builtin, DOUBLE_ADD_DOUBLE, DOUBLE, DOUBLE, INT_TO_DOUBLE);

+ 3
- 0
Constructor/src/main/java/org/openzen/zenscript/constructor/module/DirectoryModuleReference.java 查看文件

@@ -26,6 +26,7 @@ import org.openzen.zenscript.constructor.ParsedModule;
26 26
 import org.openzen.zenscript.constructor.ModuleLoader;
27 27
 import org.openzen.zenscript.codemodel.type.TypeSymbol;
28 28
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
29
+import org.openzen.zenscript.lexer.ParseException;
29 30
 import org.openzen.zenscript.parser.ParsedFile;
30 31
 
31 32
 /**
@@ -112,6 +113,8 @@ public class DirectoryModuleReference implements ModuleReference {
112 113
 			return result;
113 114
 		} catch (IOException ex) {
114 115
 			throw new ConstructorException("Loading module files failed: " + ex.getMessage(), ex);
116
+		} catch (ParseException ex) {
117
+			throw new ConstructorException("Loading module files failed: " + ex.getMessage(), ex);
115 118
 		}
116 119
 	}
117 120
 	

+ 20
- 7
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java 查看文件

@@ -380,11 +380,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
380 380
 
381 381
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type))
382 382
 				throw new IllegalStateException("Call target has no method info!");
383
-			//if (expression.member.getHeader().returnType != expression.type)
384
-
385
-			//TODO see if the types differ (e.g. if a generic method was invoked) and only cast then
386
-			if(expression.type.type != BasicTypeID.VOID)
383
+			
384
+			if (expression.member.getTarget().header.getReturnType().isGeneric())
387 385
 				javaWriter.checkCast(context.getInternalName(expression.type));
386
+			
388 387
 			return null;
389 388
 		}
390 389
 
@@ -895,7 +894,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
895 894
 						JavaMethod.getNativeVirtual(
896 895
 								JavaClass.fromInternalName(context.getInternalName(expression.target.type), JavaClass.Kind.INTERFACE),
897 896
 								"accept",
898
-								context.getMethodSignature(expression.instancedHeader)));
897
+								context.getMethodDescriptor(expression.instancedHeader)));
899 898
 				break;
900 899
 			case AUTOOP_NOTEQUALS:
901 900
 				throw new UnsupportedOperationException("Not yet supported!");
@@ -1158,32 +1157,44 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1158 1157
 				javaWriter.invokeStatic(INTEGER_TO_STRING);
1159 1158
 				break;
1160 1159
 			case INT_TO_BYTE:
1160
+			case USIZE_TO_BYTE:
1161 1161
 				break;
1162 1162
 			case INT_TO_SBYTE:
1163
+			case USIZE_TO_SBYTE:
1163 1164
 				javaWriter.i2b();
1164 1165
 				break;
1165 1166
 			case INT_TO_SHORT:
1167
+			case USIZE_TO_SHORT:
1166 1168
 				javaWriter.i2s();
1167 1169
 				break;
1168 1170
 			case INT_TO_USHORT:
1171
+			case USIZE_TO_USHORT:
1169 1172
 				break;
1170 1173
 			case INT_TO_UINT:
1174
+			case USIZE_TO_INT:
1175
+			case USIZE_TO_UINT:
1171 1176
 			case INT_TO_USIZE:
1172 1177
 				break;
1173 1178
 			case INT_TO_LONG:
1174 1179
 			case INT_TO_ULONG:
1180
+			case USIZE_TO_LONG:
1181
+			case USIZE_TO_ULONG:
1175 1182
 				javaWriter.i2l();
1176 1183
 				break;
1177 1184
 			case INT_TO_FLOAT:
1185
+			case USIZE_TO_FLOAT:
1178 1186
 				javaWriter.i2f();
1179 1187
 				break;
1180 1188
 			case INT_TO_DOUBLE:
1189
+			case USIZE_TO_DOUBLE:
1181 1190
 				javaWriter.i2d();
1182 1191
 				break;
1183 1192
 			case INT_TO_CHAR:
1193
+			case USIZE_TO_CHAR:
1184 1194
 				javaWriter.i2s();
1185 1195
 				break;
1186 1196
 			case INT_TO_STRING:
1197
+			case USIZE_TO_STRING:
1187 1198
 				javaWriter.invokeStatic(INTEGER_TO_STRING);
1188 1199
 				break;
1189 1200
 			case UINT_TO_BYTE:
@@ -1646,10 +1657,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
1646 1657
             ((ReturnStatement) expression.body).value.accept(this);
1647 1658
             return null;
1648 1659
         }
1660
+		
1661
+		final String descriptor = context.getMethodDescriptor(expression.header);
1649 1662
         final String signature = context.getMethodSignature(expression.header);
1650 1663
 		final String name = context.getLambdaCounter();
1651 1664
 
1652
-		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, "accept", signature);
1665
+		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, "accept", descriptor);
1653 1666
 		final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
1654 1667
 		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))});
1655 1668
 		final JavaWriter functionWriter = new JavaWriter(lambdaCW, methodInfo, null, signature, null, "java/lang/Override");
@@ -2136,7 +2149,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
2136 2149
 
2137 2150
 	@Override
2138 2151
 	public Void visitNull(NullExpression expression) {
2139
-		if (expression.type.type.withoutOptional() == BasicTypeID.USIZE)
2152
+		if (!expression.type.isBasic(BasicTypeID.NULL) && expression.type.type.withoutOptional() == BasicTypeID.USIZE)
2140 2153
 			javaWriter.constant(-1); // special case: usize? null = -1
2141 2154
 		else
2142 2155
 			javaWriter.aConstNull();

+ 15
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java 查看文件

@@ -78,7 +78,12 @@ public class JavaWriter {
78 78
         if (debug)
79 79
             System.out.println("--end--");
80 80
 
81
-        visitor.visitMaxs(0, 0);
81
+		try {
82
+	        visitor.visitMaxs(0, 0);
83
+		} catch (ArrayIndexOutOfBoundsException ex) {
84
+			throw ex;
85
+		}
86
+		
82 87
         if (nameVariables) {
83 88
             for (JavaLocalVariableInfo info : localVariableInfos) {
84 89
                 nameVariable(info.local, info.name, info.start, info.end, info.type);
@@ -132,7 +137,7 @@ public class JavaWriter {
132 137
 
133 138
     public void aConstNull() {
134 139
         if (debug)
135
-            System.out.println("null");
140
+            System.out.println("aConstNull");
136 141
 
137 142
         visitor.visitInsn(ACONST_NULL);
138 143
     }
@@ -1111,6 +1116,14 @@ public class JavaWriter {
1111 1116
             keys[i] = switchLabels[i].key;
1112 1117
             labels[i] = switchLabels[i].label;
1113 1118
         }
1119
+		
1120
+		if (debug) {
1121
+			System.out.println("lookupSwitch");
1122
+			for (int i = 0; i < switchLabels.length; i++) {
1123
+				System.out.println("  " + keys[i] + " -> " + getLabelName(labels[i]));
1124
+			}
1125
+			System.out.println("  default -> " + getLabelName(defaultLabel));
1126
+		}
1114 1127
 
1115 1128
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1116 1129
     }

+ 1
- 1
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaContext.java 查看文件

@@ -177,7 +177,7 @@ public abstract class JavaContext {
177 177
 		String id = typeInfo.primitive ? type.accept(null, new JavaSyntheticTypeSignatureConverter()) : "T";
178 178
 		JavaSynthesizedRange range;
179 179
 		if (!ranges.containsKey(id)) {
180
-			JavaClass cls = new JavaClass("zsynthetic", id + "Range", JavaClass.Kind.CLASS);
180
+			JavaClass cls = new JavaClass("zsynthetic", id, JavaClass.Kind.CLASS);
181 181
 			if (typeInfo.primitive) {
182 182
 				range = new JavaSynthesizedRange(cls, TypeParameter.NONE, type.baseType);
183 183
 			} else {

+ 3
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaMethod.java 查看文件

@@ -53,6 +53,9 @@ public class JavaMethod {
53 53
 	public final boolean genericResult;
54 54
 	
55 55
 	public JavaMethod(JavaClass cls, Kind kind, String name, boolean compile, String descriptor, int modifiers, boolean genericResult) {
56
+		if (descriptor.contains("<")) // fix signature bug
57
+			throw new IllegalArgumentException("Invalid descriptor!");
58
+		
56 59
 		this.cls = cls;
57 60
 		this.kind = kind;
58 61
 		this.name = name;

+ 21
- 9
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java 查看文件

@@ -5,6 +5,7 @@
5 5
  */
6 6
 package org.openzen.zenscript.javasource;
7 7
 
8
+import org.openzen.zencode.shared.CompileException;
8 9
 import org.openzen.zencode.shared.StringExpansion;
9 10
 import org.openzen.zenscript.codemodel.CompareType;
10 11
 import org.openzen.zenscript.codemodel.FunctionHeader;
@@ -82,6 +83,7 @@ import org.openzen.zenscript.codemodel.expression.TryRethrowAsResultExpression;
82 83
 import org.openzen.zenscript.codemodel.expression.VariantValueExpression;
83 84
 import org.openzen.zenscript.codemodel.expression.WrapOptionalExpression;
84 85
 import org.openzen.zenscript.codemodel.statement.VarStatement;
86
+import org.openzen.zenscript.codemodel.statement.VariableID;
85 87
 import org.openzen.zenscript.codemodel.type.ArrayTypeID;
86 88
 import org.openzen.zenscript.codemodel.type.AssocTypeID;
87 89
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -249,8 +251,13 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
249 251
 	
250 252
 	@Override
251 253
 	public ExpressionString visitCast(CastExpression expression) {
252
-		if (expression.member.member.builtin != null)
253
-			return visitBuiltinCast(expression);
254
+		if (expression.member.member.builtin != null) {
255
+			try {
256
+				return visitBuiltinCast(expression);
257
+			} catch (CompileException ex) {
258
+				throw new RuntimeException(ex);
259
+			}
260
+		}
254 261
 		
255 262
 		JavaMethod method = expression.member.getTag(JavaMethod.class);
256 263
 		if (method == null)
@@ -526,8 +533,13 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
526 533
 
527 534
 	@Override
528 535
 	public ExpressionString visitNew(NewExpression expression) {
529
-		if (expression.constructor.getBuiltin() != null)
530
-			return visitBuiltinConstructor(expression);
536
+		if (expression.constructor.getBuiltin() != null) {
537
+			try {
538
+				return visitBuiltinConstructor(expression);
539
+			} catch (CompileException ex) {
540
+				throw new RuntimeException(ex.toString());
541
+			}
542
+		}
531 543
 		
532 544
 		JavaMethod method = expression.constructor.getTag(JavaMethod.class);
533 545
 		switch (method.kind) {
@@ -968,7 +980,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
968 980
 	}
969 981
 	
970 982
 	private Expression hoist(Expression value) {
971
-		VarStatement temp = new VarStatement(value.position, scope.createTempVariable(), value.type, value, true);
983
+		VarStatement temp = new VarStatement(value.position, new VariableID(), scope.createTempVariable(), value.type, value, true);
972 984
 		new JavaSourceStatementFormatter(scope).formatVar(target, temp);
973 985
 		return new GetLocalVariableExpression(value.position, temp);
974 986
 	}
@@ -1446,7 +1458,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1446 1458
 		throw new UnsupportedOperationException("Unknown builtin static getter: " + builtin);
1447 1459
 	}
1448 1460
 	
1449
-	private ExpressionString visitBuiltinCast(CastExpression cast) {
1461
+	private ExpressionString visitBuiltinCast(CastExpression cast) throws CompileException {
1450 1462
 		switch (cast.member.member.builtin) {
1451 1463
 			case BOOL_TO_STRING: return callStatic("Boolean.toString", cast.target);
1452 1464
 			case BYTE_TO_SBYTE: return cast(cast, "byte");
@@ -1602,7 +1614,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1602 1614
 		throw new UnsupportedOperationException("Unknown builtin cast: " + cast.member.member.builtin);
1603 1615
 	}
1604 1616
 	
1605
-	private ExpressionString visitBuiltinConstructor(NewExpression expression) {
1617
+	private ExpressionString visitBuiltinConstructor(NewExpression expression) throws CompileException {
1606 1618
 		switch (expression.constructor.getBuiltin()) {
1607 1619
 			case STRING_CONSTRUCTOR_CHARACTERS:
1608 1620
 				return callStatic("new String", expression.arguments.arguments[0]);
@@ -1766,7 +1778,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1766 1778
 							.append(newArray(type.elementType, originalString.unaryPostfix(JavaOperator.MEMBER, ".length")))
1767 1779
 							.append(";")
1768 1780
 							.toString());
1769
-					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT.stored, null, true);
1781
+					VarStatement tempI = new VarStatement(expression.position, new VariableID(), scope.createTempVariable(), BasicTypeID.INT.stored, null, true);
1770 1782
 					target.writeLine(new StringBuilder()
1771 1783
 							.append("for (int ")
1772 1784
 							.append(tempI.name)
@@ -1843,7 +1855,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1843 1855
 							.append(newArray(type.elementType, originalString.unaryPostfix(JavaOperator.MEMBER, ".length")))
1844 1856
 							.append(";")
1845 1857
 							.toString());
1846
-					VarStatement tempI = new VarStatement(expression.position, scope.createTempVariable(), BasicTypeID.INT.stored, null, true);
1858
+					VarStatement tempI = new VarStatement(expression.position, new VariableID(), scope.createTempVariable(), BasicTypeID.INT.stored, null, true);
1847 1859
 					target.writeLine(new StringBuilder()
1848 1860
 							.append("for (int ")
1849 1861
 							.append(tempI.name)

+ 6
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFunction.java 查看文件

@@ -74,8 +74,13 @@ public class ParsedExpressionFunction extends ParsedExpression {
74 74
 		StatementScope innerScope = new LambdaScope(scope, closure, header);
75 75
 		Statement statements = body.compile(innerScope, header);
76 76
 		
77
-		if (header.getReturnType().isBasic(BasicTypeID.UNDETERMINED))
77
+		if (header.getReturnType().isBasic(BasicTypeID.UNDETERMINED)) {
78
+			StoredType returnType = statements.getReturnType();
79
+			if (returnType == null)
80
+				throw new CompileException(position, CompileExceptionCode.CANNOT_INFER_RETURN_TYPE, "Could not infer return type");
81
+			
78 82
 			header.setReturnType(statements.getReturnType());
83
+		}
79 84
 		
80 85
 		if (!scope.genericInferenceMap.isEmpty()) {
81 86
 			// perform type parameter inference

+ 3
- 3
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java 查看文件

@@ -44,13 +44,13 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
44 44
 		expression.left.accept(this);
45 45
 		expression.right.accept(this);
46 46
 		
47
-		if (!expression.left.type.type.isBasic(BasicTypeID.BOOL)) {
47
+		if (!expression.left.type.isBasic(BasicTypeID.BOOL)) {
48 48
 			validator.logError(
49 49
 					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
50 50
 					expression.position,
51 51
 					"left hand side operand of && must be a bool");
52 52
 		}
53
-		if (!expression.right.type.type.isBasic(BasicTypeID.BOOL)) {
53
+		if (!expression.right.type.isBasic(BasicTypeID.BOOL)) {
54 54
 			validator.logError(
55 55
 					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
56 56
 					expression.position,
@@ -155,7 +155,7 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
155 155
 		expression.condition.accept(this);
156 156
 		expression.ifThen.accept(this);
157 157
 		expression.ifElse.accept(this);
158
-		if (!expression.condition.type.type.isBasic(BasicTypeID.BOOL)) {
158
+		if (!expression.condition.type.isBasic(BasicTypeID.BOOL)) {
159 159
 			validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, expression.position, "conditional expression condition must be a bool");
160 160
 		}
161 161
 		return null;

Loading…
取消
儲存