Skip to content

Commit 5391c05

Browse files
committed
Give a more descriptive error for invalid constant sizes
1 parent 032f53e commit 5391c05

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CastedEval.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,8 @@ public CastedExpression of(CastedExpression.Level level, Expression value) {
109109
public CastedExpression invalid(CompileError error) {
110110
return CastedExpression.invalid(position, error);
111111
}
112+
113+
public boolean isExplicit() {
114+
return explicit;
115+
}
112116
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileErrors.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ public static CompileError cannotCast(TypeID fromType, TypeID toType, boolean ex
170170
}
171171
}
172172

173+
public static CompileError constantSize(long value, TypeID toType) {
174+
return new CompileError(CompileExceptionCode.INVALID_CAST, "Cannot fit " + value + " in type " + toType);
175+
}
176+
173177
public static CompileError bracketMultipleExpressions() {
174178
return new CompileError(CompileExceptionCode.BRACKET_MULTIPLE_EXPRESSIONS, "Bracket expression may have only one expression");
175179
}

Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionInt.java

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import org.openzen.zenscript.codemodel.type.TypeID;
1313

1414
import java.util.Optional;
15+
import java.util.function.BiFunction;
16+
import java.util.function.Supplier;
1517

16-
public class ParsedExpressionInt extends ParsedExpression {
18+
public class ParsedExpressionInt extends ParsedExpression {
1719
public final boolean negative;
1820
public final long value;
1921
public final String suffix;
@@ -164,23 +166,23 @@ private CastedExpression asInt(CastedEval cast, BasicTypeID type) {
164166
long signed = negative ? -value : value;
165167
switch (type) {
166168
case SBYTE:
167-
return cast.of(level(signed >= Byte.MIN_VALUE && signed <= Byte.MAX_VALUE), new ConstantSByteExpression(position, (byte)value));
169+
return castIfFits(cast, signed >= Byte.MIN_VALUE && signed <= Byte.MAX_VALUE, (position, value) -> new ConstantSByteExpression(position, value.byteValue()));
168170
case BYTE:
169-
return cast.of(level(!negative && value <= 0xFF), new ConstantByteExpression(position, (int)value));
171+
return castIfFits(cast, !negative && value <= 0xFF, (position, value) -> new ConstantByteExpression(position, value.intValue()));
170172
case SHORT:
171-
return cast.of(level(signed >= Short.MIN_VALUE && signed <= Short.MAX_VALUE), new ConstantShortExpression(position, (short) value));
173+
return castIfFits(cast, signed >= Short.MIN_VALUE && signed <= Short.MAX_VALUE, (position, value) -> new ConstantShortExpression(position, value.shortValue()));
172174
case USHORT:
173-
return cast.of(level(!negative && value <= 0xFFFF), new ConstantUShortExpression(position, (int)value));
175+
return castIfFits(cast, !negative && value <= 0xFFFF, (position, value) -> new ConstantUShortExpression(position, value.intValue()));
174176
case INT:
175-
return cast.of(level(signed >= Integer.MIN_VALUE && signed <= Integer.MAX_VALUE), new ConstantIntExpression(position, (int)value));
177+
return castIfFits(cast, signed >= Integer.MIN_VALUE && signed <= Integer.MAX_VALUE, (position, value) -> new ConstantIntExpression(position, value.intValue()));
176178
case UINT:
177-
return cast.of(level(!negative && value <= 0xFFFFFFFFL), new ConstantUIntExpression(position, (int)value));
179+
return castIfFits(cast, !negative && value <= 0xFFFFFFFFL, (position, value) -> new ConstantUIntExpression(position, value.intValue()));
178180
case USIZE:
179-
return cast.of(level(!negative && value <= 0xFFFFFFFFL), new ConstantUSizeExpression(position, value));
181+
return castIfFits(cast, !negative && value <= 0xFFFFFFFFL, ConstantUSizeExpression::new);
180182
case LONG:
181183
return cast.of(new ConstantLongExpression(position, value));
182184
case ULONG:
183-
return cast.of(level(!negative), new ConstantULongExpression(position, value));
185+
return castIfFits(cast, !negative, ConstantULongExpression::new);
184186
case FLOAT:
185187
return cast.of(new ConstantFloatExpression(position, value));
186188
case DOUBLE:
@@ -190,6 +192,15 @@ private CastedExpression asInt(CastedEval cast, BasicTypeID type) {
190192
return cast.of(eval());
191193
}
192194

195+
private CastedExpression castIfFits(CastedEval cast, boolean fits, BiFunction<CodePosition, Long, Expression> expr){
196+
if(fits) {
197+
return cast.of(CastedExpression.Level.EXACT, expr.apply(this.position, this.value));
198+
} else if(cast.isExplicit()) {
199+
return cast.of(CastedExpression.Level.EXPLICIT, expr.apply(this.position, this.value));
200+
}
201+
return cast.invalid(CompileErrors.constantSize(this.value,cast.type));
202+
}
203+
193204
private boolean isIntegerType(TypeID type) {
194205
return type == BasicTypeID.BYTE
195206
|| type == BasicTypeID.SBYTE
@@ -202,9 +213,6 @@ private boolean isIntegerType(TypeID type) {
202213
|| type == BasicTypeID.USIZE;
203214
}
204215

205-
private CastedExpression.Level level(boolean fits) {
206-
return fits ? CastedExpression.Level.EXACT : CastedExpression.Level.EXPLICIT;
207-
}
208216
}
209217

210218
@Override
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#error: 6:INVALID_CAST
2+
function foo(i: int) {
3+
println(i);
4+
}
5+
6+
foo(0xFFFFFFFF);

0 commit comments

Comments
 (0)