Browse Source

Adding support for builtin constructors

Stan Hebben 6 years ago
parent
commit
06e3a0c203

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

1
 package org.openzen.zenscript.javabytecode.compiler;
1
 package org.openzen.zenscript.javabytecode.compiler;
2
 
2
 
3
-import org.openzen.zenscript.javashared.JavaParameterInfo;
3
+import org.openzen.zenscript.javashared.*;
4
+
4
 import java.util.Arrays;
5
 import java.util.Arrays;
5
 import java.util.Comparator;
6
 import java.util.Comparator;
6
 import java.util.StringJoiner;
7
 import java.util.StringJoiner;
13
 import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
14
 import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
14
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
15
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
15
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
16
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
16
-import org.openzen.zenscript.codemodel.statement.ReturnStatement;
17
 import org.openzen.zenscript.codemodel.type.*;
17
 import org.openzen.zenscript.codemodel.type.*;
18
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
18
 import org.openzen.zenscript.codemodel.type.member.BuiltinID;
19
 import org.openzen.zenscript.javabytecode.*;
19
 import org.openzen.zenscript.javabytecode.*;
24
 import org.openzen.zenscript.codemodel.type.storage.BorrowStorageTag;
24
 import org.openzen.zenscript.codemodel.type.storage.BorrowStorageTag;
25
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
25
 import org.openzen.zenscript.codemodel.type.storage.StorageTag;
26
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
26
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
27
-import org.openzen.zenscript.javashared.JavaClass;
28
-import org.openzen.zenscript.javashared.JavaCompiledModule;
29
-import org.openzen.zenscript.javashared.JavaField;
30
-import org.openzen.zenscript.javashared.JavaMethod;
31
-import org.openzen.zenscript.javashared.JavaTypeUtils;
32
-import org.openzen.zenscript.javashared.JavaVariantOption;
33
 
27
 
34
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
28
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
35
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
29
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
96
 	private static final JavaField CHARACTER_MIN_VALUE = new JavaField(JavaClass.CHARACTER, "MIN_VALUE", "C");
90
 	private static final JavaField CHARACTER_MIN_VALUE = new JavaField(JavaClass.CHARACTER, "MIN_VALUE", "C");
97
 	private static final JavaField CHARACTER_MAX_VALUE = new JavaField(JavaClass.CHARACTER, "MAX_VALUE", "C");
91
 	private static final JavaField CHARACTER_MAX_VALUE = new JavaField(JavaClass.CHARACTER, "MAX_VALUE", "C");
98
 	private static final JavaMethod CHARACTER_TO_STRING = JavaMethod.getNativeStatic(JavaClass.CHARACTER, "toString", "(C)Ljava/lang/String;");
92
 	private static final JavaMethod CHARACTER_TO_STRING = JavaMethod.getNativeStatic(JavaClass.CHARACTER, "toString", "(C)Ljava/lang/String;");
93
+	private static final JavaMethod STRING_INIT_CHARACTERS = JavaMethod.getNativeConstructor(JavaClass.STRING, "([C)V");
99
 	private static final JavaMethod STRING_COMPARETO = JavaMethod.getNativeVirtual(JavaClass.STRING, "compareTo", "(Ljava/lang/String;)I");
94
 	private static final JavaMethod STRING_COMPARETO = JavaMethod.getNativeVirtual(JavaClass.STRING, "compareTo", "(Ljava/lang/String;)I");
100
 	private static final JavaMethod STRING_CONCAT = JavaMethod.getNativeVirtual(JavaClass.STRING, "concat", "(Ljava/lang/String;)Ljava/lang/String;");
95
 	private static final JavaMethod STRING_CONCAT = JavaMethod.getNativeVirtual(JavaClass.STRING, "concat", "(Ljava/lang/String;)Ljava/lang/String;");
101
 	private static final JavaMethod STRING_CHAR_AT = JavaMethod.getNativeVirtual(JavaClass.STRING, "charAt", "(I)C");
96
 	private static final JavaMethod STRING_CHAR_AT = JavaMethod.getNativeVirtual(JavaClass.STRING, "charAt", "(I)C");
109
 	private static final JavaMethod ENUM_COMPARETO = JavaMethod.getNativeVirtual(JavaClass.ENUM, "compareTo", "(Ljava/lang/Enum;)I");
104
 	private static final JavaMethod ENUM_COMPARETO = JavaMethod.getNativeVirtual(JavaClass.ENUM, "compareTo", "(Ljava/lang/Enum;)I");
110
 	private static final JavaMethod ENUM_NAME = JavaMethod.getNativeVirtual(JavaClass.ENUM, "name", "()Ljava/lang/String;");
105
 	private static final JavaMethod ENUM_NAME = JavaMethod.getNativeVirtual(JavaClass.ENUM, "name", "()Ljava/lang/String;");
111
 	private static final JavaMethod ENUM_ORDINAL = JavaMethod.getNativeVirtual(JavaClass.ENUM, "ordinal", "()I");
106
 	private static final JavaMethod ENUM_ORDINAL = JavaMethod.getNativeVirtual(JavaClass.ENUM, "ordinal", "()I");
107
+	private static final JavaMethod HASHMAP_INIT = JavaMethod.getNativeConstructor(JavaClass.HASHMAP, "()V");
112
 	private static final JavaMethod MAP_GET = JavaMethod.getNativeVirtual(JavaClass.MAP, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
108
 	private static final JavaMethod MAP_GET = JavaMethod.getNativeVirtual(JavaClass.MAP, "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
113
 	private static final JavaMethod MAP_PUT = JavaMethod.getNativeVirtual(JavaClass.MAP, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
109
 	private static final JavaMethod MAP_PUT = JavaMethod.getNativeVirtual(JavaClass.MAP, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
114
 	private static final JavaMethod MAP_CONTAINS_KEY = JavaMethod.getNativeVirtual(JavaClass.MAP, "containsKey", "(Ljava/lang/Object;)Z");
110
 	private static final JavaMethod MAP_CONTAINS_KEY = JavaMethod.getNativeVirtual(JavaClass.MAP, "containsKey", "(Ljava/lang/Object;)Z");
2128
 
2124
 
2129
     @Override
2125
     @Override
2130
     public Void visitNew(NewExpression expression) {
2126
     public Void visitNew(NewExpression expression) {
2127
+		if (expression.constructor.getBuiltin() != null) {
2128
+			visitBuiltinConstructor(expression);
2129
+			return null;
2130
+		}
2131
+
2131
 		JavaMethod method = context.getJavaMethod(expression.constructor);
2132
 		JavaMethod method = context.getJavaMethod(expression.constructor);
2132
-        javaWriter.newObject(method.cls.internalName);
2133
+        javaWriter.newObject(method.cls);
2133
         javaWriter.dup();
2134
         javaWriter.dup();
2134
 
2135
 
2135
 		for (Expression argument : expression.arguments.arguments) {
2136
 		for (Expression argument : expression.arguments.arguments) {
2140
 		return null;
2141
 		return null;
2141
 	}
2142
 	}
2142
 
2143
 
2144
+	private void visitBuiltinConstructor(NewExpression expression) {
2145
+		switch (expression.constructor.getBuiltin()) {
2146
+			case STRING_CONSTRUCTOR_CHARACTERS:
2147
+				javaWriter.newObject(JavaClass.STRING);
2148
+				javaWriter.dup();
2149
+				expression.arguments.arguments[0].accept(this);
2150
+				javaWriter.invokeSpecial(STRING_INIT_CHARACTERS);
2151
+				return;
2152
+			case ASSOC_CONSTRUCTOR:
2153
+			case GENERICMAP_CONSTRUCTOR: {
2154
+				javaWriter.newObject(JavaClass.HASHMAP);
2155
+				javaWriter.dup();
2156
+				javaWriter.invokeSpecial(HASHMAP_INIT);
2157
+				return;
2158
+			}
2159
+			case ARRAY_CONSTRUCTOR_SIZED: {
2160
+				ArrayTypeID type = (ArrayTypeID) expression.type.type;
2161
+				if (type.dimension == 1) {
2162
+					// new T[arguments[0]]
2163
+					expression.arguments.arguments[0].accept(this);
2164
+					javaWriter.newArray(context.getType(type.elementType));
2165
+					return;
2166
+				} else {
2167
+					// TODO: implement multidimensional arrays
2168
+					throw new UnsupportedOperationException("Not yet supported!");
2169
+				}
2170
+			}
2171
+			case ARRAY_CONSTRUCTOR_INITIAL_VALUE: {
2172
+				ArrayTypeID type = (ArrayTypeID) expression.type.type;
2173
+
2174
+				if (type.dimension == 1) {
2175
+					// array = new T[arguments[0]]
2176
+					// value = arguments[1]
2177
+					// for (int i = 0; i < array.length; i++)
2178
+					//    array[i] = value;
2179
+
2180
+					expression.arguments.arguments[0].accept(this); // array size
2181
+					javaWriter.newArray(context.getType(type.elementType));
2182
+
2183
+					int i = javaWriter.local(int.class);
2184
+					javaWriter.iConst0();
2185
+					javaWriter.storeInt(i);
2186
+
2187
+					Type valueType = context.getType(expression.arguments.arguments[1].type);
2188
+
2189
+					expression.arguments.arguments[1].accept(this); // initializer value
2190
+					javaWriter.store(valueType, i);
2191
+
2192
+					// TODO: implement in bytecode
2193
+					return;
2194
+				} else {
2195
+					// TODO: implement
2196
+					throw new UnsupportedOperationException("Not yet supported!");
2197
+				}
2198
+			}
2199
+			case ARRAY_CONSTRUCTOR_LAMBDA: {
2200
+				ArrayTypeID type = (ArrayTypeID) expression.type.type;
2201
+
2202
+				if (type.dimension == 1) {
2203
+					// array = new T[arguments[0]]
2204
+					// lambda = arguments[1]
2205
+					// for (int i = 0; i < array.length; i++)
2206
+					//    array[i] = lambda.invoke(i);
2207
+					//
2208
+					// NOTE: arguments[1] can be a FunctionExpression; this can be optimized by running it inline
2209
+
2210
+					// TODO: implement in bytecode
2211
+
2212
+					return;
2213
+				} else {
2214
+					// TODO: implement
2215
+					throw new UnsupportedOperationException("Not yet supported!");
2216
+				}
2217
+			}
2218
+			case ARRAY_CONSTRUCTOR_PROJECTED: {
2219
+				ArrayTypeID type = (ArrayTypeID) expression.type.type;
2220
+
2221
+				if (type.dimension == 1) {
2222
+					// original = arguments[0] (this is an array)
2223
+					// projector = arguments[1] (this is a lambda with 1 parameter)
2224
+					// array = new T[original.length]
2225
+					// for (int i = 0; i < array.length; i++)
2226
+					//    array[i] = projector(original[i]);
2227
+					//
2228
+					// NOTE: arguments[1] can be a FunctionExpression; this can be optimized by running it inline
2229
+
2230
+					// TODO: implement in bytecode
2231
+
2232
+					return;
2233
+				} else {
2234
+					// TODO: implement
2235
+					throw new UnsupportedOperationException("Not yet supported!");
2236
+				}
2237
+			}
2238
+			case ARRAY_CONSTRUCTOR_PROJECTED_INDEXED: {
2239
+				ArrayTypeID type = (ArrayTypeID) expression.type.type;
2240
+
2241
+				if (type.dimension == 1) {
2242
+					// original = arguments[0] (this is an array)
2243
+					// projector = arguments[1] (this is a lambda with 2 parameters)
2244
+					// array = new T[original.length]
2245
+					// for (int i = 0; i < array.length; i++)
2246
+					//   array[i] = projector(i, original[i]);
2247
+					//
2248
+					// NOTE: arguments[1] can be a FunctionExpression; this can be optimized by running it inline
2249
+
2250
+					// TODO: implement in bytecode
2251
+
2252
+					return;
2253
+				} else {
2254
+					// TODO: implement
2255
+					throw new UnsupportedOperationException("Not yet supported!");
2256
+				}
2257
+			}
2258
+			case CLASS_DEFAULT_CONSTRUCTOR:
2259
+				javaWriter.newObject(context.getInternalName(expression.type));
2260
+				javaWriter.dup();
2261
+				javaWriter.invokeSpecial(context.getJavaMethod(expression.constructor));
2262
+				return;
2263
+		}
2264
+
2265
+		throw new UnsupportedOperationException("Unknown builtin constructor: " + expression.constructor.getBuiltin());
2266
+	}
2267
+
2143
 	@Override
2268
 	@Override
2144
 	public Void visitNull(NullExpression expression) {
2269
 	public Void visitNull(NullExpression expression) {
2145
 		if (!expression.type.isBasic(BasicTypeID.NULL) && expression.type.type.withoutOptional() == BasicTypeID.USIZE)
2270
 		if (!expression.type.isBasic(BasicTypeID.NULL) && expression.type.type.withoutOptional() == BasicTypeID.USIZE)

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

851
         visitor.visitTypeInsn(NEW, internalName);
851
         visitor.visitTypeInsn(NEW, internalName);
852
     }
852
     }
853
 
853
 
854
+    public void newObject(JavaClass cls) {
855
+        if (debug)
856
+            System.out.println("newObject " + cls.internalName);
857
+
858
+        visitor.visitTypeInsn(NEW, cls.internalName);
859
+    }
860
+
854
     public void goTo(Label lbl) {
861
     public void goTo(Label lbl) {
855
         if (debug)
862
         if (debug)
856
             System.out.println("goTo " + getLabelName(lbl));
863
             System.out.println("goTo " + getLabelName(lbl));

Loading…
Cancel
Save