use of dyvilx.tools.compiler.ast.field.IVariable in project Dyvil by Dyvil.
the class BindingIfStatement method conditionToString.
// endregion
@Override
protected void conditionToString(String indent, StringBuilder buffer) {
for (IVariable var : this.variables) {
var.toString(indent, buffer);
buffer.append(", ");
}
this.condition.toString(indent, buffer);
}
use of dyvilx.tools.compiler.ast.field.IVariable in project Dyvil by Dyvil.
the class BindingIfStatement method resolveConditionTypes.
@Override
protected void resolveConditionTypes(MarkerList markers, IContext context) {
final int size = this.variables.size();
for (int i = 0; i < size; i++) {
final IVariable var = this.variables.get(i);
var.setValue(new OptionalUnwrapOperator(var.getValue(), true));
var.resolveTypes(markers, this.varContext(i, context));
}
super.resolveConditionTypes(markers, this.varContext(size, context));
}
use of dyvilx.tools.compiler.ast.field.IVariable in project Dyvil by Dyvil.
the class BindingIfStatement method checkCondition.
@Override
protected void checkCondition(MarkerList markers, IContext context) {
final int size = this.variables.size();
for (int i = 0; i < size; i++) {
final IVariable var = this.variables.get(i);
var.check(markers, this.varContext(i, context));
final IValue value = getOptionalValue(var);
final IType type = value.getType();
if (value.isResolved() && type.isResolved() && !NullableType.isNullable(type)) {
final Marker marker = Markers.semanticError(value.getPosition(), "if.binding.nonnull");
marker.addInfo(Markers.getSemantic("value.type", type));
markers.add(marker);
}
}
super.checkCondition(markers, this.varContext(size, context));
}
use of dyvilx.tools.compiler.ast.field.IVariable in project Dyvil by Dyvil.
the class BindingIfStatement method writeCondition.
@Override
protected void writeCondition(MethodWriter writer, Label elseStart) {
for (IVariable var : this.variables) {
IValue value = getOptionalValue(var);
final CastOperator castOp;
final int localCount = writer.localCount();
final int varIndex;
if (value instanceof CastOperator && (castOp = (CastOperator) value).isOptional()) {
// optimization for optional cast operators
value = castOp.getValue();
varIndex = value.writeStoreLoad(writer, null);
// branch if necessary (also branches if null)
writer.visitTypeInsn(Opcodes.INSTANCEOF, castOp.getType().getInternalName());
writer.visitJumpInsn(Opcodes.IFEQ, elseStart);
} else {
varIndex = value.writeStoreLoad(writer, null);
// branch if necessary
writer.visitJumpInsn(Opcodes.IFNULL, elseStart);
}
// load and unwrap the variable
writer.visitVarInsn(Opcodes.ALOAD, varIndex);
writer.resetLocals(localCount);
value.getType().writeCast(writer, var.getType(), value.lineNumber());
// store, but this time with the right type
var.writeInit(writer, null);
}
super.writeCondition(writer, elseStart);
}
use of dyvilx.tools.compiler.ast.field.IVariable in project Dyvil by Dyvil.
the class ArrayForStatement method writeStatement.
@Override
public void writeStatement(MethodWriter writer) throws BytecodeException {
dyvilx.tools.asm.Label startLabel = this.startLabel.getTarget();
dyvilx.tools.asm.Label updateLabel = this.updateLabel.getTarget();
dyvilx.tools.asm.Label endLabel = this.endLabel.getTarget();
final IVariable var = this.variable;
final IType elementType = this.arrayType.getElementType();
final int lineNumber = this.lineNumber();
// Scope
dyvilx.tools.asm.Label scopeLabel = new dyvilx.tools.asm.Label();
writer.visitLabel(scopeLabel);
final int localCount = writer.localCount();
// Load the array
final int arrayVarIndex = var.getValue().writeStore(writer, null);
// Local Variables
final int lengthVarIndex = writer.localCount();
final int indexVarIndex = lengthVarIndex + 1;
writer.visitVarInsn(Opcodes.ALOAD, arrayVarIndex);
// Load the length
writer.visitLineNumber(lineNumber);
writer.visitInsn(Opcodes.ARRAYLENGTH);
writer.visitInsn(Opcodes.DUP);
writer.visitVarInsn(Opcodes.ISTORE, lengthVarIndex);
// Initial Boundary Check - if the length is less than or equal to 0, skip the loop
writer.visitJumpInsn(Opcodes.IFLE, endLabel);
// Set index to 0
writer.visitLdcInsn(0);
writer.visitVarInsn(Opcodes.ISTORE, indexVarIndex);
writer.visitTargetLabel(startLabel);
// Load the element
writer.visitVarInsn(Opcodes.ALOAD, arrayVarIndex);
writer.visitVarInsn(Opcodes.ILOAD, indexVarIndex);
writer.visitLineNumber(lineNumber);
writer.visitInsn(elementType.getArrayLoadOpcode());
// Autocasting
elementType.writeCast(writer, var.getType(), lineNumber);
// Store variable
var.writeInit(writer, null);
// Action
if (this.action != null) {
this.action.writeExpression(writer, Types.VOID);
}
writer.visitLabel(updateLabel);
// Increment index
writer.visitIincInsn(indexVarIndex, 1);
// Boundary Check
writer.visitVarInsn(Opcodes.ILOAD, indexVarIndex);
writer.visitVarInsn(Opcodes.ILOAD, lengthVarIndex);
writer.visitJumpInsn(Opcodes.IF_ICMPLT, startLabel);
// Local Variables
writer.visitLabel(endLabel);
writer.resetLocals(localCount);
var.writeLocal(writer, scopeLabel, endLabel);
}
Aggregations