Browse Source

Merge remote-tracking branch 'kindlich/development' into development

Jared 5 years ago
parent
commit
791068d83e
No account linked to committer's email address

+ 2
- 2
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/ExpressionFormatter.java View File

@@ -373,12 +373,12 @@ public class ExpressionFormatter implements ExpressionVisitor<ExpressionString>
373 373
 
374 374
 	@Override
375 375
 	public ExpressionString visitConstantDouble(ConstantDoubleExpression expression) {
376
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
376
+	    return new ExpressionString(Double.toString(expression.value), ZenScriptOperator.PRIMARY);
377 377
 	}
378 378
 
379 379
 	@Override
380 380
 	public ExpressionString visitConstantFloat(ConstantFloatExpression expression) {
381
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
381
+        return new ExpressionString(Float.toString(expression.value), ZenScriptOperator.PRIMARY);
382 382
 	}
383 383
 
384 384
 	@Override

+ 5
- 0
JavaAnnotations/src/main/java/org/openzen/zencode/java/StorageTagType.java View File

@@ -0,0 +1,5 @@
1
+package org.openzen.zencode.java;
2
+
3
+public enum StorageTagType {
4
+    STATIC
5
+}

+ 11
- 0
JavaAnnotations/src/main/java/org/openzen/zencode/java/ZenCodeStorageTag.java View File

@@ -0,0 +1,11 @@
1
+package org.openzen.zencode.java;
2
+
3
+import java.lang.annotation.*;
4
+
5
+@Retention(RetentionPolicy.RUNTIME)
6
+@Target(ElementType.TYPE_USE)
7
+public @interface ZenCodeStorageTag {
8
+    
9
+    StorageTagType value();
10
+    
11
+}

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

@@ -28,7 +28,7 @@ public class CompilerUtils {
28 28
 	}
29 29
 
30 30
 	public static boolean isLarge(StoredType type) {
31
-		return type.type == BasicTypeID.DOUBLE || type.type == BasicTypeID.DOUBLE;
31
+		return type.type == BasicTypeID.DOUBLE || type.type == BasicTypeID.LONG;
32 32
 	}
33 33
 	
34 34
 	public static int calcAccess(int modifiers) {

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

@@ -60,7 +60,6 @@ public class JavaBoxingTypeVisitor implements TypeVisitorWithContext<StoredType,
60 60
 			default:
61 61
 				return null;
62 62
 		}
63
-		writer.dup();
64 63
 		
65 64
 		if (method != null)
66 65
 			writer.invokeStatic(method);

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

@@ -31,6 +31,8 @@ import java.util.Objects;
31 31
 import java.util.StringJoiner;
32 32
 
33 33
 public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativeTranslator<Void> {
34
+    private static final JavaMethod OBJECTS_TOSTRING = JavaMethod.getNativeStatic(new JavaClass("java.util", "Objects", JavaClass.Kind.CLASS), "toString", "(Ljava/lang/Object;)Ljava/lang/String;");
35
+    
34 36
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
35 37
 	private static final JavaMethod BOOLEAN_TO_STRING = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "toString", "(Z)Ljava/lang/String;");
36 38
 	private static final JavaMethod BYTE_PARSE = JavaMethod.getNativeStatic(JavaClass.BYTE, "parseByte", "(Ljava/lang/String;)B");
@@ -155,16 +157,20 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
155 157
 	private static final JavaMethod SHARED_ADDREF = JavaMethod.getNativeVirtual(JavaClass.SHARED, "addRef", "()V");
156 158
 	private static final JavaMethod SHARED_RELEASE = JavaMethod.getNativeVirtual(JavaClass.SHARED, "release", "()V");
157 159
 
158
-	protected final JavaWriter javaWriter;
159
-	private final JavaCapturedExpressionVisitor capturedExpressionVisitor = new JavaCapturedExpressionVisitor(this);
160
-	private final JavaBytecodeContext context;
161
-	private final JavaCompiledModule module;
160
+	final JavaWriter javaWriter;
161
+    private final JavaBoxingTypeVisitor boxingTypeVisitor;
162
+    private final JavaUnboxingTypeVisitor unboxingTypeVisitor;
163
+    private final JavaCapturedExpressionVisitor capturedExpressionVisitor = new JavaCapturedExpressionVisitor(this);
164
+    private final JavaBytecodeContext context;
165
+    private final JavaCompiledModule module;
162 166
 
163 167
 	public JavaExpressionVisitor(JavaBytecodeContext context, JavaCompiledModule module, JavaWriter javaWriter) {
164 168
 		this.javaWriter = javaWriter;
165 169
 		this.context = context;
166 170
 		this.module = module;
167
-	}
171
+        boxingTypeVisitor = new JavaBoxingTypeVisitor(javaWriter);
172
+        unboxingTypeVisitor = new JavaUnboxingTypeVisitor(javaWriter);
173
+    }
168 174
 
169 175
 	@Override
170 176
 	public Void visitAndAnd(AndAndExpression expression) {
@@ -1289,7 +1295,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1289 1295
 
1290 1296
 		switch (builtin) {
1291 1297
 			case BOOL_TO_STRING:
1292
-				javaWriter.invokeStatic(BOOLEAN_TO_STRING);
1298
+                if(expression.target.type.isOptional()) {
1299
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1300
+                } else {
1301
+                    javaWriter.invokeStatic(BOOLEAN_TO_STRING);
1302
+                }
1293 1303
 				break;
1294 1304
 			case BYTE_TO_SBYTE:
1295 1305
 				javaWriter.i2b();
@@ -1327,9 +1337,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1327 1337
 				javaWriter.iAnd();
1328 1338
 				break;
1329 1339
 			case BYTE_TO_STRING:
1330
-				javaWriter.constant(0xFF);
1331
-				javaWriter.iAnd();
1332
-				javaWriter.invokeStatic(INTEGER_TO_STRING);
1340
+                if(expression.target.type.isOptional()) {
1341
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1342
+                } else {
1343
+                    javaWriter.constant(0xFF);
1344
+                    javaWriter.iAnd();
1345
+                    javaWriter.invokeStatic(INTEGER_TO_STRING);
1346
+                }
1333 1347
 				break;
1334 1348
 			case SBYTE_TO_BYTE:
1335 1349
 			case SBYTE_TO_SHORT:
@@ -1351,7 +1365,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1351 1365
 			case SBYTE_TO_CHAR:
1352 1366
 				break;
1353 1367
 			case SBYTE_TO_STRING:
1354
-				javaWriter.invokeStatic(INTEGER_TO_STRING);
1368
+                if(expression.target.type.isOptional()) {
1369
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1370
+                } else {
1371
+                    javaWriter.invokeStatic(INTEGER_TO_STRING);
1372
+                }
1355 1373
 				break;
1356 1374
 			case SHORT_TO_BYTE:
1357 1375
 				break;
@@ -1376,7 +1394,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1376 1394
 			case SHORT_TO_CHAR:
1377 1395
 				break;
1378 1396
 			case SHORT_TO_STRING:
1379
-				javaWriter.invokeStatic(SHORT_TO_STRING);
1397
+                if(expression.target.type.isOptional()) {
1398
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1399
+                } else {
1400
+                    javaWriter.invokeStatic(SHORT_TO_STRING);
1401
+                }
1380 1402
 				break;
1381 1403
 			case USHORT_TO_BYTE:
1382 1404
 				break;
@@ -1412,10 +1434,14 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1412 1434
 				javaWriter.iAnd();
1413 1435
 				break;
1414 1436
 			case USHORT_TO_STRING:
1415
-				javaWriter.constant(0xFFFFL);
1416
-				javaWriter.iAnd();
1417
-				javaWriter.invokeStatic(INTEGER_TO_STRING);
1418
-				break;
1437
+                if(expression.target.type.isOptional()) {
1438
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1439
+                } else {
1440
+                    javaWriter.constant(0xFFFFL);
1441
+                    javaWriter.iAnd();
1442
+                    javaWriter.invokeStatic(INTEGER_TO_STRING);
1443
+                }
1444
+                break;
1419 1445
 			case INT_TO_BYTE:
1420 1446
 			case USIZE_TO_BYTE:
1421 1447
 				break;
@@ -1455,7 +1481,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1455 1481
 				break;
1456 1482
 			case INT_TO_STRING:
1457 1483
 			case USIZE_TO_STRING:
1458
-				javaWriter.invokeStatic(INTEGER_TO_STRING);
1484
+			    if(expression.target.type.isOptional()) {
1485
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1486
+                } else {
1487
+                    javaWriter.invokeStatic(INTEGER_TO_STRING);
1488
+                }
1459 1489
 				break;
1460 1490
 			case UINT_TO_BYTE:
1461 1491
 				break;
@@ -1493,7 +1523,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1493 1523
 				javaWriter.i2s();
1494 1524
 				break;
1495 1525
 			case UINT_TO_STRING:
1496
-				javaWriter.invokeStatic(INTEGER_TO_UNSIGNED_STRING);
1526
+                if(expression.target.type.isOptional()) {
1527
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1528
+                } else {
1529
+                    javaWriter.invokeStatic(INTEGER_TO_UNSIGNED_STRING);
1530
+                }
1497 1531
 				break;
1498 1532
 			case LONG_TO_BYTE:
1499 1533
 				javaWriter.l2i();
@@ -1525,7 +1559,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1525 1559
 				javaWriter.i2s();
1526 1560
 				break;
1527 1561
 			case LONG_TO_STRING:
1528
-				javaWriter.invokeStatic(LONG_TO_STRING);
1562
+                if(expression.target.type.isOptional()) {
1563
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1564
+                } else {
1565
+                    javaWriter.invokeStatic(LONG_TO_STRING);
1566
+                }
1529 1567
 				break;
1530 1568
 			case ULONG_TO_BYTE:
1531 1569
 				javaWriter.l2i();
@@ -1556,7 +1594,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1556 1594
 				javaWriter.i2s();
1557 1595
 				break;
1558 1596
 			case ULONG_TO_STRING:
1559
-				javaWriter.invokeStatic(LONG_TO_UNSIGNED_STRING);
1597
+                if(expression.target.type.isOptional()) {
1598
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1599
+                } else {
1600
+                    javaWriter.invokeStatic(LONG_TO_UNSIGNED_STRING);
1601
+                }
1560 1602
 				break;
1561 1603
 			case FLOAT_TO_BYTE:
1562 1604
 				javaWriter.f2i();
@@ -1583,7 +1625,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1583 1625
 				javaWriter.f2d();
1584 1626
 				break;
1585 1627
 			case FLOAT_TO_STRING:
1586
-				javaWriter.invokeStatic(FLOAT_TO_STRING);
1628
+                if(expression.target.type.isOptional()) {
1629
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1630
+                } else {
1631
+                    javaWriter.invokeStatic(FLOAT_TO_STRING);
1632
+                }
1587 1633
 				break;
1588 1634
 			case DOUBLE_TO_BYTE:
1589 1635
 				javaWriter.d2i();
@@ -1610,7 +1656,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1610 1656
 				javaWriter.d2f();
1611 1657
 				break;
1612 1658
 			case DOUBLE_TO_STRING:
1613
-				javaWriter.invokeStatic(DOUBLE_TO_STRING);
1659
+                if(expression.target.type.isOptional()) {
1660
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1661
+                } else {
1662
+                    javaWriter.invokeStatic(DOUBLE_TO_STRING);
1663
+                }
1614 1664
 				break;
1615 1665
 			case CHAR_TO_BYTE:
1616 1666
 				break;
@@ -1628,7 +1678,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1628 1678
 				javaWriter.i2l();
1629 1679
 				break;
1630 1680
 			case CHAR_TO_STRING:
1631
-				javaWriter.invokeStatic(CHARACTER_TO_STRING);
1681
+                if(expression.target.type.isOptional()) {
1682
+                    javaWriter.invokeStatic(OBJECTS_TOSTRING);
1683
+                } else {
1684
+                    javaWriter.invokeStatic(CHARACTER_TO_STRING);
1685
+                }
1632 1686
 				break;
1633 1687
 			case ENUM_TO_STRING:
1634 1688
 				javaWriter.invokeVirtual(ENUM_NAME);
@@ -1665,7 +1719,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1665 1719
 		javaWriter.ifNonNull(end);
1666 1720
 		javaWriter.pop();
1667 1721
 		expression.right.accept(this);
1722
+		expression.right.type.type.accept(expression.right.type, boxingTypeVisitor);
1668 1723
 		javaWriter.label(end);
1724
+		expression.type.type.accept(expression.type, unboxingTypeVisitor);
1669 1725
 		return null;
1670 1726
 	}
1671 1727
 
@@ -1940,7 +1996,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1940 1996
 				}
1941 1997
 			}
1942 1998
 			
1943
-			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), methodInfo.kind, methodInfo.name, methodInfo.compile, signature, methodInfo.modifiers, methodInfo.genericResult));
1999
+			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, methodInfo.name, methodInfo.compile, signature, methodInfo.modifiers, methodInfo.genericResult));
1944 2000
 			if(expression.header.getReturnType().type != BasicTypeID.VOID) {
1945 2001
 				bridgeWriter.returnType(context.getType(expression.header.getReturnType()));
1946 2002
 			}
@@ -2335,11 +2391,14 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
2335 2391
 		javaWriter.newObject("java/util/HashMap");
2336 2392
 		javaWriter.dup();
2337 2393
 		javaWriter.invokeSpecial("java/util/HashMap", "<init>", "()V");
2394
+        final AssocTypeID type = (AssocTypeID) expression.type.type;
2338 2395
 		for (int i = 0; i < expression.keys.length; i++) {
2339 2396
 			javaWriter.dup();
2340 2397
 			expression.keys[i].accept(this);
2341
-			expression.values[i].accept(this);
2342
-			javaWriter.invokeInterface(MAP_PUT);
2398
+            type.keyType.type.accept(type.keyType, boxingTypeVisitor);
2399
+            expression.values[i].accept(this);
2400
+            type.valueType.type.accept(type.valueType, boxingTypeVisitor);
2401
+            javaWriter.invokeInterface(MAP_PUT);
2343 2402
 			javaWriter.pop();
2344 2403
 		}
2345 2404
 		return null;
@@ -4142,7 +4201,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
4142 4201
 	public Void visitWrapOptional(WrapOptionalExpression expression) {
4143 4202
 		//Does nothing if not required to be wrapped
4144 4203
 		expression.value.accept(this);
4145
-		expression.value.type.type.accept(expression.value.type, new JavaBoxingTypeVisitor(javaWriter));
4204
+		expression.value.type.type.accept(expression.value.type, boxingTypeVisitor);
4146 4205
 		return null;
4147 4206
 	}
4148 4207
 

+ 39
- 14
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaForeachWriter.java View File

@@ -7,10 +7,11 @@ import org.openzen.zenscript.codemodel.statement.VarStatement;
7 7
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
8 8
 import org.openzen.zenscript.javashared.JavaClass;
9 9
 import org.openzen.zenscript.javashared.JavaMethod;
10
+import org.openzen.zenscript.javashared.JavaModifiers;
10 11
 
11 12
 import java.util.HashMap;
12 13
 import java.util.Map;
13
-
14
+@SuppressWarnings("Duplicates")
14 15
 public class JavaForeachWriter {
15 16
 
16 17
 	private final JavaWriter javaWriter;
@@ -19,6 +20,7 @@ public class JavaForeachWriter {
19 20
 	private final Label startLabel;
20 21
 	private final Label endLabel;
21 22
 	private final JavaStatementVisitor statementVisitor;
23
+	private final JavaUnboxingTypeVisitor unboxingTypeVisitor;
22 24
 
23 25
 	public JavaForeachWriter(JavaStatementVisitor statementVisitor, VarStatement[] variables, Statement content, Label start, Label end) {
24 26
 		this.statementVisitor = statementVisitor;
@@ -27,7 +29,8 @@ public class JavaForeachWriter {
27 29
 		this.content = content;
28 30
 		this.startLabel = start;
29 31
 		this.endLabel = end;
30
-	}
32
+        this.unboxingTypeVisitor = new JavaUnboxingTypeVisitor(this.javaWriter);
33
+    }
31 34
 
32 35
 	public void visitIntRange() {
33 36
 		javaWriter.dup();
@@ -55,8 +58,7 @@ public class JavaForeachWriter {
55 58
 	}
56 59
 
57 60
 	public void visitStringCharacterIterator() {
58
-		//TODO UNTESTED!
59
-		javaWriter.invokeSpecial("java/lang/String", "toCharArray()", "()[C");
61
+        javaWriter.invokeVirtual(JavaMethod.getVirtual(JavaClass.STRING, "toCharArray", "()[C", JavaModifiers.PUBLIC));
60 62
 		handleArray(javaWriter.local(int.class), javaWriter.getLocalVariable(variables[0].variable));
61 63
 	}
62 64
 
@@ -66,12 +68,12 @@ public class JavaForeachWriter {
66 68
 
67 69
 		javaWriter.label(startLabel);
68 70
 		javaWriter.dup();
69
-		javaWriter.dup();
70 71
 		javaWriter.arrayLength();
71
-		javaWriter.loadInt(z);
72
-
73
-		javaWriter.ifICmpLE(endLabel);
74
-		javaWriter.loadInt(z);
72
+        javaWriter.loadInt(z);
73
+        
74
+        javaWriter.ifICmpLE(endLabel);
75
+        javaWriter.dup();
76
+        javaWriter.loadInt(z);
75 77
 
76 78
 
77 79
 		javaWriter.arrayLoad(arrayTypeInfo.type);
@@ -85,7 +87,21 @@ public class JavaForeachWriter {
85 87
 	}
86 88
 
87 89
 	public void visitAssocKeyIterator() {
88
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
90
+	    javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.MAP, "keySet", "()Ljava/util/Set;", 0));
91
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.COLLECTION, "iterator", "()Ljava/util/Iterator;", 0));
92
+        
93
+        javaWriter.label(startLabel);
94
+        javaWriter.dup();
95
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "hasNext", "()Z", 0));
96
+        javaWriter.ifEQ(endLabel);
97
+        javaWriter.dup();
98
+        javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "next", "()Ljava/lang/Object;", 0));
99
+        
100
+        final JavaLocalVariableInfo keyVariable = javaWriter.getLocalVariable(variables[0].variable);
101
+        this.downCast(0, keyVariable.type);
102
+        javaWriter.store(keyVariable.type, keyVariable.local);
103
+        
104
+        content.accept(statementVisitor);
89 105
 	}
90 106
 
91 107
 	public void visitAssocKeyValueIterator() {
@@ -96,6 +112,7 @@ public class JavaForeachWriter {
96 112
 		javaWriter.dup();
97 113
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "hasNext", "()Z", 0));
98 114
 		javaWriter.ifEQ(endLabel);
115
+		javaWriter.dup();
99 116
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.ITERATOR, "next", "()Ljava/lang/Object;", 0));
100 117
 		javaWriter.checkCast(Type.getType(Map.Entry.class));
101 118
 		javaWriter.dup(false);
@@ -105,13 +122,21 @@ public class JavaForeachWriter {
105 122
 		final JavaLocalVariableInfo valueVariable = javaWriter.getLocalVariable(variables[1].variable);
106 123
 
107 124
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.fromInternalName("java/util/Map$Entry", JavaClass.Kind.INTERFACE), "getKey", "()Ljava/lang/Object;", 0));
125
+		this.downCast(0, keyVariable.type);
108 126
 		javaWriter.store(keyVariable.type, keyVariable.local);
109
-
127
+		
110 128
 		javaWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.fromInternalName("java/util/Map$Entry", JavaClass.Kind.INTERFACE), "getValue", "()Ljava/lang/Object;", 0));
129
+        this.downCast(1, valueVariable.type);
111 130
 		javaWriter.store(valueVariable.type, valueVariable.local);
131
+		
112 132
 		content.accept(statementVisitor);
113
-
114
-
115
-		//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
116 133
 	}
134
+	
135
+	private void downCast(int typeNumber, Type t) {
136
+        if(CompilerUtils.isPrimitive(variables[typeNumber].type.type)) {
137
+            variables[typeNumber].type.type.accept(variables[typeNumber].type, unboxingTypeVisitor);
138
+        } else {
139
+            javaWriter.checkCast(t);
140
+        }
141
+    }
117 142
 }

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

@@ -148,6 +148,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
148 148
 		
149 149
 		javaWriter.goTo(start);
150 150
 		javaWriter.label(end);
151
+		javaWriter.pop();
151 152
 		return false;
152 153
 	}
153 154
 

+ 137
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaUnboxingTypeVisitor.java View File

@@ -0,0 +1,137 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.objectweb.asm.Type;
4
+import org.openzen.zenscript.codemodel.type.*;
5
+import org.openzen.zenscript.javashared.JavaClass;
6
+import org.openzen.zenscript.javashared.JavaMethod;
7
+
8
+public class JavaUnboxingTypeVisitor implements TypeVisitorWithContext<StoredType, Void, RuntimeException> {
9
+    
10
+    private static final JavaMethod UNBOX_BOOLEAN = JavaMethod.getNativeVirtual(JavaClass.BOOLEAN, "booleanValue", "()Z");
11
+    private static final JavaMethod UNBOX_BYTE = JavaMethod.getNativeVirtual(JavaClass.BYTE, "byteValue", "()B");
12
+    private static final JavaMethod UNBOX_SHORT = JavaMethod.getNativeVirtual(JavaClass.SHORT, "shortValue", "()S");
13
+    private static final JavaMethod UNBOX_INTEGER = JavaMethod.getNativeVirtual(JavaClass.INTEGER, "intValue", "()I");
14
+    private static final JavaMethod UNBOX_LONG = JavaMethod.getNativeVirtual(JavaClass.LONG, "longValue", "()J");
15
+    private static final JavaMethod UNBOX_FLOAT = JavaMethod.getNativeVirtual(JavaClass.FLOAT, "floatValue", "()F");
16
+    private static final JavaMethod UNBOX_DOUBLE = JavaMethod.getNativeVirtual(JavaClass.DOUBLE, "doubleValue", "()D");
17
+    private static final JavaMethod UNBOX_CHARACTER = JavaMethod.getNativeVirtual(JavaClass.CHARACTER, "charValue", "()C");
18
+    
19
+    private final JavaWriter writer;
20
+    
21
+    public JavaUnboxingTypeVisitor(JavaWriter writer) {
22
+        this.writer = writer;
23
+    }
24
+    
25
+    
26
+    @Override
27
+    public Void visitBasic(StoredType context, BasicTypeID basic) throws RuntimeException {
28
+        final JavaMethod method;
29
+        
30
+        switch(basic) {
31
+            case BOOL:
32
+                writer.checkCast(JavaClass.BOOLEAN.internalName);
33
+                method = UNBOX_BOOLEAN;
34
+                break;
35
+            case BYTE:
36
+            case SBYTE:
37
+                writer.checkCast(JavaClass.BYTE.internalName);
38
+                method = UNBOX_BYTE;
39
+                break;
40
+            case SHORT:
41
+            case USHORT:
42
+                writer.checkCast(JavaClass.SHORT.internalName);
43
+                method = UNBOX_SHORT;
44
+                break;
45
+            case INT:
46
+            case UINT:
47
+                writer.checkCast(JavaClass.INTEGER.internalName);
48
+                method = UNBOX_INTEGER;
49
+                break;
50
+            case LONG:
51
+            case ULONG:
52
+            case USIZE:
53
+                writer.checkCast(JavaClass.LONG.internalName);
54
+                method = UNBOX_LONG;
55
+                break;
56
+            case FLOAT:
57
+                writer.checkCast(JavaClass.FLOAT.internalName);
58
+                method = UNBOX_FLOAT;
59
+                break;
60
+            case DOUBLE:
61
+                writer.checkCast(JavaClass.DOUBLE.internalName);
62
+                method = UNBOX_DOUBLE;
63
+                break;
64
+            case CHAR:
65
+                writer.checkCast(JavaClass.CHARACTER.internalName);
66
+                method = UNBOX_CHARACTER;
67
+                break;
68
+            case VOID:
69
+            case UNDETERMINED:
70
+            case NULL:
71
+            default:
72
+                return null;
73
+        }
74
+        writer.invokeVirtual(method);
75
+        return null;
76
+    }
77
+    
78
+    @Override
79
+    public Void visitString(StoredType context, StringTypeID string) throws RuntimeException {
80
+        //NO-OP
81
+        return null;
82
+    }
83
+    
84
+    @Override
85
+    public Void visitArray(StoredType context, ArrayTypeID array) throws RuntimeException {
86
+        //NO-OP
87
+        return null;
88
+    }
89
+    
90
+    @Override
91
+    public Void visitAssoc(StoredType context, AssocTypeID assoc) throws RuntimeException {
92
+        //NO-OP
93
+        return null;
94
+    }
95
+    
96
+    @Override
97
+    public Void visitGenericMap(StoredType context, GenericMapTypeID map) throws RuntimeException {
98
+        //NO-OP
99
+        return null;
100
+    }
101
+    
102
+    @Override
103
+    public Void visitIterator(StoredType context, IteratorTypeID iterator) throws RuntimeException {
104
+        //NO-OP
105
+        return null;
106
+    }
107
+    
108
+    @Override
109
+    public Void visitFunction(StoredType context, FunctionTypeID function) throws RuntimeException {
110
+        //NO-OP
111
+        return null;
112
+    }
113
+    
114
+    @Override
115
+    public Void visitDefinition(StoredType context, DefinitionTypeID definition) throws RuntimeException {
116
+        //NO-OP
117
+        return null;
118
+    }
119
+    
120
+    @Override
121
+    public Void visitGeneric(StoredType context, GenericTypeID generic) throws RuntimeException {
122
+        //NO-OP
123
+        return null;
124
+    }
125
+    
126
+    @Override
127
+    public Void visitRange(StoredType context, RangeTypeID range) throws RuntimeException {
128
+        //NO-OP
129
+        return null;
130
+    }
131
+    
132
+    @Override
133
+    public Void visitOptional(StoredType context, OptionalTypeID type) throws RuntimeException {
134
+        //NO-OP
135
+        return null;
136
+    }
137
+}

+ 56
- 31
JavaIntegration/src/main/java/org/openzen/zencode/java/JavaNativeModule.java View File

@@ -56,25 +56,16 @@ import org.openzen.zenscript.codemodel.type.storage.StaticStorageTag;
56 56
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
57 57
 import org.openzen.zenscript.codemodel.type.storage.StorageType;
58 58
 import org.openzen.zenscript.javashared.*;
59
-import org.openzen.zenscript.lexer.ParseException;
60
-import org.openzen.zenscript.lexer.ZSTokenParser;
59
+import org.openzen.zenscript.lexer.*;
61 60
 import org.openzen.zenscript.parser.BracketExpressionParser;
62 61
 import org.openzen.zenscript.parser.expression.ParsedExpression;
63 62
 import org.openzen.zenscript.parser.type.IParsedType;
64 63
 import stdlib.Strings;
65 64
 
66 65
 import java.io.IOException;
67
-import java.lang.reflect.AnnotatedType;
68
-import java.lang.reflect.Field;
69
-import java.lang.reflect.Member;
70
-import java.lang.reflect.Method;
71
-import java.lang.reflect.Modifier;
72
-import java.lang.reflect.Parameter;
73
-import java.lang.reflect.ParameterizedType;
74
-import java.lang.reflect.Type;
75
-import java.lang.reflect.TypeVariable;
66
+import java.lang.reflect.*;
76 67
 import java.util.*;
77
-import java.util.stream.Collectors;
68
+
78 69
 
79 70
 /**
80 71
  * @author Stan Hebben
@@ -834,11 +825,10 @@ public class JavaNativeModule {
834 825
 		boolean nullable = annotatedType.isAnnotationPresent(ZenCodeType.Nullable.class);
835 826
 		boolean unsigned = annotatedType.isAnnotationPresent(ZenCodeType.Unsigned.class);
836 827
 		
837
-		Type type = annotatedType.getType();
838
-		return loadType(context, type, nullable, unsigned);
828
+		return loadType(context, annotatedType, nullable, unsigned);
839 829
 	}
840 830
 	
841
-	private StoredType loadType(TypeVariableContext context, Type type, boolean nullable, boolean unsigned) {
831
+	private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean nullable, boolean unsigned) {
842 832
 		StoredType result = loadType(context, type, unsigned);
843 833
 		if (nullable)
844 834
 			result = new StoredType(registry.getOptional(result.type), result.getSpecifiedStorage());
@@ -846,18 +836,20 @@ public class JavaNativeModule {
846 836
 		return result;
847 837
 	}
848 838
 	
849
-	private StoredType loadType(TypeVariableContext context, Type type, boolean unsigned) {
839
+	@SuppressWarnings("ChainOfInstanceofChecks")
840
+    private StoredType loadType(TypeVariableContext context, AnnotatedElement type, boolean unsigned) {
850 841
 		if (type instanceof Class) {
851
-			Class<?> classType = (Class<?>) type;
842
+            Class<?> classType = (Class<?>) type;
852 843
 			if (unsigned) {
853
-				if (unsignedByClass.containsKey(classType))
854
-					return unsignedByClass.get(classType).stored();
855
-				else
856
-					throw new IllegalArgumentException("This class cannot be used as unsigned: " + classType);
844
+				if (unsignedByClass.containsKey(classType)) {
845
+                    return unsignedByClass.get(classType).stored();
846
+                } else {
847
+                    throw new IllegalArgumentException("This class cannot be used as unsigned: " + classType);
848
+                }
857 849
 			} else if (classType.isArray()) {
858 850
 				return registry.getArray(loadType(context, classType.getComponentType(), false, false), 1).stored();
859 851
 			} else if (classType.isAnnotationPresent(FunctionalInterface.class)) {
860
-				return loadFunctionalInterface(context, classType, new Type[0]);
852
+				return loadFunctionalInterface(context, classType, new AnnotatedElement[0]);
861 853
 			}
862 854
 			
863 855
 			if (typeByClass.containsKey(classType))
@@ -869,24 +861,57 @@ public class JavaNativeModule {
869 861
 			ParameterizedType parameterizedType = (ParameterizedType) type;
870 862
 			Class<?> rawType = (Class) parameterizedType.getRawType();
871 863
 			if (rawType.isAnnotationPresent(FunctionalInterface.class))
872
-				return loadFunctionalInterface(context, rawType, parameterizedType.getActualTypeArguments());
864
+				return loadFunctionalInterface(context, rawType, (AnnotatedElement[]) parameterizedType.getActualTypeArguments());
873 865
 			
874
-			HighLevelDefinition definition = addClass(rawType);
875 866
 			Type[] parameters = parameterizedType.getActualTypeArguments();
876 867
 			StoredType[] codeParameters = new StoredType[parameters.length];
877 868
 			for (int i = 0; i < parameters.length; i++)
878
-				codeParameters[i] = loadType(context, parameters[i], false, false);
879
-			
880
-			return registry.getForDefinition(definition, codeParameters).stored();
869
+			    codeParameters[i] = loadType(context, (AnnotatedElement) parameters[i], false, false);
870
+       
871
+			if(rawType == Map.class) {
872
+                return registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
873
+            }
874
+            
875
+            HighLevelDefinition definition = addClass(rawType);
876
+            return registry.getForDefinition(definition, codeParameters).stored();
881 877
 		} else if (type instanceof TypeVariable) {
882
-			TypeVariable variable = (TypeVariable)type;
883
-			return registry.getGeneric(context.get(variable)).stored();
884
-		} else {
878
+            TypeVariable variable = (TypeVariable) type;
879
+            return registry.getGeneric(context.get(variable)).stored();
880
+        }else if(type instanceof AnnotatedType){
881
+		    final StoredType storedType;
882
+		    if(type instanceof AnnotatedParameterizedType) {
883
+                AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) type;
884
+                final Type rawType = ((ParameterizedType) parameterizedType.getType()).getRawType();
885
+                final AnnotatedType[] actualTypeArguments = parameterizedType.getAnnotatedActualTypeArguments();
886
+                final StoredType[] codeParameters = new StoredType[actualTypeArguments.length];
887
+                for(int i = 0; i < actualTypeArguments.length; i++) {
888
+                    codeParameters[i] = loadType(context, actualTypeArguments[i], false, false);
889
+                }
890
+            
891
+                if(rawType == Map.class) {
892
+                    storedType = registry.getAssociative(codeParameters[0], codeParameters[1]).stored();
893
+                } else {
894
+                    HighLevelDefinition definition = addClass((Class<?>) rawType);
895
+                    storedType = registry.getForDefinition(definition, codeParameters).stored();
896
+                }
897
+            } else {
898
+		        storedType = loadType(context, (AnnotatedElement) ((AnnotatedType) type).getType(), unsigned);
899
+            }
900
+            
901
+		    if(type.isAnnotationPresent(ZenCodeStorageTag.class)) {
902
+		        //Replace with switch if more StorageTagTypes are added
903
+                if(type.getAnnotation(ZenCodeStorageTag.class).value() == StorageTagType.STATIC) {
904
+                    return storedType.type.stored(StorageTag.union(CodePosition.BUILTIN, storedType.getSpecifiedStorage(), StaticStorageTag.INSTANCE));
905
+                }
906
+            }
907
+		    return storedType;
908
+		    
909
+        } else {
885 910
 			throw new IllegalArgumentException("Could not analyze type: " + type);
886 911
 		}
887 912
 	}
888 913
 	
889
-	private StoredType loadFunctionalInterface(TypeVariableContext loadContext, Class<?> cls, Type[] parameters) {
914
+	private StoredType loadFunctionalInterface(TypeVariableContext loadContext, Class<?> cls, AnnotatedElement[] parameters) {
890 915
 		Method functionalInterfaceMethod = getFunctionalInterfaceMethod(cls);
891 916
 		TypeVariableContext context = convertTypeParameters(cls);
892 917
 		FunctionHeader header = getHeader(context, functionalInterfaceMethod);

+ 13
- 1
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionArray.java View File

@@ -6,7 +6,10 @@
6 6
 
7 7
 package org.openzen.zenscript.parser.expression;
8 8
 
9
+import java.util.ArrayList;
9 10
 import java.util.List;
11
+import java.util.function.BiFunction;
12
+
10 13
 import org.openzen.zencode.shared.CodePosition;
11 14
 import org.openzen.zencode.shared.CompileException;
12 15
 import org.openzen.zencode.shared.CompileExceptionCode;
@@ -24,7 +27,9 @@ import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
24 27
  * @author Stanneke
25 28
  */
26 29
 public class ParsedExpressionArray extends ParsedExpression {
27
-	private final List<ParsedExpression> contents;
30
+    
31
+    public static final List<BiFunction<ParsedExpressionArray, ExpressionScope, IPartialExpression>> compileOverrides = new ArrayList<>(0);
32
+    public final List<ParsedExpression> contents;
28 33
 
29 34
 	public ParsedExpressionArray(CodePosition position, List<ParsedExpression> contents) {
30 35
 		super(position);
@@ -34,6 +39,13 @@ public class ParsedExpressionArray extends ParsedExpression {
34 39
 
35 40
 	@Override
36 41
 	public IPartialExpression compile(ExpressionScope scope) throws CompileException {
42
+        
43
+        for(BiFunction<ParsedExpressionArray, ExpressionScope, IPartialExpression> compileOverride : compileOverrides) {
44
+            final IPartialExpression apply = compileOverride.apply(this, scope);
45
+            if(apply != null)
46
+                return apply;
47
+        }
48
+        
37 49
 		StoredType asBaseType = null;
38 50
 		StoredType asType = null;
39 51
 		boolean couldHintType = false;

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

@@ -8,6 +8,9 @@ package org.openzen.zenscript.parser.expression;
8 8
 
9 9
 import java.util.ArrayList;
10 10
 import java.util.List;
11
+import java.util.function.BiFunction;
12
+import java.util.function.Function;
13
+
11 14
 import org.openzen.zencode.shared.CodePosition;
12 15
 import org.openzen.zencode.shared.CompileException;
13 16
 import org.openzen.zencode.shared.CompileExceptionCode;
@@ -30,8 +33,11 @@ import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
30 33
  * @author Stanneke
31 34
  */
32 35
 public class ParsedExpressionMap extends ParsedExpression {
33
-	private final List<ParsedExpression> keys;
34
-	private final List<ParsedExpression> values;
36
+    
37
+    public static final List<BiFunction<ParsedExpressionMap, ExpressionScope, ? extends IPartialExpression>> compileOverrides = new ArrayList<>(0);
38
+    
39
+	public final List<ParsedExpression> keys;
40
+	public final List<ParsedExpression> values;
35 41
 
36 42
 	public ParsedExpressionMap(
37 43
 			CodePosition position,
@@ -45,6 +51,12 @@ public class ParsedExpressionMap extends ParsedExpression {
45 51
 
46 52
 	@Override
47 53
 	public IPartialExpression compile(ExpressionScope scope) throws CompileException {
54
+        for(BiFunction<ParsedExpressionMap, ExpressionScope, ? extends IPartialExpression> compileOverride : compileOverrides) {
55
+            final IPartialExpression apply = compileOverride.apply(this, scope);
56
+            if(apply != null)
57
+                return apply;
58
+        }
59
+	    
48 60
 		StoredType usedHint = null;
49 61
 		List<StoredType> keyHints = new ArrayList<>();
50 62
 		List<StoredType> valueHints = new ArrayList<>();

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

@@ -10,9 +10,7 @@ import java.util.List;
10 10
 import org.openzen.zencode.shared.CodePosition;
11 11
 import org.openzen.zenscript.codemodel.context.TypeResolutionContext;
12 12
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
13
-import org.openzen.zenscript.lexer.ParseException;
14
-import org.openzen.zenscript.lexer.ZSTokenParser;
15
-import org.openzen.zenscript.lexer.ZSTokenType;
13
+import org.openzen.zenscript.lexer.*;
16 14
 
17 15
 /**
18 16
  *
@@ -25,7 +23,8 @@ public class ParsedStorageTag {
25 23
 		if (parser.optional(ZSTokenType.T_BACKTICK) == null)
26 24
 			return NULL;
27 25
 		
28
-		String name = parser.required(ZSTokenType.T_IDENTIFIER, "identifier expected").content;
26
+		ZSToken token = parser.optional(ZSTokenType.K_STATIC);
27
+		String name = token != null ? token.content : parser.required(ZSTokenType.T_IDENTIFIER, "identifier expected").content;
29 28
 		List<String> arguments = new ArrayList<>();
30 29
 		while (parser.optional(ZSTokenType.T_COLON) != null)
31 30
 			arguments.add(parser.next().content);

+ 3
- 3
Validator/src/main/java/org/openzen/zenscript/validator/visitors/ExpressionValidator.java View File

@@ -60,7 +60,7 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
60 60
 				validator.logError(
61 61
 					ValidationLogEntry.Code.INVALID_OPERAND_TYPE,
62 62
 					expression.position,
63
-					"array element expression type doesn't match array type");
63
+					"array element expression type " + element.type + " doesn't match array type " + expression.arrayType.elementType);
64 64
 			}
65 65
 			element.accept(this);
66 66
 		}
@@ -383,10 +383,10 @@ public class ExpressionValidator implements ExpressionVisitor<Void> {
383 383
 			key.accept(this);
384 384
 			value.accept(this);
385 385
 			if (!key.type.equals(type.keyType)) {
386
-				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Key type must match the associative array key type");
386
+				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Key type " + key.type + " must match the associative array key type " + type.keyType);
387 387
 			}
388 388
 			if (!value.type.equals(type.valueType)) {
389
-				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Value type must match the associative array value type");
389
+				validator.logError(ValidationLogEntry.Code.INVALID_OPERAND_TYPE, key.position, "Value type " + value.type + " must match the associative array value type " + type.valueType);
390 390
 			}
391 391
 		}
392 392
 		return null;

Loading…
Cancel
Save