Search in sources :

Example 96 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class ColonOperator method getTypeMatch.

@Override
public int getTypeMatch(IType type, IImplicitContext implicitContext) {
    if (!Types.isSuperClass(type, TupleType.getTupleClass(2).getClassType())) {
        if (type.getAnnotation(LazyFields.COLON_CONVERTIBLE) != null) {
            return CONVERSION_MATCH;
        }
        return MISMATCH;
    }
    final IType leftType = Types.resolveTypeSafely(type, LazyFields.KEY_PARAMETER);
    final int leftMatch = TypeChecker.getTypeMatch(this.left, leftType, implicitContext);
    if (leftMatch == MISMATCH) {
        return MISMATCH;
    }
    final IType rightType = Types.resolveTypeSafely(type, LazyFields.VALUE_PARAMETER);
    final int rightMatch = TypeChecker.getTypeMatch(this.right, rightType, implicitContext);
    if (rightMatch == MISMATCH) {
        return MISMATCH;
    }
    return Math.min(leftMatch, rightMatch);
}
Also used : IType(dyvilx.tools.compiler.ast.type.IType)

Example 97 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class AttributeList method getAnnotation.

public Annotation getAnnotation(IClass type) {
    for (int i = 0; i < this.size; i++) {
        final Attribute attribute = this.data[i];
        final IType attributeType = attribute.getType();
        if (attributeType != null && attributeType.getTheClass() == type) {
            return (Annotation) attribute;
        }
    }
    return null;
}
Also used : Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation) ExternalAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.ExternalAnnotation) IType(dyvilx.tools.compiler.ast.type.IType)

Example 98 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class AbstractConstructor method checkArguments.

@Override
public IType checkArguments(MarkerList markers, SourcePosition position, IContext context, IType type, ArgumentList arguments) {
    final IClass theClass = this.enclosingClass;
    if (!theClass.isTypeParametric()) {
        for (int i = 0, count = this.parameters.size(); i < count; i++) {
            arguments.checkValue(i, this.parameters.get(i), null, position, markers, context);
        }
        return type;
    }
    final IType classType = theClass.getThisType();
    final GenericData genericData = new GenericData(theClass);
    classType.inferTypes(type, genericData);
    genericData.lockAvailable();
    // Check Values and infer Types
    for (int i = 0, count = this.parameters.size(); i < count; i++) {
        arguments.checkValue(i, this.parameters.get(i), genericData, position, markers, context);
    }
    genericData.lockAvailable();
    // Check Type Var Inference and Compatibility
    final TypeParameterList typeParams = theClass.getTypeParameters();
    for (int i = 0, count = typeParams.size(); i < count; i++) {
        final ITypeParameter typeParameter = typeParams.get(i);
        final IType typeArgument = genericData.resolveType(typeParameter);
        if (typeArgument == null) {
            final IType inferredType = typeParameter.getUpperBound();
            markers.add(Markers.semantic(position, "constructor.typevar.infer", theClass.getName(), typeParameter.getName(), inferredType));
            genericData.addMapping(typeParameter, inferredType);
        } else if (!typeParameter.isAssignableFrom(typeArgument, genericData)) {
            final Marker marker = Markers.semanticError(position, "constructor.typevar.incompatible", theClass.getName(), typeParameter.getName());
            marker.addInfo(Markers.getSemantic("type.generic.argument", typeArgument));
            marker.addInfo(Markers.getSemantic("type_parameter.declaration", typeParameter));
            markers.add(marker);
        }
    }
    return classType.getConcreteType(genericData);
}
Also used : TypeParameterList(dyvilx.tools.compiler.ast.generic.TypeParameterList) ITypeParameter(dyvilx.tools.compiler.ast.generic.ITypeParameter) IClass(dyvilx.tools.compiler.ast.classes.IClass) Marker(dyvilx.tools.parsing.marker.Marker) GenericData(dyvilx.tools.compiler.ast.generic.GenericData) IType(dyvilx.tools.compiler.ast.type.IType)

Example 99 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class RangeForStatement method writeStatement.

@Override
public void writeStatement(MethodWriter writer) throws BytecodeException {
    // Determine the kind (int, long, float, double, Rangeable) of the range to fasten up compilation.
    byte kind = RANGEABLE;
    boolean boxed = false;
    final int lineNumber = this.lineNumber();
    final IVariable var = this.variable;
    final IType varType = var.getType();
    final MethodCall rangeOperator = (MethodCall) var.getValue();
    final IValue startValue = getStartValue(rangeOperator);
    final IValue endValue = getEndValue(rangeOperator);
    final IType elementType = this.elementType;
    final boolean halfOpen = isHalfOpen(rangeOperator);
    if (elementType.isPrimitive()) {
        switch(elementType.getTypecode()) {
            case PrimitiveType.BYTE_CODE:
            case PrimitiveType.SHORT_CODE:
            case PrimitiveType.CHAR_CODE:
            case PrimitiveType.INT_CODE:
                kind = INT;
                break;
            case PrimitiveType.LONG_CODE:
                kind = LONG;
                break;
            case PrimitiveType.FLOAT_CODE:
                kind = FLOAT;
                break;
            case PrimitiveType.DOUBLE_CODE:
                kind = DOUBLE;
                break;
        }
        if (!varType.isPrimitive()) {
            boxed = true;
        }
    }
    dyvilx.tools.asm.Label startLabel = this.startLabel.getTarget();
    dyvilx.tools.asm.Label updateLabel = this.updateLabel.getTarget();
    dyvilx.tools.asm.Label endLabel = this.endLabel.getTarget();
    dyvilx.tools.asm.Label scopeLabel = new dyvilx.tools.asm.Label();
    writer.visitLabel(scopeLabel);
    // Write the start value and store it in the variable.
    startValue.writeExpression(writer, elementType);
    final int counterVarIndex, varIndex;
    if (boxed) {
        // Create two variables, the counter variable and the user-visible loop variable
        writer.visitInsn(Opcodes.AUTO_DUP);
        counterVarIndex = writer.localCount();
        writer.visitVarInsn(elementType.getStoreOpcode(), counterVarIndex);
        elementType.writeCast(writer, varType, lineNumber);
        var.writeInit(writer, null);
        varIndex = var.getLocalIndex();
    } else {
        // Use the loop variable as the counter variable
        var.writeInit(writer, null);
        varIndex = counterVarIndex = var.getLocalIndex();
    }
    endValue.writeExpression(writer, elementType);
    final int endVarIndex = writer.localCount();
    writer.visitVarInsn(elementType.getStoreOpcode(), endVarIndex);
    writer.visitTargetLabel(startLabel);
    // Check the condition
    switch(kind) {
        case INT:
            writer.visitVarInsn(Opcodes.ILOAD, counterVarIndex);
            writer.visitVarInsn(Opcodes.ILOAD, endVarIndex);
            writer.visitJumpInsn(halfOpen ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPGT, endLabel);
            break;
        case LONG:
            writer.visitVarInsn(Opcodes.LLOAD, counterVarIndex);
            writer.visitVarInsn(Opcodes.LLOAD, endVarIndex);
            writer.visitJumpInsn(halfOpen ? Opcodes.IF_LCMPGE : Opcodes.IF_LCMPGT, endLabel);
            break;
        case FLOAT:
            writer.visitVarInsn(Opcodes.FLOAD, counterVarIndex);
            writer.visitVarInsn(Opcodes.FLOAD, endVarIndex);
            writer.visitJumpInsn(halfOpen ? Opcodes.IF_FCMPGE : Opcodes.IF_FCMPGT, endLabel);
            break;
        case DOUBLE:
            writer.visitVarInsn(Opcodes.DLOAD, counterVarIndex);
            writer.visitVarInsn(Opcodes.DLOAD, endVarIndex);
            writer.visitJumpInsn(halfOpen ? Opcodes.IF_DCMPGE : Opcodes.IF_DCMPGT, endLabel);
            break;
        case RANGEABLE:
            writer.visitVarInsn(Opcodes.ALOAD, counterVarIndex);
            writer.visitVarInsn(Opcodes.ALOAD, endVarIndex);
            writer.visitLineNumber(lineNumber);
            writer.visitMethodInsn(Opcodes.INVOKEINTERFACE, "dyvil/collection/range/Rangeable", "compareTo", "(Ldyvil/collection/range/Rangeable;)I", true);
            writer.visitJumpInsn(halfOpen ? Opcodes.IFGE : Opcodes.IFGT, endLabel);
            break;
    }
    // Action
    if (this.action != null) {
        this.action.writeExpression(writer, Types.VOID);
    }
    // Increment
    writer.visitLabel(updateLabel);
    switch(kind) {
        case INT:
            writer.visitIincInsn(counterVarIndex, 1);
            if (boxed) {
                writer.visitVarInsn(Opcodes.ILOAD, counterVarIndex);
                elementType.writeCast(writer, varType, lineNumber);
                writer.visitVarInsn(varType.getStoreOpcode(), varIndex);
            }
            break;
        case LONG:
            writer.visitVarInsn(Opcodes.LLOAD, counterVarIndex);
            writer.visitInsn(Opcodes.LCONST_1);
            writer.visitInsn(Opcodes.LADD);
            if (boxed) {
                writer.visitInsn(Opcodes.DUP2);
                elementType.writeCast(writer, varType, lineNumber);
                writer.visitVarInsn(varType.getStoreOpcode(), varIndex);
            }
            writer.visitVarInsn(Opcodes.LSTORE, counterVarIndex);
            break;
        case FLOAT:
            writer.visitVarInsn(Opcodes.FLOAD, counterVarIndex);
            writer.visitInsn(Opcodes.FCONST_1);
            writer.visitInsn(Opcodes.FADD);
            if (boxed) {
                writer.visitInsn(Opcodes.DUP);
                elementType.writeCast(writer, varType, lineNumber);
                writer.visitVarInsn(varType.getStoreOpcode(), varIndex);
            }
            writer.visitVarInsn(Opcodes.FSTORE, counterVarIndex);
            break;
        case DOUBLE:
            writer.visitVarInsn(Opcodes.DLOAD, counterVarIndex);
            writer.visitInsn(Opcodes.DCONST_1);
            writer.visitInsn(Opcodes.DADD);
            if (boxed) {
                writer.visitInsn(Opcodes.DUP2);
                elementType.writeCast(writer, varType, lineNumber);
                writer.visitVarInsn(varType.getStoreOpcode(), varIndex);
            }
            writer.visitVarInsn(Opcodes.DSTORE, counterVarIndex);
            break;
        case RANGEABLE:
            writer.visitVarInsn(Opcodes.ALOAD, counterVarIndex);
            writer.visitLineNumber(lineNumber);
            writer.visitMethodInsn(Opcodes.INVOKEINTERFACE, "dyvil/collection/range/Rangeable", "next", "()Ldyvil/collection/range/Rangeable;", true);
            if (elementType.getTheClass() != LazyFields.RANGEABLE_CLASS) {
                LazyFields.RANGEABLE.writeCast(writer, elementType, lineNumber);
            }
            assert !boxed;
            writer.visitVarInsn(Opcodes.ASTORE, counterVarIndex);
            break;
    }
    writer.visitJumpInsn(Opcodes.GOTO, startLabel);
    // Local Variables
    writer.resetLocals(counterVarIndex);
    writer.visitLabel(endLabel);
    var.writeLocal(writer, scopeLabel, endLabel);
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) IVariable(dyvilx.tools.compiler.ast.field.IVariable) MethodCall(dyvilx.tools.compiler.ast.expression.access.MethodCall) IType(dyvilx.tools.compiler.ast.type.IType)

Example 100 with IType

use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.

the class ClassGenericType method inferTypes.

@Override
public void inferTypes(IType concrete, ITypeContext typeContext) {
    final TypeParameterList classTypeParams = this.getTheClass().getTypeParameters();
    for (int i = 0, size = this.arguments.size(); i < size; i++) {
        final ITypeParameter typeVar = classTypeParams.get(i);
        final IType concreteType = concrete.resolveType(typeVar);
        if (concreteType != null) {
            this.arguments.get(i).inferTypes(concreteType, typeContext);
        }
    }
}
Also used : TypeParameterList(dyvilx.tools.compiler.ast.generic.TypeParameterList) ITypeParameter(dyvilx.tools.compiler.ast.generic.ITypeParameter) IType(dyvilx.tools.compiler.ast.type.IType)

Aggregations

IType (dyvilx.tools.compiler.ast.type.IType)159 IClass (dyvilx.tools.compiler.ast.classes.IClass)26 Marker (dyvilx.tools.parsing.marker.Marker)23 IValue (dyvilx.tools.compiler.ast.expression.IValue)21 TypeParameterList (dyvilx.tools.compiler.ast.generic.TypeParameterList)13 ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)11 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)10 SourcePosition (dyvil.source.position.SourcePosition)9 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)9 ITypeParameter (dyvilx.tools.compiler.ast.generic.ITypeParameter)9 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)9 TypeList (dyvilx.tools.compiler.ast.type.TypeList)7 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)6 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)6 IVariable (dyvilx.tools.compiler.ast.field.IVariable)6 ArrayType (dyvilx.tools.compiler.ast.type.compound.ArrayType)6 MethodWriter (dyvilx.tools.compiler.backend.MethodWriter)6 CodeMethod (dyvilx.tools.compiler.ast.method.CodeMethod)5 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)5 Name (dyvil.lang.Name)4