use of dyvilx.tools.compiler.ast.expression.IValue 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.expression.IValue in project Dyvil by Dyvil.
the class Closure method withType.
@Override
public IValue withType(IType type, ITypeContext typeContext, MarkerList markers, IContext context) {
if (this.resolved) {
return super.withType(type, typeContext, markers, context);
}
final IMethod functionalMethod = type.getFunctionalMethod();
if (functionalMethod == null) {
return null;
}
final ParameterList parameterList = functionalMethod.getParameters();
final int parameterCount = parameterList.size();
final IParameter[] parameters = new IParameter[parameterCount];
for (int i = 0; i < parameterCount; i++) {
parameters[i] = new CodeParameter(null, this.position, Name.fromRaw("$" + i), Types.UNKNOWN);
}
final LambdaType functionType = type.extract(LambdaType.class);
if (functionType != null && functionType.isExtension() && parameterCount > 0) {
this.implicitValue = new FieldAccess(parameters[0]);
}
final LambdaExpr lambdaExpr = new LambdaExpr(this.position, parameters, parameterCount);
lambdaExpr.setValue(this);
this.resolved = true;
context = context.push(this);
final IValue typedLambda = lambdaExpr.withType(type, typeContext, markers, context);
context.pop();
return typedLambda;
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class IStatement method checkStatement.
static IValue checkStatement(MarkerList markers, IContext context, IValue resolvedValue, String key) {
final IValue typedValue = resolvedValue.withType(Types.VOID, Types.VOID, markers, context);
if (typedValue != null && typedValue.isUsableAsStatement()) {
return typedValue;
}
// Create an error
final Marker marker = Markers.semantic(resolvedValue.getPosition(), key);
marker.addInfo(Markers.getSemantic("expression.type", resolvedValue.getType()));
markers.add(marker);
return resolvedValue;
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class ArgumentList method resolveMissing.
protected void resolveMissing(IParameter param, GenericData genericData, SourcePosition position, MarkerList markers, IContext context) {
if (this == EMPTY) {
// cannot infer missing arguments if the argument list is EMPTY (i.e. not denoted)
final Marker marker = Markers.semanticError(position, "method.access.argument.empty", param.getName());
marker.addInfo(Markers.getSemantic("method.access.argument.empty.info"));
markers.add(marker);
return;
}
if (param.isVarargs()) {
// varargs parameter
final IValue value = convertValue(new ArrayExpr(position, EMPTY), param, genericData, markers, context);
this.add(param.getLabel(), value);
return;
}
if (!param.isImplicit()) {
if (this.resolveDefault(param, context)) {
return;
}
markers.add(Markers.semanticError(position, "method.access.argument.missing", param.getName()));
return;
}
// implicit parameter, possibly default
final IType type;
if (genericData != null) {
genericData.lockAvailable();
type = param.getCovariantType().getConcreteType(genericData);
} else {
type = param.getCovariantType();
}
final IValue implicit = context.resolveImplicit(type);
if (implicit != null) {
// make sure to resolve and type-check the implicit value
// (implicit values should be only field accesses, but might need some capture or "this<Outer" resolution)
final IValue value = convertValue(implicit.resolve(markers, context), param, genericData, markers, context);
this.add(param.getLabel(), value);
return;
}
// default resolution only if implicit resolution fails
if (this.resolveDefault(param, context)) {
return;
}
markers.add(Markers.semanticError(position, "method.access.argument.implicit", param.getName(), type));
return;
}
use of dyvilx.tools.compiler.ast.expression.IValue in project Dyvil by Dyvil.
the class NamedArgumentList method resolveTypes.
@Override
public void resolveTypes(MarkerList markers, IContext context) {
for (int i = 0; i < this.size; i++) {
final Name key = this.keys[i];
final IValue value = this.values[i];
value.resolveTypes(markers, context);
if (key == null) {
continue;
}
for (int j = 0; j < i; j++) {
if (this.keys[j] == key) {
markers.add(Markers.semanticError(value.getPosition(), "arguments.duplicate.key", key));
break;
}
}
}
}
Aggregations