Browse Source

- Fix missing shift operators in some integer types

- Fix some problems when comparing a long with an int or ulong with uint
- Add signed-unsigned implicit array conversion (sbyte[] <-> byte[], short[] <-> ushort[], int[] <-> uint[], long[] <-> ulong[])
- Fix bug when copying multiple lines from the source editor
- Added string <-> byte[] conversion operations
- Fix unsigned arrays, use compact representations
- Added suffixes & custom suffixes
- Added 0x 0b 0o for hex, binary and octal notation
Stan Hebben 6 years ago
parent
commit
3e013cb052
17 changed files with 466 additions and 96 deletions
  1. 4
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java
  2. 23
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinID.java
  3. 9
    0
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java
  4. 57
    26
      CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java
  5. 6
    0
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java
  6. 1
    1
      IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java
  7. 28
    4
      JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java
  8. 8
    0
      JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaNativeTranslator.java
  9. 18
    1
      JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java
  10. 126
    32
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java
  11. 4
    1
      JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceImporter.java
  12. 3
    2
      Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java
  13. 4
    3
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java
  14. 53
    14
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFloat.java
  15. 119
    10
      Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionInt.java
  16. 1
    1
      ScriptingExample/build.gradle
  17. 2
    1
      Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java

+ 4
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java View File

@@ -462,4 +462,8 @@ public class FunctionHeader {
462 462
 		
463 463
 		return false;
464 464
 	}
465
+
466
+	public boolean accepts(int arguments) {
467
+		return arguments >= this.minParameters && arguments <= this.maxParameters;
468
+	}
465 469
 }

+ 23
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/BuiltinID.java View File

@@ -30,6 +30,8 @@ public enum BuiltinID {
30 30
 	BYTE_AND_BYTE,
31 31
 	BYTE_OR_BYTE,
32 32
 	BYTE_XOR_BYTE,
33
+	BYTE_SHL,
34
+	BYTE_SHR,
33 35
 	BYTE_COMPARE,
34 36
 	BYTE_TO_SBYTE,
35 37
 	BYTE_TO_SHORT,
@@ -60,6 +62,9 @@ public enum BuiltinID {
60 62
 	SBYTE_AND_SBYTE,
61 63
 	SBYTE_OR_SBYTE,
62 64
 	SBYTE_XOR_SBYTE,
65
+	SBYTE_SHL,
66
+	SBYTE_SHR,
67
+	SBYTE_USHR,
63 68
 	SBYTE_COMPARE,
64 69
 	SBYTE_TO_BYTE,
65 70
 	SBYTE_TO_SHORT,
@@ -90,6 +95,9 @@ public enum BuiltinID {
90 95
 	SHORT_AND_SHORT,
91 96
 	SHORT_OR_SHORT,
92 97
 	SHORT_XOR_SHORT,
98
+	SHORT_SHL,
99
+	SHORT_SHR,
100
+	SHORT_USHR,
93 101
 	SHORT_COMPARE,
94 102
 	SHORT_TO_BYTE,
95 103
 	SHORT_TO_SBYTE,
@@ -119,6 +127,8 @@ public enum BuiltinID {
119 127
 	USHORT_AND_USHORT,
120 128
 	USHORT_OR_USHORT,
121 129
 	USHORT_XOR_USHORT,
130
+	USHORT_SHL,
131
+	USHORT_SHR,
122 132
 	USHORT_COMPARE,
123 133
 	USHORT_TO_BYTE,
124 134
 	USHORT_TO_SBYTE,
@@ -235,6 +245,7 @@ public enum BuiltinID {
235 245
 	LONG_SHR,
236 246
 	LONG_USHR,
237 247
 	LONG_COMPARE,
248
+	LONG_COMPARE_INT,
238 249
 	LONG_TO_BYTE,
239 250
 	LONG_TO_SBYTE,
240 251
 	LONG_TO_SHORT,
@@ -275,6 +286,8 @@ public enum BuiltinID {
275 286
 	ULONG_SHL,
276 287
 	ULONG_SHR,
277 288
 	ULONG_COMPARE,
289
+	ULONG_COMPARE_UINT,
290
+	ULONG_COMPARE_USIZE,
278 291
 	ULONG_TO_BYTE,
279 292
 	ULONG_TO_SBYTE,
280 293
 	ULONG_TO_SHORT,
@@ -315,6 +328,7 @@ public enum BuiltinID {
315 328
 	USIZE_SHL,
316 329
 	USIZE_SHR,
317 330
 	USIZE_COMPARE,
331
+	USIZE_COMPARE_UINT,
318 332
 	USIZE_TO_BYTE,
319 333
 	USIZE_TO_SBYTE,
320 334
 	USIZE_TO_SHORT,
@@ -474,6 +488,15 @@ public enum BuiltinID {
474 488
 	ARRAY_SAME,
475 489
 	ARRAY_NOTSAME,
476 490
 	
491
+	SBYTE_ARRAY_AS_BYTE_ARRAY,
492
+	BYTE_ARRAY_AS_SBYTE_ARRAY,
493
+	SHORT_ARRAY_AS_USHORT_ARRAY,
494
+	USHORT_ARRAY_AS_SHORT_ARRAY,
495
+	INT_ARRAY_AS_UINT_ARRAY,
496
+	UINT_ARRAY_AS_INT_ARRAY,
497
+	LONG_ARRAY_AS_ULONG_ARRAY,
498
+	ULONG_ARRAY_AS_LONG_ARRAY,
499
+	
477 500
 	FUNCTION_CALL,
478 501
 	FUNCTION_SAME,
479 502
 	FUNCTION_NOTSAME,

+ 9
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java View File

@@ -105,6 +105,15 @@ public class DefinitionMemberGroup {
105 105
 		return false;
106 106
 	}
107 107
 	
108
+	public FunctionalMemberRef getStaticMethod(int arguments, ITypeID returnType) {
109
+		for (TypeMember<FunctionalMemberRef> method : methods) {
110
+			if (method.member.isStatic() && method.member.getHeader().accepts(arguments) && method.member.getHeader().getReturnType() == returnType)
111
+				return method.member;
112
+		}
113
+		
114
+		return null;
115
+	}
116
+	
108 117
 	public List<TypeMember<FunctionalMemberRef>> getMethodMembers() {
109 118
 		return this.methods;
110 119
 	}

+ 57
- 26
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/TypeMemberBuilder.java View File

@@ -193,6 +193,23 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
193 193
 					OperatorType.INDEXGET,
194 194
 					sliceHeader,
195 195
 					ARRAY_INDEXGETRANGE);
196
+			
197
+			if (baseType == BYTE)
198
+				castImplicit(definition, BYTE_ARRAY_AS_SBYTE_ARRAY, registry.getArray(SBYTE, 1));
199
+			if (baseType == SBYTE)
200
+				castImplicit(definition, SBYTE_ARRAY_AS_BYTE_ARRAY, registry.getArray(BYTE, 1));
201
+			if (baseType == SHORT)
202
+				castImplicit(definition, SHORT_ARRAY_AS_USHORT_ARRAY, registry.getArray(USHORT, 1));
203
+			if (baseType == USHORT)
204
+				castImplicit(definition, USHORT_ARRAY_AS_SHORT_ARRAY, registry.getArray(SHORT, 1));
205
+			if (baseType == INT)
206
+				castImplicit(definition, INT_ARRAY_AS_UINT_ARRAY, registry.getArray(UINT, 1));
207
+			if (baseType == UINT)
208
+				castImplicit(definition, UINT_ARRAY_AS_INT_ARRAY, registry.getArray(INT, 1));
209
+			if (baseType == LONG)
210
+				castImplicit(definition, LONG_ARRAY_AS_ULONG_ARRAY, registry.getArray(ULONG, 1));
211
+			if (baseType == ULONG)
212
+				castImplicit(definition, ULONG_ARRAY_AS_LONG_ARRAY, registry.getArray(LONG, 1));
196 213
 		}
197 214
 
198 215
 		FunctionHeader containsHeader = new FunctionHeader(BOOL, new FunctionParameter(baseType, "value"));
@@ -558,6 +575,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
558 575
 		and(builtin, BYTE_AND_BYTE, BYTE, BYTE);
559 576
 		or(builtin, BYTE_OR_BYTE, BYTE, BYTE);
560 577
 		xor(builtin, BYTE_XOR_BYTE, BYTE, BYTE);
578
+		shl(builtin, BYTE_SHL, USIZE, BYTE);
579
+		shr(builtin, BYTE_SHR, USIZE, BYTE);
561 580
 		compare(builtin, BYTE_COMPARE, BYTE);
562 581
 		
563 582
 		castImplicit(builtin, BYTE_TO_SBYTE, SBYTE);
@@ -597,6 +616,9 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
597 616
 		and(builtin, SBYTE_AND_SBYTE, SBYTE, SBYTE);
598 617
 		or(builtin, SBYTE_OR_SBYTE, SBYTE, SBYTE);
599 618
 		xor(builtin, SBYTE_XOR_SBYTE, SBYTE, SBYTE);
619
+		shl(builtin, SBYTE_SHL, USIZE, SBYTE);
620
+		shr(builtin, SBYTE_SHR, USIZE, SBYTE);
621
+		ushr(builtin, SBYTE_USHR, USIZE, SBYTE);
600 622
 		compare(builtin, SBYTE_COMPARE, SBYTE);
601 623
 		
602 624
 		castImplicit(builtin, SBYTE_TO_BYTE, BYTE);
@@ -636,6 +658,9 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
636 658
 		and(builtin, SHORT_AND_SHORT, SHORT, SHORT);
637 659
 		or(builtin, SHORT_OR_SHORT, SHORT, SHORT);
638 660
 		xor(builtin, SHORT_XOR_SHORT, SHORT, SHORT);
661
+		shl(builtin, SHORT_SHL, USIZE, SHORT);
662
+		shr(builtin, SHORT_SHR, USIZE, SHORT);
663
+		ushr(builtin, SHORT_USHR, USIZE, SHORT);
639 664
 		compare(builtin, SHORT_COMPARE, SHORT);
640 665
 		
641 666
 		castExplicit(builtin, SHORT_TO_BYTE, BYTE);
@@ -674,6 +699,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
674 699
 		and(builtin, USHORT_AND_USHORT, USHORT, USHORT);
675 700
 		or(builtin, USHORT_OR_USHORT, USHORT, USHORT);
676 701
 		xor(builtin, USHORT_XOR_USHORT, USHORT, USHORT);
702
+		shl(builtin, USHORT_SHL, USIZE, USHORT);
703
+		shr(builtin, USHORT_SHR, USIZE, USHORT);
677 704
 		compare(builtin, USHORT_COMPARE, USHORT);
678 705
 		
679 706
 		castExplicit(builtin, USHORT_TO_BYTE, BYTE);
@@ -736,9 +763,9 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
736 763
 		xor(builtin, INT_XOR_INT, INT, INT);
737 764
 		xor(builtin, LONG_XOR_LONG, LONG, LONG, INT_TO_LONG);
738 765
 		
739
-		shl(builtin, INT_SHL, INT, INT);
740
-		shr(builtin, INT_SHR, INT, INT);
741
-		ushr(builtin, INT_USHR, INT, INT);
766
+		shl(builtin, INT_SHL, USIZE, INT);
767
+		shr(builtin, INT_SHR, USIZE, INT);
768
+		ushr(builtin, INT_USHR, USIZE, INT);
742 769
 		
743 770
 		compare(builtin, INT_COMPARE, INT);
744 771
 		compare(builtin, LONG_COMPARE, LONG, INT_TO_LONG);
@@ -816,8 +843,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
816 843
 		xor(builtin, UINT_XOR_UINT, UINT, UINT);
817 844
 		xor(builtin, ULONG_XOR_ULONG, ULONG, ULONG, UINT_TO_ULONG);
818 845
 		
819
-		shl(builtin, UINT_SHL, UINT, UINT);
820
-		shr(builtin, UINT_SHR, UINT, UINT);
846
+		shl(builtin, UINT_SHL, USIZE, UINT);
847
+		shr(builtin, UINT_SHR, USIZE, UINT);
821 848
 		
822 849
 		compare(builtin, UINT_COMPARE, UINT);
823 850
 		compare(builtin, ULONG_COMPARE, ULONG, UINT_TO_LONG);
@@ -888,10 +915,11 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
888 915
 		and(builtin, LONG_AND_LONG, LONG, LONG);
889 916
 		xor(builtin, LONG_XOR_LONG, LONG, LONG);
890 917
 		
891
-		shl(builtin, LONG_SHL, INT, LONG);
892
-		shr(builtin, LONG_SHR, INT, LONG);
893
-		ushr(builtin, LONG_USHR, INT, LONG);
918
+		shl(builtin, LONG_SHL, USIZE, LONG);
919
+		shr(builtin, LONG_SHR, USIZE, LONG);
920
+		ushr(builtin, LONG_USHR, USIZE, LONG);
894 921
 		
922
+		compare(builtin, LONG_COMPARE_INT, INT);
895 923
 		compare(builtin, LONG_COMPARE, LONG);
896 924
 		compare(builtin, FLOAT_COMPARE, FLOAT, LONG_TO_FLOAT);
897 925
 		compare(builtin, DOUBLE_COMPARE, DOUBLE, LONG_TO_DOUBLE);
@@ -959,9 +987,11 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
959 987
 		and(builtin, ULONG_AND_ULONG, ULONG, ULONG);
960 988
 		xor(builtin, ULONG_XOR_ULONG, ULONG, ULONG);
961 989
 		
962
-		shl(builtin, ULONG_SHL, INT, ULONG);
963
-		shr(builtin, ULONG_SHR, INT, ULONG);
990
+		shl(builtin, ULONG_SHL, USIZE, ULONG);
991
+		shr(builtin, ULONG_SHR, USIZE, ULONG);
964 992
 		
993
+		compare(builtin, ULONG_COMPARE_UINT, UINT);
994
+		compare(builtin, ULONG_COMPARE_USIZE, USIZE);
965 995
 		compare(builtin, ULONG_COMPARE, ULONG);
966 996
 		compare(builtin, FLOAT_COMPARE, FLOAT, ULONG_TO_FLOAT);
967 997
 		compare(builtin, DOUBLE_COMPARE, DOUBLE, ULONG_TO_DOUBLE);
@@ -1033,9 +1063,10 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1033 1063
 		and(builtin, USIZE_AND_USIZE, USIZE, USIZE);
1034 1064
 		xor(builtin, USIZE_XOR_USIZE, USIZE, USIZE);
1035 1065
 		
1036
-		shl(builtin, USIZE_SHL, INT, USIZE);
1037
-		shr(builtin, USIZE_SHR, INT, USIZE);
1066
+		shl(builtin, USIZE_SHL, USIZE, USIZE);
1067
+		shr(builtin, USIZE_SHR, USIZE, USIZE);
1038 1068
 		
1069
+		compare(builtin, USIZE_COMPARE_UINT, UINT);
1039 1070
 		compare(builtin, USIZE_COMPARE, USIZE);
1040 1071
 		compare(builtin, ULONG_COMPARE, ULONG, USIZE_TO_ULONG);
1041 1072
 		compare(builtin, FLOAT_COMPARE, FLOAT, USIZE_TO_FLOAT);
@@ -1143,7 +1174,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1143 1174
 		castExplicit(builtin, DOUBLE_TO_USHORT, USHORT);
1144 1175
 		castExplicit(builtin, DOUBLE_TO_INT, INT);
1145 1176
 		castExplicit(builtin, DOUBLE_TO_UINT, UINT);
1146
-		castExplicit(builtin, DOUBLE_TO_ULONG, ULONG);
1177
+		castExplicit(builtin, DOUBLE_TO_LONG, LONG);
1147 1178
 		castExplicit(builtin, DOUBLE_TO_ULONG, ULONG);
1148 1179
 		castExplicit(builtin, DOUBLE_TO_USIZE, USIZE);
1149 1180
 		castImplicit(builtin, DOUBLE_TO_FLOAT, FLOAT);
@@ -1210,8 +1241,8 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1210 1241
 		processType(builtin, STRING);
1211 1242
 	}
1212 1243
 	
1213
-	private void castedTargetCall(OperatorMember member, BuiltinID casterBuiltin) {
1214
-		CasterMemberRef caster = castImplicitRef(member.definition, casterBuiltin, member.header.parameters[0].type);
1244
+	private void castedTargetCall(OperatorMember member, ITypeID toType, BuiltinID casterBuiltin) {
1245
+		CasterMemberRef caster = castImplicitRef(member.definition, casterBuiltin, toType);
1215 1246
 		TranslatedOperatorMemberRef method = new TranslatedOperatorMemberRef(member, GenericMapper.EMPTY, call -> member.ref(null).call(call.position, caster.cast(call.position, call.target, true), call.arguments, call.scope));
1216 1247
 		members.getOrCreateGroup(member.operator).addMethod(method, TypeMemberPriority.SPECIFIED);
1217 1248
 	}
@@ -1269,7 +1300,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1269 1300
 	}
1270 1301
 	
1271 1302
 	private void add(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1272
-		castedTargetCall(addOp(definition, id, operand, result), caster);
1303
+		castedTargetCall(addOp(definition, id, operand, result), result, caster);
1273 1304
 	}
1274 1305
 	
1275 1306
 	private OperatorMember subOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1287,7 +1318,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1287 1318
 	}
1288 1319
 	
1289 1320
 	private void sub(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1290
-		castedTargetCall(subOp(definition, id, operand, result), caster);
1321
+		castedTargetCall(subOp(definition, id, operand, result), result, caster);
1291 1322
 	}
1292 1323
 	
1293 1324
 	private OperatorMember mulOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1305,7 +1336,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1305 1336
 	}
1306 1337
 	
1307 1338
 	private void mul(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1308
-		castedTargetCall(mulOp(definition, id, operand, result), caster);
1339
+		castedTargetCall(mulOp(definition, id, operand, result), result, caster);
1309 1340
 	}
1310 1341
 	
1311 1342
 	private OperatorMember divOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1323,7 +1354,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1323 1354
 	}
1324 1355
 	
1325 1356
 	private void div(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1326
-		castedTargetCall(divOp(definition, id, operand, result), caster);
1357
+		castedTargetCall(divOp(definition, id, operand, result), result, caster);
1327 1358
 	}
1328 1359
 	
1329 1360
 	private OperatorMember modOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1341,7 +1372,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1341 1372
 	}
1342 1373
 	
1343 1374
 	private void mod(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1344
-		castedTargetCall(modOp(definition, id, operand, result), caster);
1375
+		castedTargetCall(modOp(definition, id, operand, result), result, caster);
1345 1376
 	}
1346 1377
 	
1347 1378
 	private OperatorMember shlOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1359,7 +1390,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1359 1390
 	}
1360 1391
 	
1361 1392
 	private void shl(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1362
-		castedTargetCall(shlOp(definition, id, operand, result), caster);
1393
+		castedTargetCall(shlOp(definition, id, operand, result), result, caster);
1363 1394
 	}
1364 1395
 	
1365 1396
 	private OperatorMember shrOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1377,7 +1408,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1377 1408
 	}
1378 1409
 	
1379 1410
 	private void shr(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1380
-		castedTargetCall(shrOp(definition, id, operand, result), caster);
1411
+		castedTargetCall(shrOp(definition, id, operand, result), result, caster);
1381 1412
 	}
1382 1413
 	
1383 1414
 	private OperatorMember ushrOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1395,7 +1426,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1395 1426
 	}
1396 1427
 	
1397 1428
 	private void ushr(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1398
-		castedTargetCall(ushrOp(definition, id, operand, result), caster);
1429
+		castedTargetCall(ushrOp(definition, id, operand, result), result, caster);
1399 1430
 	}
1400 1431
 	
1401 1432
 	private OperatorMember orOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1431,7 +1462,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1431 1462
 	}
1432 1463
 	
1433 1464
 	private void and(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1434
-		castedTargetCall(andOp(definition, id, operand, result), caster);
1465
+		castedTargetCall(andOp(definition, id, operand, result), result, caster);
1435 1466
 	}
1436 1467
 	
1437 1468
 	private OperatorMember xorOp(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1449,7 +1480,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1449 1480
 	}
1450 1481
 	
1451 1482
 	private void xor(HighLevelDefinition definition, BuiltinID id, ITypeID operand, ITypeID result, BuiltinID caster) {
1452
-		castedTargetCall(xorOp(definition, id, operand, result), caster);
1483
+		castedTargetCall(xorOp(definition, id, operand, result), result, caster);
1453 1484
 	}
1454 1485
 	
1455 1486
 	private void indexGet(HighLevelDefinition cls, BuiltinID id, ITypeID operand, ITypeID result) {
@@ -1487,7 +1518,7 @@ public class TypeMemberBuilder implements ITypeVisitor<Void> {
1487 1518
 	}
1488 1519
 	
1489 1520
 	private void compare(HighLevelDefinition definition, BuiltinID id, ITypeID operand, BuiltinID caster) {
1490
-		castedTargetCall(compareOp(definition, id, operand), caster);
1521
+		castedTargetCall(compareOp(definition, id, operand), operand, caster);
1491 1522
 	}
1492 1523
 	
1493 1524
 	private void getter(HighLevelDefinition cls, BuiltinID id, String name, ITypeID type) {

+ 6
- 0
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/SourceEditor.java View File

@@ -470,6 +470,11 @@ public class SourceEditor implements DComponent {
470 470
 		String extract = tokens.extract(
471 471
 				SourcePosition.min(cursorStart, cursorEnd),
472 472
 				SourcePosition.max(cursorStart, cursorEnd));
473
+		if (context.getUIContext() == null)
474
+			throw new NullPointerException("No context!");
475
+		if (context.getUIContext().getClipboard() == null)
476
+			throw new NullPointerException("No clipboard!");
477
+		
473 478
 		context.getUIContext().getClipboard().copyAsString(extract);
474 479
 	}
475 480
 	
@@ -816,6 +821,7 @@ public class SourceEditor implements DComponent {
816 821
 					return IDENTIFIER;
817 822
 				case T_FLOAT:
818 823
 				case T_INT:
824
+				case T_PREFIXED_INT:
819 825
 					return NUMBER;
820 826
 				case T_STRING_SQ:
821 827
 				case T_STRING_DQ:

+ 1
- 1
IDE/src/main/java/org/openzen/zenscript/ide/ui/view/editor/TokenModel.java View File

@@ -120,7 +120,7 @@ public class TokenModel {
120 120
 			
121 121
 			for (int i = fromT.line + 1; i < toT.line; i++) {
122 122
 				result.append("\n");
123
-				for (ZSToken t : fromLine.getTokens()) {
123
+				for (ZSToken t : getLine(i).getTokens()) {
124 124
 					result.append(t.content);
125 125
 				}
126 126
 			}

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

@@ -31,10 +31,6 @@ import org.openzen.zenscript.javashared.JavaSynthesizedClassNamer;
31 31
 import org.openzen.zenscript.javashared.JavaVariantOption;
32 32
 
33 33
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
34
-	private static final int PUBLIC = Opcodes.ACC_PUBLIC;
35
-	private static final int STATIC = Opcodes.ACC_STATIC;
36
-	private static final int PUBLIC_STATIC = PUBLIC | STATIC;
37
-
38 34
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
39 35
 	private static final JavaMethod BOOLEAN_TO_STRING = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "toString", "(Z)Ljava/lang/String;");
40 36
 	private static final JavaMethod BYTE_PARSE = JavaMethod.getNativeStatic(JavaClass.BYTE, "parseByte", "(Ljava/lang/String;)B");
@@ -224,11 +220,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
224 220
 				case SHORT_COMPARE:
225 221
 				case INT_COMPARE:
226 222
 				case CHAR_COMPARE:
223
+				case USIZE_COMPARE:
227 224
 					expression.left.accept(this);
228 225
 					expression.right.accept(this);
229 226
 					compareInt(expression.comparison);
230 227
 					break;
231 228
 				case UINT_COMPARE:
229
+				case USIZE_COMPARE_UINT:
232 230
 					expression.left.accept(this);
233 231
 					expression.right.accept(this);
234 232
 					javaWriter.invokeStatic(INTEGER_COMPARE_UNSIGNED);
@@ -246,6 +244,22 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
246 244
 					javaWriter.invokeStatic(LONG_COMPARE_UNSIGNED);
247 245
 					compareGeneric(expression.comparison);
248 246
 					break;
247
+				case ULONG_COMPARE_UINT:
248
+					expression.left.accept(this);
249
+					expression.right.accept(this);
250
+					javaWriter.i2l();
251
+					javaWriter.constant(0xFFFF_FFFFL);
252
+					javaWriter.lAnd();
253
+					javaWriter.invokeStatic(LONG_COMPARE_UNSIGNED);
254
+					compareGeneric(expression.comparison);
255
+					break;
256
+				case ULONG_COMPARE_USIZE:
257
+					expression.left.accept(this);
258
+					expression.right.accept(this);
259
+					javaWriter.i2l();
260
+					javaWriter.invokeStatic(LONG_COMPARE_UNSIGNED);
261
+					compareGeneric(expression.comparison);
262
+					break;
249 263
 				case FLOAT_COMPARE:
250 264
 					expression.left.accept(this);
251 265
 					expression.right.accept(this);
@@ -486,14 +500,24 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
486 500
 			case USIZE_XOR_USIZE:
487 501
 				javaWriter.iXor();
488 502
 				break;
503
+			case BYTE_SHL:
504
+			case SBYTE_SHL:
505
+			case SHORT_SHL:
506
+			case USHORT_SHL:
489 507
 			case INT_SHL:
490 508
 			case UINT_SHL:
491 509
 			case USIZE_SHL:
492 510
 				javaWriter.iShl();
493 511
 				break;
512
+			case SBYTE_SHR:
513
+			case SHORT_SHR:
494 514
 			case INT_SHR:
495 515
 				javaWriter.iShr();
496 516
 				break;
517
+			case BYTE_SHR:
518
+			case SBYTE_USHR:
519
+			case USHORT_SHR:
520
+			case SHORT_USHR:
497 521
 			case INT_USHR:
498 522
 			case UINT_SHR:
499 523
 			case USIZE_SHR:

+ 8
- 0
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaNativeTranslator.java View File

@@ -27,4 +27,12 @@ public interface JavaNativeTranslator<T> {
27 27
 	T copy(Expression value);
28 28
 	
29 29
 	T copyTo(CallExpression call);
30
+	
31
+	T stringToAscii(Expression value);
32
+	
33
+	T stringToUTF8(Expression value);
34
+	
35
+	T bytesAsciiToString(Expression value);
36
+	
37
+	T bytesUTF8ToString(Expression value);
30 38
 }

+ 18
- 1
JavaShared/src/main/java/org/openzen/zenscript/javashared/prepare/JavaPrepareDefinitionVisitor.java View File

@@ -21,6 +21,7 @@ import org.openzen.zenscript.codemodel.definition.InterfaceDefinition;
21 21
 import org.openzen.zenscript.codemodel.definition.StructDefinition;
22 22
 import org.openzen.zenscript.codemodel.definition.VariantDefinition;
23 23
 import org.openzen.zenscript.codemodel.expression.CallExpression;
24
+import org.openzen.zenscript.codemodel.expression.CallStaticExpression;
24 25
 import org.openzen.zenscript.codemodel.expression.CastExpression;
25 26
 import org.openzen.zenscript.codemodel.expression.Expression;
26 27
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
@@ -127,11 +128,27 @@ public class JavaPrepareDefinitionVisitor implements DefinitionVisitor<JavaClass
127 128
 			cls.addInstanceMethod("lastIndexOf", "lastIndexOf", "(I)I");
128 129
 			cls.addInstanceMethod("lastIndexOfFrom", "lastIndexOf", "(II)I");
129 130
 			cls.addInstanceMethod("trim", "trim", "()Ljava/lang/String;");
131
+			cls.addMethod("fromAsciiBytes", new JavaMethod((expression, translator) -> {
132
+				CallStaticExpression call = (CallStaticExpression)expression;
133
+				return translator.bytesAsciiToString(call.arguments.arguments[0]);
134
+			}));
135
+			cls.addMethod("fromUTF8Bytes", new JavaMethod((expression, translator) -> {
136
+				CallStaticExpression call = (CallStaticExpression)expression;
137
+				return translator.bytesUTF8ToString(call.arguments.arguments[0]);
138
+			}));
139
+			cls.addMethod("toAsciiBytes", new JavaMethod((expression, translator) -> {
140
+				CallExpression call = (CallExpression)expression;
141
+				return translator.stringToAscii(call.target);
142
+			}));
143
+			cls.addMethod("toUTF8Bytes", new JavaMethod((expression, translator) -> {
144
+				CallExpression call = (CallExpression)expression;
145
+				return translator.stringToUTF8(call.target);
146
+			}));
130 147
 			nativeClasses.put("stdlib::String", cls);
131 148
 		}
132 149
 		
133 150
 		{
134
-			JavaClass arrays = new JavaClass("java.lang", "Arrays", JavaClass.Kind.CLASS);
151
+			JavaClass arrays = JavaClass.ARRAYS;
135 152
 			JavaNativeClass cls = new JavaNativeClass(arrays);
136 153
 			cls.addMethod("sort", JavaMethod.getNativeExpansion(arrays, "sort", "([Ljava/lang/Object;)[Ljava/lang/Object;"));
137 154
 			cls.addMethod("sorted", new JavaMethod((expression, translator) -> {

+ 126
- 32
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceExpressionFormatter.java View File

@@ -108,6 +108,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
108 108
 	private static final JavaClass RESULT = new JavaClass("stdlib", "Result", JavaClass.Kind.CLASS);
109 109
 	private static final JavaClass RESULT_OK = new JavaClass("stdlib", "Result.Ok", JavaClass.Kind.CLASS);
110 110
 	private static final JavaClass RESULT_ERROR = new JavaClass("stdlib", "Result.Error", JavaClass.Kind.CLASS);
111
+	private static final JavaClass STANDARD_CHARSETS = new JavaClass("java.nio.charset", "StandardCharsets", JavaClass.Kind.CLASS);
111 112
 	
112 113
 	public final JavaSourceStatementScope scope;
113 114
 	public final StatementFormattingTarget target;
@@ -205,6 +206,9 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
205 206
 		if (method == null)
206 207
 			throw new IllegalStateException("No source method tag for " + expression.member.getCanonicalName() + "!");
207 208
 		
209
+		if (method.kind == JavaMethod.Kind.COMPILED)
210
+			return (ExpressionString) method.translation.translate(expression, this);
211
+		
208 212
 		StringBuilder result = new StringBuilder();
209 213
 		result.append(scope.type(method.cls));
210 214
 		result.append('.');
@@ -327,7 +331,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
327 331
 
328 332
 	@Override
329 333
 	public ExpressionString visitConstantLong(ConstantLongExpression expression) {
330
-		return new ExpressionString(Long.toString(expression.value), JavaOperator.PRIMARY);
334
+		return new ExpressionString(Long.toString(expression.value) + "L", JavaOperator.PRIMARY);
331 335
 	}
332 336
 
333 337
 	@Override
@@ -354,7 +358,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
354 358
 
355 359
 	@Override
356 360
 	public ExpressionString visitConstantULong(ConstantULongExpression expression) {
357
-		return new ExpressionString(Long.toString(expression.value), JavaOperator.CAST);
361
+		return new ExpressionString(Long.toString(expression.value) + "L", JavaOperator.CAST);
358 362
 	}
359 363
 
360 364
 	@Override
@@ -745,6 +749,14 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
745 749
 			GenericTypeID generic = (GenericTypeID)elementType;
746 750
 			String array = scope.type(new JavaClass("java.lang.reflect", "Array", JavaClass.Kind.CLASS));
747 751
 			return new ExpressionString("(" + generic.parameter.name + "[])(" + array + ".newInstance(typeOf" + generic.parameter.name + ", " + length.value + "))", JavaOperator.CAST);
752
+		} else if (elementType == BasicTypeID.BYTE) {
753
+			return new ExpressionString("new byte[" + length.value + "]", JavaOperator.NEW);
754
+		} else if (elementType == BasicTypeID.USHORT) {
755
+			return new ExpressionString("new short[" + length.value + "]", JavaOperator.NEW);
756
+		} else if (elementType == BasicTypeID.UINT) {
757
+			return new ExpressionString("new int[" + length.value + "]", JavaOperator.NEW);
758
+		} else if (elementType == BasicTypeID.ULONG) {
759
+			return new ExpressionString("new long[" + length.value + "]", JavaOperator.NEW);
748 760
 		} else {
749 761
 			return new ExpressionString("new " + scope.type(elementType) + "[" + length.value + "]", JavaOperator.NEW);
750 762
 		}
@@ -874,6 +886,18 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
874 886
 		return new ExpressionString(output.toString(), JavaOperator.CALL);
875 887
 	}
876 888
 	
889
+	public ExpressionString callAsStaticTruncated(String target, CallExpression expression, JavaOperator truncator) {
890
+		StringBuilder output = new StringBuilder();
891
+		output.append(target).append("(");
892
+		output.append(expression.target.accept(this).value);
893
+		for (Expression argument : expression.arguments.arguments) {
894
+			output.append(", ");
895
+			output.append(argument.accept(this).unaryPostfix(truncator).value);
896
+		}
897
+		output.append(")");
898
+		return new ExpressionString(output.toString(), JavaOperator.CALL);
899
+	}
900
+	
877 901
 	public ExpressionString callAsStatic(String target, Expression left, Expression right) {
878 902
 		StringBuilder output = new StringBuilder();
879 903
 		output.append(target).append("(");
@@ -897,21 +921,11 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
897 921
 	}
898 922
 	
899 923
 	private ExpressionString cast(CastExpression cast, String type) {
900
-		StringBuilder output = new StringBuilder();
901
-		output.append('(');
902
-		output.append(type);
903
-		output.append(')');
904
-		output.append(cast.target.accept(this).value);
905
-		return new ExpressionString(output.toString(), JavaOperator.CAST);
924
+		return cast.target.accept(this).unaryPrefix(JavaOperator.CAST, "(" + type + ")");
906 925
 	}
907 926
 	
908 927
 	private ExpressionString cast(ExpressionString value, String type) {
909
-		StringBuilder output = new StringBuilder();
910
-		output.append('(');
911
-		output.append(type);
912
-		output.append(')');
913
-		output.append(value.value);
914
-		return new ExpressionString(output.toString(), JavaOperator.CAST);
928
+		return value.unaryPrefix(JavaOperator.CALL, "(" + type + ")");
915 929
 	}
916 930
 	
917 931
 	private ExpressionString castPostfix(CastExpression cast, JavaOperator operator) {
@@ -954,11 +968,13 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
954 968
 			case BYTE_ADD_BYTE: return binary(call, JavaOperator.ADD);
955 969
 			case BYTE_SUB_BYTE: return binary(call, JavaOperator.SUB);
956 970
 			case BYTE_MUL_BYTE: return binary(call, JavaOperator.MUL);
957
-			case BYTE_DIV_BYTE: return callAsStatic("Integer.divideUnsigned", call);
958
-			case BYTE_MOD_BYTE: return callAsStatic("Integer.remainderUnsigned", call);
971
+			case BYTE_DIV_BYTE: return callAsStaticTruncated("Integer.divideUnsigned", call, JavaOperator.AND_FF);
972
+			case BYTE_MOD_BYTE: return callAsStaticTruncated("Integer.remainderUnsigned", call, JavaOperator.AND_FF);
959 973
 			case BYTE_AND_BYTE: return binary(call, JavaOperator.AND);
960 974
 			case BYTE_OR_BYTE: return binary(call, JavaOperator.OR);
961 975
 			case BYTE_XOR_BYTE: return binary(call, JavaOperator.XOR);
976
+			case BYTE_SHL: return binary(call, JavaOperator.SHL);
977
+			case BYTE_SHR: return binary(call, JavaOperator.SHR);
962 978
 			case SBYTE_NOT: return unaryPrefix(call, JavaOperator.INVERT);
963 979
 			case SBYTE_NEG: return unaryPrefix(call, JavaOperator.NEG);
964 980
 			case SBYTE_ADD_SBYTE: return binary(call, JavaOperator.ADD);
@@ -969,6 +985,9 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
969 985
 			case SBYTE_AND_SBYTE: return binary(call, JavaOperator.AND);
970 986
 			case SBYTE_OR_SBYTE: return binary(call, JavaOperator.OR);
971 987
 			case SBYTE_XOR_SBYTE: return binary(call, JavaOperator.XOR);
988
+			case SBYTE_SHL: return binary(call, JavaOperator.SHL);
989
+			case SBYTE_SHR: return binary(call, JavaOperator.SHR);
990
+			case SBYTE_USHR: return binary(call, JavaOperator.USHR);
972 991
 			case SHORT_NOT: return unaryPrefix(call, JavaOperator.INVERT);
973 992
 			case SHORT_NEG: return unaryPrefix(call, JavaOperator.NEG);
974 993
 			case SHORT_ADD_SHORT: return binary(call, JavaOperator.ADD);
@@ -979,15 +998,19 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
979 998
 			case SHORT_AND_SHORT: return binary(call, JavaOperator.AND);
980 999
 			case SHORT_OR_SHORT: return binary(call, JavaOperator.OR);
981 1000
 			case SHORT_XOR_SHORT: return binary(call, JavaOperator.XOR);
1001
+			case SHORT_SHL: return binary(call, JavaOperator.SHL);
1002
+			case SHORT_SHR: return binary(call, JavaOperator.SHR);
982 1003
 			case USHORT_NOT: return unaryPrefix(call, JavaOperator.INVERT);
983 1004
 			case USHORT_ADD_USHORT: return binary(call, JavaOperator.ADD);
984 1005
 			case USHORT_SUB_USHORT: return binary(call, JavaOperator.SUB);
985 1006
 			case USHORT_MUL_USHORT: return binary(call, JavaOperator.MUL);
986
-			case USHORT_DIV_USHORT: return binary(call, JavaOperator.DIV);
987
-			case USHORT_MOD_USHORT: return binary(call, JavaOperator.MOD);
1007
+			case USHORT_DIV_USHORT: return callAsStaticTruncated("Integer.divideUnsigned", call, JavaOperator.AND_FFFF);
1008
+			case USHORT_MOD_USHORT: return callAsStaticTruncated("Integer.remainderUnsigned", call, JavaOperator.AND_FFFF);
988 1009
 			case USHORT_AND_USHORT: return binary(call, JavaOperator.AND);
989 1010
 			case USHORT_OR_USHORT: return binary(call, JavaOperator.OR);
990 1011
 			case USHORT_XOR_USHORT: return binary(call, JavaOperator.XOR);
1012
+			case USHORT_SHL: return binary(call, JavaOperator.SHL);
1013
+			case USHORT_SHR: return binary(call, JavaOperator.SHR);
991 1014
 			case INT_NOT: return unaryPrefix(call, JavaOperator.INVERT);
992 1015
 			case INT_NEG: return unaryPrefix(call, JavaOperator.NEG);
993 1016
 			case INT_ADD_INT: return binary(call, JavaOperator.ADD);
@@ -1128,11 +1151,29 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1128 1151
 			case GENERICMAP_SAME: return binary(call, JavaOperator.EQUALS);
1129 1152
 			case GENERICMAP_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1130 1153
 			case ARRAY_INDEXGET: return new ExpressionString(call.target.accept(this) + "[" + call.arguments.arguments[0].accept(this) + "]", JavaOperator.INDEX);
1131
-			case ARRAY_INDEXSET: return new ExpressionString(
1154
+			case ARRAY_INDEXSET: {
1155
+				ExpressionString value = call.arguments.arguments[1].accept(this);
1156
+				ITypeID baseType = ((ArrayTypeID)(call.target.type)).elementType;
1157
+				String asType = "";
1158
+				if (baseType == BasicTypeID.BYTE) {
1159
+					asType = "(byte)";
1160
+				} else if (baseType == BasicTypeID.USHORT) {
1161
+					asType = "(short)";
1162
+				}
1163
+				
1164
+				if (!asType.isEmpty()) {
1165
+					if (value.priority == JavaOperator.CAST && value.value.startsWith("(int)"))
1166
+						value = new ExpressionString(asType + value.value.substring(5), value.priority);
1167
+					else
1168
+						value = value.unaryPrefix(JavaOperator.CAST, asType);
1169
+				}
1170
+				
1171
+				return new ExpressionString(
1132 1172
 					call.target.accept(this)
1133 1173
 							+ "[" + call.arguments.arguments[0].accept(this)
1134 1174
 							+ "] = "
1135
-							+ call.arguments.arguments[1].accept(this), JavaOperator.INDEX);
1175
+							+ value.value, JavaOperator.INDEX);
1176
+			}
1136 1177
 			case ARRAY_INDEXGETRANGE: {
1137 1178
 				ExpressionString left = call.target.accept(this);
1138 1179
 				Expression argument = call.arguments.arguments[0];
@@ -1140,7 +1181,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1140 1181
 					RangeExpression rangeArgument = (RangeExpression)argument;
1141 1182
 					ExpressionString from = rangeArgument.from.accept(this);
1142 1183
 					ExpressionString to = rangeArgument.to.accept(this);
1143
-					return new ExpressionString("Arrays.copyOfRange(" + left.value + ", " + from.value + ", " + to.value + ")", JavaOperator.CALL);
1184
+					return new ExpressionString(scope.type(JavaClass.ARRAYS) + ".copyOfRange(" + left.value + ", " + from.value + ", " + to.value + ")", JavaOperator.CALL);
1144 1185
 				} else {
1145 1186
 					throw new UnsupportedOperationException("Not yet supported!");
1146 1187
 				}
@@ -1149,8 +1190,8 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1149 1190
 				JavaMethod method = scope.fileScope.helperGenerator.createArrayContains((ArrayTypeID)call.target.type);
1150 1191
 				return callAsStatic(scope.fileScope.importer.importType(method.cls) + '.' + method.name, call);
1151 1192
 			}
1152
-			case ARRAY_EQUALS: return callAsStatic("Arrays.equals", call);
1153
-			case ARRAY_NOTEQUALS: return callAsStatic("!Arrays.equals", call);
1193
+			case ARRAY_EQUALS: return callAsStatic(scope.type(JavaClass.ARRAYS) + ".equals", call);
1194
+			case ARRAY_NOTEQUALS: return callAsStatic("!" + scope.type(JavaClass.ARRAYS) + ".equals", call);
1154 1195
 			case ARRAY_SAME: return binary(call, JavaOperator.EQUALS);
1155 1196
 			case ARRAY_NOTSAME: return binary(call, JavaOperator.NOTEQUALS);
1156 1197
 			case FUNCTION_CALL: {
@@ -1231,9 +1272,15 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1231 1272
 			case INT_COMPARE:
1232 1273
 			case USIZE_COMPARE:
1233 1274
 				return compare(call.left, call.right, call.comparison);
1234
-			case UINT_COMPARE: return compare(callAsStatic("Integer.compareUnsigned", call.left, call.right), call.comparison);
1235
-			case LONG_COMPARE: return compare(call.left, call.right, call.comparison);
1236
-			case ULONG_COMPARE: return compare(callAsStatic("Long.compareUnsigned", call.left, call.right), call.comparison);
1275
+			case UINT_COMPARE:
1276
+			case USIZE_COMPARE_UINT:
1277
+				return compare(callAsStatic("Integer.compareUnsigned", call.left, call.right), call.comparison);
1278
+			case LONG_COMPARE:
1279
+			case LONG_COMPARE_INT:
1280
+				return compare(call.left, call.right, call.comparison);
1281
+			case ULONG_COMPARE:
1282
+			case ULONG_COMPARE_UINT:
1283
+				return compare(callAsStatic("Long.compareUnsigned", call.left, call.right), call.comparison);
1237 1284
 			case FLOAT_COMPARE: return compare(call.left, call.right, call.comparison);
1238 1285
 			case DOUBLE_COMPARE: return compare(call.left, call.right, call.comparison);
1239 1286
 			case CHAR_COMPARE: return compare(call.left, call.right, call.comparison);
@@ -1323,7 +1370,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1323 1370
 			case ARRAY_LENGTH:
1324 1371
 				return call.target.accept(this).unaryPostfix(JavaOperator.MEMBER, ".length");
1325 1372
 			case ARRAY_HASHCODE:
1326
-				return callAsStatic("Arrays.deepHashCode", call);
1373
+				return callAsStatic(scope.type(JavaClass.ARRAYS) + ".deepHashCode", call);
1327 1374
 			case ARRAY_ISEMPTY:
1328 1375
 				return call.target.accept(this).unaryPostfix(JavaOperator.EQUALS, ".length == 0");
1329 1376
 			case ENUM_NAME:
@@ -1474,6 +1521,16 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1474 1521
 			case ULONG_TO_DOUBLE: return castImplicit(cast, "double"); // TODO: this is incorrect!
1475 1522
 			case ULONG_TO_CHAR: return cast(cast, "char");
1476 1523
 			case ULONG_TO_STRING: return callStatic("Long.toUnsignedString", cast.target);
1524
+			case USIZE_TO_BYTE: return cast.target.accept(this);
1525
+			case USIZE_TO_SBYTE: return cast(cast, "byte");
1526
+			case USIZE_TO_SHORT: return cast(cast, "short");
1527
+			case USIZE_TO_USHORT: return cast.target.accept(this);
1528
+			case USIZE_TO_INT: return cast.target.accept(this);
1529
+			case USIZE_TO_UINT: return cast.target.accept(this);
1530
+			case USIZE_TO_LONG: return castImplicit(cast, "long");
1531
+			case USIZE_TO_ULONG: return castImplicit(cast, "long");
1532
+			case USIZE_TO_FLOAT: return castImplicit(cast, "float");
1533
+			case USIZE_TO_DOUBLE: return castImplicit(cast, "double");
1477 1534
 			case FLOAT_TO_BYTE: return cast(cast, "int");
1478 1535
 			case FLOAT_TO_SBYTE: return cast(cast, "byte");
1479 1536
 			case FLOAT_TO_SHORT: return cast(cast, "short");
@@ -1507,6 +1564,15 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1507 1564
 			case CHAR_TO_USIZE: return castImplicit(cast, "int");
1508 1565
 			case CHAR_TO_STRING: return callStatic("Character.toString", cast.target);
1509 1566
 			case ENUM_TO_STRING: return cast.target.accept(this).unaryPostfix(JavaOperator.TOSTRING);
1567
+			case BYTE_ARRAY_AS_SBYTE_ARRAY:
1568
+			case SBYTE_ARRAY_AS_BYTE_ARRAY:
1569
+			case SHORT_ARRAY_AS_USHORT_ARRAY:
1570
+			case USHORT_ARRAY_AS_SHORT_ARRAY:
1571
+			case INT_ARRAY_AS_UINT_ARRAY:
1572
+			case UINT_ARRAY_AS_INT_ARRAY:
1573
+			case LONG_ARRAY_AS_ULONG_ARRAY:
1574
+			case ULONG_ARRAY_AS_LONG_ARRAY:
1575
+				return cast.target.accept(this);
1510 1576
 		}
1511 1577
 		
1512 1578
 		throw new UnsupportedOperationException("Unknown builtin cast: " + cast.member.member.builtin);
@@ -1843,9 +1909,9 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1843 1909
 	public ExpressionString sorted(Expression value) {
1844 1910
 		Expression target = duplicable(value);
1845 1911
 		ExpressionString targetString = target.accept(this);
1846
-		ExpressionString copy = new ExpressionString("Arrays.copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
1912
+		ExpressionString copy = new ExpressionString(scope.type(JavaClass.ARRAYS) + ".copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
1847 1913
 		ExpressionString source = hoist(copy, scope.type(target.type));
1848
-		this.target.writeLine("Arrays.sort(" + source.value + ");");
1914
+		this.target.writeLine(scope.type(JavaClass.ARRAYS) + ".sort(" + source.value + ");");
1849 1915
 		return source;
1850 1916
 	}
1851 1917
 
@@ -1854,9 +1920,9 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1854 1920
 		Expression target = duplicable(value);
1855 1921
 		ExpressionString comparatorString = comparator.accept(this);
1856 1922
 		ExpressionString targetString = target.accept(this);
1857
-		ExpressionString copy = new ExpressionString("Arrays.copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
1923
+		ExpressionString copy = new ExpressionString(scope.type(JavaClass.ARRAYS) + ".copyOf(" + targetString.value + ", " + targetString.value + ".length).sort()", JavaOperator.CALL);
1858 1924
 		ExpressionString source = hoist(copy, scope.type(target.type));
1859
-		this.target.writeLine("Arrays.sort(" + source.value + ", " + comparatorString.value + ");");
1925
+		this.target.writeLine(scope.type(JavaClass.ARRAYS) + ".sort(" + source.value + ", " + comparatorString.value + ");");
1860 1926
 		return source;
1861 1927
 	}
1862 1928
 
@@ -1864,7 +1930,7 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1864 1930
 	public ExpressionString copy(Expression value) {
1865 1931
 		Expression target = duplicable(value);
1866 1932
 		ExpressionString source = target.accept(this);
1867
-		return new ExpressionString("Arrays.copyOf(" + source.value + ", " + source.value + ".length)", JavaOperator.CALL);
1933
+		return new ExpressionString(scope.type(JavaClass.ARRAYS) + ".copyOf(" + source.value + ", " + source.value + ".length)", JavaOperator.CALL);
1868 1934
 	}
1869 1935
 
1870 1936
 	@Override
@@ -1881,4 +1947,32 @@ public class JavaSourceExpressionFormatter implements ExpressionVisitor<Expressi
1881 1947
 			+ targetOffset.accept(this) + ", "
1882 1948
 			+ length.accept(this) + ")", JavaOperator.CALL);
1883 1949
 	}
1950
+
1951
+	@Override
1952
+	public ExpressionString stringToAscii(Expression value) {
1953
+		String standardCharsets = scope.type(STANDARD_CHARSETS);
1954
+		return value.accept(this).unaryPostfix(JavaOperator.CALL, ".getBytes(" + standardCharsets + ".US_ASCII)");
1955
+	}
1956
+
1957
+	@Override
1958
+	public ExpressionString stringToUTF8(Expression value) {
1959
+		String standardCharsets = scope.type(STANDARD_CHARSETS);
1960
+		return value.accept(this).unaryPostfix(JavaOperator.CALL, ".getBytes(" + standardCharsets + ".UTF_8)");
1961
+	}
1962
+
1963
+	@Override
1964
+	public ExpressionString bytesAsciiToString(Expression value) {
1965
+		String standardCharsets = scope.type(STANDARD_CHARSETS);
1966
+		return new ExpressionString(
1967
+				"new String(" + value.accept(this).value + ", " + standardCharsets + ".US_ASCII)",
1968
+				JavaOperator.NEW);
1969
+	}
1970
+
1971
+	@Override
1972
+	public ExpressionString bytesUTF8ToString(Expression value) {
1973
+		String standardCharsets = scope.type(STANDARD_CHARSETS);
1974
+		return new ExpressionString(
1975
+				"new String(" + value.accept(this).value + ", " + standardCharsets + ".UTF_8)",
1976
+				JavaOperator.NEW);
1977
+	}
1884 1978
 }

+ 4
- 1
JavaSourceCompiler/src/main/java/org/openzen/zenscript/javasource/JavaSourceImporter.java View File

@@ -35,7 +35,10 @@ public class JavaSourceImporter {
35 35
 	}
36 36
 	
37 37
 	public String importType(JavaClass cls) {
38
-		if (imports.containsKey(cls.outer.getName())) {
38
+		if (cls == null)
39
+			throw new NullPointerException();
40
+		
41
+		if (cls.outer != null && imports.containsKey(cls.outer.getName())) {
39 42
 			JavaClass imported = imports.get(cls.outer.getName());
40 43
 			usedImports.add(imported);
41 44
 			return imported.fullName.equals(cls.outer.fullName) ? cls.getName() : cls.fullName;

+ 3
- 2
Parser/src/main/java/org/openzen/zenscript/lexer/ZSTokenType.java View File

@@ -19,8 +19,9 @@ public enum ZSTokenType implements TokenType {
19 19
 	T_WHITESPACE_CARRIAGE_RETURN(true, "\r", "\r"),
20 20
 	T_IDENTIFIER("@?[a-zA-Z_][a-zA-Z_0-9]*"),
21 21
 	T_LOCAL_IDENTIFIER("$[a-zA-Z_][a-zA-Z_0-9]*"),
22
-	T_FLOAT("\\-?(0|[1-9][0-9]*)\\.[0-9]+([eE][\\+\\-]?[0-9]+)?"),
23
-	T_INT("\\-?(0|[1-9][0-9]*)"),
22
+	T_FLOAT("\\-?(0|[1-9][0-9]*)\\.[0-9]+([eE][\\+\\-]?[0-9]+)?[a-zA-Z_]"),
23
+	T_INT("\\-?(0|[1-9][0-9_]*)[a-zA-Z_]*"),
24
+	T_PREFIXED_INT("\\-?(0b|0x|0o|0B|0X|0O)(0|[1-9a-fA-F][0-9a-fA-F_]*)(u|U|l|L|ul|UL)?"),
24 25
 	T_STRING_SQ("\"([^\"\\\\\\n]|\\\\([\'\"\\\\/bfnrt&]|u[0-9a-fA-F]{4}))*\""),
25 26
 	T_STRING_DQ("\'([^\'\\\\\\n]|\\\\([\'\"\\\\/bfnrt&]|u[0-9a-fA-F]{4}))*\'"),
26 27
 	T_AOPEN("\\{", "{"),

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpression.java View File

@@ -426,17 +426,18 @@ public abstract class ParsedExpression {
426 426
 	private static ParsedExpression readPrimaryExpression(CodePosition position, ZSTokenParser parser, ParsingOptions options) {
427 427
 		switch (parser.peek().getType()) {
428 428
 			case T_INT:
429
-				return new ParsedExpressionInt(position, Long.parseLong(parser.next().content));
429
+				return new ParsedExpressionInt(position, parser.next().content);
430
+			case T_PREFIXED_INT:
431
+				return ParsedExpressionInt.parsePrefixed(position, parser.next().content);
430 432
 			case T_FLOAT:
431 433
 				return new ParsedExpressionFloat(
432 434
 						position,
433
-						Double.parseDouble(parser.next().content));
435
+						parser.next().content);
434 436
 			case T_STRING_SQ:
435 437
 			case T_STRING_DQ:
436 438
 				return new ParsedExpressionString(
437 439
 						position,
438 440
 						StringExpansion.unescape(parser.next().content).orElse(error -> {
439
-							
440 441
 							return "INVALID_STRING";
441 442
 						}));
442 443
 			case T_IDENTIFIER: {

+ 53
- 14
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionFloat.java View File

@@ -5,16 +5,19 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.expression;
7 7
 
8
+import java.util.Collections;
8 9
 import org.openzen.zencode.shared.CodePosition;
9 10
 import org.openzen.zencode.shared.CompileException;
10 11
 import org.openzen.zencode.shared.CompileExceptionCode;
12
+import org.openzen.zenscript.codemodel.expression.CallArguments;
11 13
 import org.openzen.zenscript.codemodel.expression.ConstantDoubleExpression;
12 14
 import org.openzen.zenscript.codemodel.expression.ConstantFloatExpression;
15
+import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
13 16
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
14 17
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
15 18
 import org.openzen.zenscript.codemodel.type.ITypeID;
16 19
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
17
-import org.openzen.zenscript.parser.PrecompilationState;
20
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
18 21
 
19 22
 /**
20 23
  *
@@ -22,11 +25,24 @@ import org.openzen.zenscript.parser.PrecompilationState;
22 25
  */
23 26
 public class ParsedExpressionFloat extends ParsedExpression {
24 27
 	public final double value;
28
+	public final String suffix;
25 29
 	
26
-	public ParsedExpressionFloat(CodePosition position, double value) {
30
+	public ParsedExpressionFloat(CodePosition position, String value) {
31
+		super(position);
32
+		
33
+		int split = value.length();
34
+		while (isLetter(value.charAt(split - 1)))
35
+			split--;
36
+		
37
+		this.value = Long.parseLong(value.substring(0, split));
38
+		suffix = value.substring(split);
39
+	}
40
+	
41
+	private ParsedExpressionFloat(CodePosition position, double value) {
27 42
 		super(position);
28 43
 		
29 44
 		this.value = value;
45
+		this.suffix = "";
30 46
 	}
31 47
 
32 48
 	@Override
@@ -34,26 +50,49 @@ public class ParsedExpressionFloat extends ParsedExpression {
34 50
 		if (scope.hints.isEmpty())
35 51
 			return new ConstantDoubleExpression(position, value);
36 52
 		
53
+		if (suffix.equals("f") || suffix.equals("F"))
54
+			return new ConstantFloatExpression(position, (float)value);
55
+		if (suffix.equals("d") || suffix.equals("D"))
56
+			return new ConstantDoubleExpression(position, value);
57
+		
37 58
 		for (ITypeID hint : scope.hints) {
38
-			if (hint == BasicTypeID.DOUBLE)
39
-				return new ConstantDoubleExpression(position, value);
40
-			else if (hint == BasicTypeID.FLOAT)
41
-				return new ConstantFloatExpression(position, (float) value);
59
+			if (suffix.isEmpty()) {
60
+				if (hint == BasicTypeID.DOUBLE)
61
+					return new ConstantDoubleExpression(position, value);
62
+				else if (hint == BasicTypeID.FLOAT)
63
+					return new ConstantFloatExpression(position, (float) value);
64
+			} else {
65
+				TypeMembers members = scope.getTypeMembers(hint);
66
+				FunctionalMemberRef method = members.getOrCreateGroup(suffix, true).getStaticMethod(1, hint);
67
+				if (method != null) {
68
+					ParsedCallArguments parsedArguments = new ParsedCallArguments(Collections.emptyList(), Collections.singletonList(new ParsedExpressionFloat(position, value)));
69
+					CallArguments arguments = parsedArguments.compileCall(position, scope, ITypeID.NONE, method.getHeader());
70
+					method.callStatic(position, hint, method.getHeader(), arguments, scope);
71
+				}
72
+			}
42 73
 		}
43 74
 		
44
-		StringBuilder types = new StringBuilder();
45
-		for (int i = 0; i < scope.hints.size(); i++) {
46
-			if (i > 0)
47
-				types.append(", ");
48
-			
49
-			types.append(scope.hints.get(i).toString());
75
+		if (suffix.isEmpty()) {
76
+			StringBuilder types = new StringBuilder();
77
+			for (int i = 0; i < scope.hints.size(); i++) {
78
+				if (i > 0)
79
+					types.append(", ");
80
+
81
+				types.append(scope.hints.get(i).toString());
82
+			}
83
+
84
+			throw new CompileException(position, CompileExceptionCode.INVALID_CAST, "Cannot cast a floating-point value to any of these types: " + types);
85
+		} else {
86
+			throw new CompileException(position, CompileExceptionCode.INVALID_SUFFIX, "Invalid suffix: " + suffix);
50 87
 		}
51
-		
52
-		throw new CompileException(position, CompileExceptionCode.INVALID_CAST, "Cannot cast a floating-point value to any of these types: " + types);
53 88
 	}
54 89
 
55 90
 	@Override
56 91
 	public boolean hasStrongType() {
57 92
 		return false;
58 93
 	}
94
+	
95
+	private static boolean isLetter(char c) {
96
+		return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
97
+	}
59 98
 }

+ 119
- 10
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionInt.java View File

@@ -5,9 +5,11 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.expression;
7 7
 
8
+import java.util.Collections;
8 9
 import org.openzen.zencode.shared.CodePosition;
9 10
 import org.openzen.zencode.shared.CompileException;
10 11
 import org.openzen.zencode.shared.CompileExceptionCode;
12
+import org.openzen.zenscript.codemodel.expression.CallArguments;
11 13
 import org.openzen.zenscript.codemodel.expression.ConstantByteExpression;
12 14
 import org.openzen.zenscript.codemodel.expression.ConstantCharExpression;
13 15
 import org.openzen.zenscript.codemodel.expression.ConstantIntExpression;
@@ -21,58 +23,161 @@ import org.openzen.zenscript.codemodel.expression.ConstantUSizeExpression;
21 23
 import org.openzen.zenscript.codemodel.expression.Expression;
22 24
 import org.openzen.zenscript.codemodel.expression.switchvalue.IntSwitchValue;
23 25
 import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
26
+import org.openzen.zenscript.codemodel.member.ref.FunctionalMemberRef;
24 27
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
25 28
 import org.openzen.zenscript.codemodel.type.ITypeID;
26 29
 import org.openzen.zenscript.codemodel.scope.ExpressionScope;
27
-import org.openzen.zenscript.parser.PrecompilationState;
30
+import org.openzen.zenscript.codemodel.type.member.TypeMembers;
28 31
 
29 32
 /**
30 33
  *
31 34
  * @author Hoofdgebruiker
32 35
  */
33 36
 public class ParsedExpressionInt extends ParsedExpression {
37
+	public static ParsedExpressionInt parsePrefixed(CodePosition position, String value) {
38
+		boolean negative = value.startsWith("-");
39
+		if (negative)
40
+			value = value.substring(1);
41
+		
42
+		String suffix = "";
43
+		if (value.endsWith("u") || value.endsWith("l") || value.endsWith("U") || value.endsWith("L")) {
44
+			suffix = value.substring(value.length() - 1);
45
+			value = value.substring(0, value.length() - 1);
46
+		} else if (value.endsWith("ul") || value.endsWith("UL")) {
47
+			suffix = value.substring(value.length() - 2);
48
+			value = value.substring(0, value.length() - 2);
49
+		}
50
+		
51
+		value = value.toLowerCase();
52
+		
53
+		long parsed = 0;
54
+		if (value.startsWith("0x")) {
55
+			for (char c : value.substring(2).toCharArray()) {
56
+				if (c >= '0' && c <= '9')
57
+					parsed = parsed * 16 + (c - '0');
58
+				else if (c >= 'a' && c <= 'f')
59
+					parsed = parsed * 16 + 10 + (c - 'a');
60
+				else if (c != '_')
61
+					throw new NumberFormatException("Invalid number: " + value);
62
+			}
63
+		} else if (value.startsWith("0b")) {
64
+			for (char c : value.substring(2).toCharArray()) {
65
+				if (c == '0')
66
+					parsed = parsed * 2;
67
+				else if (c == '1')
68
+					parsed = parsed * 2 + 1;
69
+				else if (c != '_')
70
+					throw new NumberFormatException("Invalid number: " + value);
71
+			}
72
+		} else if (value.startsWith("0o")) {
73
+			for (char c : value.substring(2).toCharArray()) {
74
+				if (c >= '0' && c <= '7')
75
+					parsed = parsed * 8 + c - '0';
76
+				else if (c != '_')
77
+					throw new NumberFormatException("Invalid number: " + value);
78
+			}
79
+		} else {
80
+			throw new NumberFormatException("Invalid number: " + value);
81
+		}
82
+		
83
+		return new ParsedExpressionInt(position, negative, negative ? -parsed : parsed, suffix);
84
+	}
85
+	
86
+	public final boolean negative;
34 87
 	public final long value;
88
+	public final String suffix;
35 89
 	
36
-	public ParsedExpressionInt(CodePosition position, long value) {
90
+	public ParsedExpressionInt(CodePosition position, String value) {
37 91
 		super(position);
38 92
 		
93
+		int split = value.length();
94
+		while (isLetter(value.charAt(split - 1)))
95
+			split--;
96
+		
97
+		negative = value.charAt(0) == '-';
98
+		this.value = Long.parseLong(value.substring(0, split));
99
+		suffix = value.substring(split);
100
+	}
101
+	
102
+	private ParsedExpressionInt(CodePosition position, boolean negative, long value, String suffix) {
103
+		super(position);
104
+		
105
+		this.negative = negative;
39 106
 		this.value = value;
107
+		this.suffix = suffix;
40 108
 	}
41
-
109
+	
42 110
 	@Override
43 111
 	public Expression compile(ExpressionScope scope) {
112
+		if (suffix.equals("L") || suffix.equals("l"))
113
+			return new ConstantLongExpression(position, value);
114
+		if (suffix.equals("UL") || suffix.equals("ul"))
115
+			return new ConstantULongExpression(position, value);
116
+		if (suffix.equals("U") || suffix.equals("u"))
117
+			return new ConstantUIntExpression(position, (int)value);
118
+		
44 119
 		for (ITypeID hint : scope.hints) {
45
-			if (hint instanceof BasicTypeID) {
120
+			if (suffix.isEmpty() && (hint instanceof BasicTypeID)) {
46 121
 				switch ((BasicTypeID) hint) {
47 122
 					case SBYTE:
48 123
 						return new ConstantSByteExpression(position, (byte) value);
49 124
 					case BYTE:
50
-						return new ConstantByteExpression(position, (byte) value);
125
+						if (negative)
126
+							break;
127
+						
128
+						return new ConstantByteExpression(position, (int)(value & 0xFF));
51 129
 					case SHORT:
52 130
 						return new ConstantShortExpression(position, (short) value);
53 131
 					case USHORT:
54
-						return new ConstantUShortExpression(position, (short) value);
132
+						if (negative)
133
+							break;
134
+						
135
+						return new ConstantUShortExpression(position, (int)(value & 0xFFFF));
55 136
 					case INT:
56 137
 						return new ConstantIntExpression(position, (int) value);
57 138
 					case UINT:
139
+						if (negative)
140
+							break;
141
+						
58 142
 						return new ConstantUIntExpression(position, (int) value);
59 143
 					case LONG:
60 144
 						return new ConstantLongExpression(position, value);
61 145
 					case ULONG:
146
+						if (negative)
147
+							break;
148
+						
62 149
 						return new ConstantULongExpression(position, value);
63 150
 					case USIZE:
151
+						if (negative)
152
+							break;
153
+						
64 154
 						return new ConstantUSizeExpression(position, value);
65 155
 					case CHAR:
156
+						if (negative)
157
+							break;
158
+						
66 159
 						return new ConstantCharExpression(position, (char) value);
67 160
 					default:
68 161
 				}
162
+			} else if (!suffix.isEmpty()) {
163
+				TypeMembers members = scope.getTypeMembers(hint);
164
+				FunctionalMemberRef method = members.getOrCreateGroup(suffix, true).getStaticMethod(1, hint);
165
+				if (method != null) {
166
+					ParsedCallArguments parsedArguments = new ParsedCallArguments(Collections.emptyList(), Collections.singletonList(new ParsedExpressionInt(position, negative, value, "")));
167
+					CallArguments arguments = parsedArguments.compileCall(position, scope, ITypeID.NONE, method.getHeader());
168
+					method.callStatic(position, hint, method.getHeader(), arguments, scope);
169
+				}
69 170
 			}
70 171
 		}
71 172
 		
72
-		if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE)
73
-			return new ConstantIntExpression(position, (int) value);
74
-		else
75
-			return new ConstantLongExpression(position, value);
173
+		if (suffix.isEmpty()) {
174
+			if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE)
175
+				return new ConstantIntExpression(position, (int) value);
176
+			else
177
+				return new ConstantLongExpression(position, value);
178
+		} else {
179
+			throw new CompileException(position, CompileExceptionCode.INVALID_SUFFIX, "Invalid suffix: " + suffix);
180
+		}
76 181
 	}
77 182
 	
78 183
 	@Override
@@ -87,4 +192,8 @@ public class ParsedExpressionInt extends ParsedExpression {
87 192
 	public boolean hasStrongType() {
88 193
 		return false;
89 194
 	}
195
+	
196
+	private static boolean isLetter(char c) {
197
+		return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
198
+	}
90 199
 }

+ 1
- 1
ScriptingExample/build.gradle View File

@@ -18,5 +18,5 @@ dependencies {
18 18
 	compile project(':JavaBytecodeCompiler')
19 19
 	compile project(':JavaShared')
20 20
 	compile project(':CodeFormatter')
21
-	compile project(':ScriptingHost')
21
+	//compile project(':ScriptingHost')
22 22
 }

+ 2
- 1
Shared/src/main/java/org/openzen/zencode/shared/CompileExceptionCode.java View File

@@ -68,5 +68,6 @@ public enum CompileExceptionCode {
68 68
 	INVALID_BRACKET_EXPRESSION,
69 69
 	VARIANT_OPTION_NOT_AN_EXPRESSION,
70 70
 	DUPLICATE_GLOBAL,
71
-	CANNOT_INFER_RETURN_TYPE
71
+	CANNOT_INFER_RETURN_TYPE,
72
+	INVALID_SUFFIX
72 73
 }

Loading…
Cancel
Save