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();
}
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"));
}
}
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);
}
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);
}
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;
}
Aggregations