Search in sources :

Example 46 with IValue

use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.

the class CodeConstructor method resolve.

@Override
public void resolve(MarkerList markers, IContext context) {
    super.resolve(markers, context);
    context = context.push(this);
    this.parameters.resolve(markers, context);
    if (this.exceptions != null) {
        this.exceptions.resolve(markers, context);
    }
    this.resolveInitCall(markers, context);
    if (this.value != null) {
        this.value = this.value.resolve(markers, context);
        final IValue typedValue = this.value.withType(Types.VOID, Types.VOID, markers, context);
        if (typedValue == null) {
            Marker marker = Markers.semanticError(this.position, "constructor.return.type");
            marker.addInfo(Markers.getSemantic("return.type", this.value.getType()));
            markers.add(marker);
        } else {
            this.value = typedValue;
        }
    }
    context.pop();
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) Marker(dyvilx.tools.parsing.marker.Marker)

Example 47 with IValue

use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.

the class Initializer method resolve.

@Override
public void resolve(MarkerList markers, IContext context) {
    super.resolve(markers, context);
    if (this.value != null) {
        final IContext context1 = new CombiningContext(this, context);
        final IValue resolved = this.value.resolve(markers, context1);
        this.value = TypeChecker.convertValue(resolved, Types.VOID, Types.VOID, markers, context1, TypeChecker.markerSupplier("initializer.type"));
    }
}
Also used : IContext(dyvilx.tools.compiler.ast.context.IContext) IValue(dyvilx.tools.compiler.ast.expression.IValue) CombiningContext(dyvilx.tools.compiler.ast.context.CombiningContext)

Example 48 with IValue

use of dyvilx.tools.compiler.ast.expression.IValue 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 49 with IValue

use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.

the class ValueAnnotationVisitor method visit.

@Override
public void visit(String key, Object value) {
    final IValue iValue = IValue.fromObject(value);
    if (iValue == null) {
        throw new BytecodeException("Cannot convert '" + value + "' into an IValue");
    }
    this.consumer.setValue(iValue);
}
Also used : IValue(dyvilx.tools.compiler.ast.expression.IValue) BytecodeException(dyvilx.tools.compiler.backend.exception.BytecodeException)

Example 50 with IValue

use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.

the class Deprecation method getReasons.

private static Reason[] getReasons(ArgumentList arguments) {
    final IValue value = arguments.get(DEP_REASONS_PARAM);
    if (value == null) {
        return null;
    }
    assert value.valueTag() == IValue.ARRAY;
    final ArrayExpr array = (ArrayExpr) value;
    final ArgumentList values = array.getValues();
    final int size = values.size();
    if (size <= 0) {
        return null;
    }
    final Reason[] reasons = new Reason[size];
    for (int i = 0; i < size; i++) {
        final IValue element = values.get(i);
        assert element.valueTag() == IValue.ENUM_ACCESS;
        final EnumValue enumValue = (EnumValue) element;
        reasons[i] = Reason.valueOf(enumValue.getInternalName());
    }
    return reasons;
}
Also used : ArrayExpr(dyvilx.tools.compiler.ast.expression.ArrayExpr) IValue(dyvilx.tools.compiler.ast.expression.IValue) EnumValue(dyvilx.tools.compiler.ast.expression.constant.EnumValue) ArgumentList(dyvilx.tools.compiler.ast.parameter.ArgumentList) Reason(dyvil.annotation.Deprecated.Reason)

Aggregations

IValue (dyvilx.tools.compiler.ast.expression.IValue)79 IType (dyvilx.tools.compiler.ast.type.IType)20 ArgumentList (dyvilx.tools.compiler.ast.parameter.ArgumentList)17 FieldAccess (dyvilx.tools.compiler.ast.expression.access.FieldAccess)11 SourcePosition (dyvil.source.position.SourcePosition)10 IParameter (dyvilx.tools.compiler.ast.parameter.IParameter)9 ArrayExpr (dyvilx.tools.compiler.ast.expression.ArrayExpr)7 Marker (dyvilx.tools.parsing.marker.Marker)7 IMethod (dyvilx.tools.compiler.ast.method.IMethod)6 AttributeList (dyvilx.tools.compiler.ast.attribute.AttributeList)5 IContext (dyvilx.tools.compiler.ast.context.IContext)5 MethodCall (dyvilx.tools.compiler.ast.expression.access.MethodCall)5 CodeParameter (dyvilx.tools.compiler.ast.parameter.CodeParameter)5 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)4 IClass (dyvilx.tools.compiler.ast.classes.IClass)4 Variable (dyvilx.tools.compiler.ast.field.Variable)4 ParameterList (dyvilx.tools.compiler.ast.parameter.ParameterList)4 CombiningContext (dyvilx.tools.compiler.ast.context.CombiningContext)3 IVariable (dyvilx.tools.compiler.ast.field.IVariable)3 CodeMethod (dyvilx.tools.compiler.ast.method.CodeMethod)3