use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class ArrayExpr method withType.
@Override
public IValue withType(IType type, ITypeContext typeContext, MarkerList markers, IContext context) {
final IType elementType;
final Mutability mutability;
final ArrayType arrayType = type.extract(ArrayType.class);
if (arrayType == null) {
final Annotation annotation;
if ((annotation = type.getAnnotation(LazyFields.ARRAY_CONVERTIBLE)) != null) {
return new LiteralConversion(this, annotation, this.values).withType(type, typeContext, markers, context);
}
if (type.getTheClass() != Types.OBJECT_CLASS) {
return null;
}
// Compute element type from scratch
elementType = this.getElementType();
mutability = Mutability.IMMUTABLE;
} else {
// If the type is an array type, get it's element type
elementType = arrayType.getElementType();
mutability = type.getMutability();
}
final int size = this.values.size();
if (size == 0) {
this.elementType = elementType.getConcreteType(ITypeContext.DEFAULT);
this.arrayType = new ArrayType(this.elementType, mutability);
return this;
}
for (int i = 0; i < size; i++) {
final IValue value = TypeChecker.convertValue(this.values.get(i), elementType, typeContext, markers, context, LazyFields.ELEMENT_MARKER_SUPPLIER);
this.values.set(i, value);
}
this.elementType = null;
final int typecode = elementType.getTypecode();
if (typecode < 0) {
// local element type is an object type, so we infer the reference version of the computed element type
this.elementType = this.getElementType().getObjectType();
} else if (typecode != this.getElementType().getTypecode()) {
// local element type is a primitive type, but a different one from the computed element type,
// so we infer the local one
this.elementType = elementType;
}
// else: the above call to this.getElementType() has set this.elementType already
this.arrayType = new ArrayType(this.elementType, mutability);
return this;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class ArrayExpr method writeExpression.
@Override
public void writeExpression(MethodWriter writer, IType type) throws BytecodeException {
final int size = this.values.size();
final IType elementType = this.getElementType();
final int arrayStoreOpcode = elementType.getArrayStoreOpcode();
writer.visitLdcInsn(size);
writer.visitMultiANewArrayInsn(this.getType(), 1);
for (int i = 0; i < size; i++) {
writer.visitInsn(Opcodes.DUP);
writer.visitLdcInsn(i);
this.values.get(i).writeExpression(writer, elementType);
writer.visitInsn(arrayStoreOpcode);
}
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class BraceAccessExpr method resolve.
@Override
public IValue resolve(MarkerList markers, IContext context) {
if (this.value != null) {
this.value = this.value.resolve(markers, context);
} else {
this.value = context.resolveImplicit(null);
}
if (this.value == null) {
markers.add(Markers.semanticError(this.position, "braceaccess.invalid"));
} else {
final IType valueType = this.value.getType();
final IValue typedValue = this.value.withType(valueType, valueType, markers, context);
if (typedValue != null) {
this.value = typedValue;
}
this.variable = new Variable(Names.$0, this.value.getType());
this.implicitAccess = new FieldAccess(this.variable);
}
context = context.push(this);
this.statement = this.statement.resolve(markers, context);
context.pop();
return this;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class CastOperator method resolve.
@Override
public IValue resolve(MarkerList markers, IContext context) {
this.type.resolve(markers, context);
if (this.value == null) {
return this;
}
this.value = this.value.resolve(markers, context);
if (!this.type.isResolved()) {
return this;
}
final IType valueType = this.value.getType();
final IValue typedValue = TypeChecker.convertValue(this.value, this.type, null, markers, context);
if (typedValue != null) {
if (Types.isExactType(this.type, valueType)) {
// the cast type and the type of the value before type hinting are the exact same
// so we create a warning
markers.add(Markers.semantic(this.position, "cast.unnecessary", this.type));
return typedValue;
}
// the cast was a type hint that was not useless
this.value = typedValue;
this.optional = false;
return this;
}
// type hinting failed, this is an actual cast
final boolean primitiveType = this.type.isPrimitive();
final boolean primitiveValue = valueType.isPrimitive();
if (!(primitiveType && primitiveValue) && !Types.isSuperClass(valueType, this.type)) {
markers.add(Markers.semanticError(this.position, "cast.incompatible", valueType, this.type));
return this;
}
if (this.optional && (primitiveType || primitiveValue)) {
markers.add(Markers.semanticError(this.position, "cast.optional.primitive", valueType, this.type));
}
return this;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class ColonOperator method withType.
@Override
public IValue withType(IType type, ITypeContext typeContext, MarkerList markers, IContext context) {
final Annotation annotation = type.getAnnotation(LazyFields.COLON_CONVERTIBLE);
if (annotation != null) {
return new LiteralConversion(this, annotation, new ArgumentList(this.left, this.right)).withType(type, typeContext, markers, context);
}
if (!Types.isSuperClass(type, TupleType.getTupleClass(2).getClassType())) {
return null;
}
// reset type
this.type = null;
final IType leftType = Types.resolveTypeSafely(type, LazyFields.KEY_PARAMETER);
final IType rightType = Types.resolveTypeSafely(type, LazyFields.VALUE_PARAMETER);
this.left = TypeChecker.convertValue(this.left, leftType, typeContext, markers, context, TypeChecker.markerSupplier("colon_operator.left.type"));
this.right = TypeChecker.convertValue(this.right, rightType, typeContext, markers, context, TypeChecker.markerSupplier("colon_operator.right.type"));
return this;
}
Aggregations