use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class TryStatement method getType.
@Override
public IType getType() {
if (this.commonType != null) {
return this.commonType;
}
if (this.action == null) {
return Types.UNKNOWN;
}
IType combinedType = this.action.getType();
for (int i = 0; i < this.catchBlockCount; i++) {
final IType catchBlockType = this.catchBlocks[i].action.getType();
combinedType = Types.combine(combinedType, catchBlockType);
if (combinedType == null) {
return this.commonType = Types.ANY;
}
}
return this.commonType = combinedType;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class ForEachStatement method resolve.
@Override
public IValue resolve(MarkerList markers, IContext context) {
IType varType = this.variable.getType();
final IValue value = this.resolveValue(markers, context);
final IType valueType = value.getType();
if (value.valueTag() == IValue.METHOD_CALL) {
final MethodCall rangeOperator = (MethodCall) value;
if (RangeForStatement.isRangeOperator(rangeOperator)) {
final IType elementType = RangeForStatement.getElementType(rangeOperator);
if (varType == Types.UNKNOWN) {
this.inferVariableType(markers, elementType);
} else if (!Types.isAssignable(varType, elementType)) {
final Marker marker = Markers.semanticError(value.getPosition(), "for.range.type");
marker.addInfo(Markers.getSemantic("range.type", valueType));
marker.addInfo(Markers.getSemantic("variable.type", varType));
markers.add(marker);
}
final RangeForStatement rangeForStatement = new RangeForStatement(this.position, this.variable, elementType);
rangeForStatement.resolveAction(this.action, markers, context);
return rangeForStatement;
}
}
final ArrayType arrayType = valueType.extract(ArrayType.class);
if (arrayType != null) {
if (varType == Types.UNKNOWN) {
this.inferVariableType(markers, arrayType.getElementType());
} else if (!Types.isAssignable(varType, arrayType.getElementType())) {
final Marker marker = Markers.semanticError(value.getPosition(), "for.array.type");
marker.addInfo(Markers.getSemantic("array.type", valueType));
marker.addInfo(Markers.getSemantic("variable.type", varType));
markers.add(marker);
}
final ArrayForStatement arrayForStatement = new ArrayForStatement(this.position, this.variable, arrayType);
arrayForStatement.resolveAction(this.action, markers, context);
return arrayForStatement;
}
if (Types.isAssignable(IterableForStatement.LazyFields.ITERATOR, valueType)) {
return this.toIteratorLoop(markers, context, varType, value, valueType);
}
if (Types.isAssignable(IterableForStatement.LazyFields.ITERABLE, valueType)) {
return this.toIterable(markers, context, varType, value, valueType);
}
if (Types.isAssignable(Types.STRING, valueType)) {
return this.toStringLoop(markers, context, varType, value);
}
final Marker marker = Markers.semanticError(this.variable.getPosition(), "for.each.invalid");
marker.addInfo(Markers.getSemantic("value.type", valueType));
markers.add(marker);
this.resolveAction(this.action, markers, context);
return this;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class ForEachStatement method resolveValue.
private IValue resolveValue(MarkerList markers, IContext context) {
IValue value = this.variable.getValue().resolve(markers, context);
IType valueType = value.getType();
value = TypeChecker.convertValue(value, valueType, valueType, markers, context, TypeChecker.markerSupplier("for.each.type"));
this.variable.setValue(value);
return value;
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class IterableForStatement 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 varType = var.getType();
final int lineNumber = this.lineNumber();
// Scope
dyvilx.tools.asm.Label scopeLabel = new dyvilx.tools.asm.Label();
writer.visitLabel(scopeLabel);
int localCount = writer.localCount();
// Get the iterator
var.getValue().writeExpression(writer, null);
if (!this.iterator) {
writer.visitLineNumber(lineNumber);
writer.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/lang/Iterable", "iterator", "()Ljava/util/Iterator;", true);
}
// Local Variables
int iteratorVarIndex = writer.localCount();
var.setLocalIndex(iteratorVarIndex + 1);
// Store Iterator
writer.visitVarInsn(Opcodes.ASTORE, iteratorVarIndex);
// Jump to hasNext check
writer.visitJumpInsn(Opcodes.GOTO, updateLabel);
writer.visitTargetLabel(startLabel);
// Invoke Iterator.next()
writer.visitVarInsn(Opcodes.ALOAD, iteratorVarIndex);
writer.visitLineNumber(lineNumber);
writer.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
// Auocasting
Types.OBJECT.writeCast(writer, varType, lineNumber);
// Store the next element
writer.visitVarInsn(varType.getStoreOpcode(), iteratorVarIndex + 1);
// Action
if (this.action != null) {
this.action.writeExpression(writer, Types.VOID);
}
writer.visitLabel(updateLabel);
// Load Iterator
writer.visitVarInsn(Opcodes.ALOAD, iteratorVarIndex);
// Check hasNext
writer.visitLineNumber(lineNumber);
writer.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
// Go back to start if Iterator.hasNext() returned true
writer.visitJumpInsn(Opcodes.IFNE, startLabel);
// Local Variables
writer.resetLocals(localCount);
writer.visitLabel(endLabel);
var.writeLocal(writer, scopeLabel, endLabel);
}
use of dyvilx.tools.compiler.ast.type.IType in project Dyvil by Dyvil.
the class Types method addSuperClasses.
private static void addSuperClasses(IType type, Collection<IClass> types) {
final IClass theClass = type.getTheClass();
if (theClass == null) {
return;
}
types.add(theClass);
final IType superType = theClass.getSuperType();
if (superType != null) {
addSuperClasses(superType, types);
}
final TypeList interfaces = theClass.getInterfaces();
if (interfaces == null) {
return;
}
for (int i = 0, count = interfaces.size(); i < count; i++) {
addSuperClasses(interfaces.get(i), types);
}
}
Aggregations