111 lines
4.0 KiB
Plaintext
111 lines
4.0 KiB
Plaintext
|
package slangc.model.expressions;
|
||
|
|
||
|
import slangc.api.BytecodeInstructionWriter;
|
||
|
import slangc.api.Reporter;
|
||
|
import slangc.bytecode.TypeSignature;
|
||
|
import slangc.model.ExpressionModel;
|
||
|
import slangc.model.ExpressionOwner;
|
||
|
import slangc.model.ExpressionResult;
|
||
|
import slangc.model.FieldModel;
|
||
|
import slangc.model.LocalStorageModel;
|
||
|
import slangc.model.Named;
|
||
|
import slangc.model.StorageSlot;
|
||
|
import slangc.model.TypeModel;
|
||
|
import slangc.model.UserTypeModel;
|
||
|
import slangc.parser.Branch;
|
||
|
import slangc.parser.ErrorType;
|
||
|
import slangc.parser.Node;
|
||
|
|
||
|
public class ReferenceExpression extends ExpressionModel {
|
||
|
private String name;
|
||
|
private Named resolvedNamedEntity;
|
||
|
|
||
|
public ReferenceExpression(ExpressionOwner owner, Node source) {
|
||
|
super(owner, source);
|
||
|
name = UserTypeModel.plainName(((Branch)source).getSubnode(0));
|
||
|
// This now waits until expressions are resolved later
|
||
|
//resolvedNamedEntity = lookupSimpleName(name);
|
||
|
//sourceFile.annotate(ErrorType.INTERNAL_ERROR, "Unrecognised expression (Internal error/TODO)");
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void dump(Reporter reporter, String indent, String incr) {
|
||
|
reporter.note("DUMP", indent + "> Reference expression '" + name + "' -> " + resolvedNamedEntity);
|
||
|
dumpResolved(reporter, indent + incr, incr);
|
||
|
}
|
||
|
|
||
|
public String getName() {
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
public Named getResolvedNamedEntity() {
|
||
|
return resolvedNamedEntity;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public ExpressionModel[] getSubexpressions() {
|
||
|
return NO_SUBEXPRESSIONS;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected ExpressionResult resolveResult() {
|
||
|
if (resolvedNamedEntity == null) {
|
||
|
resolvedNamedEntity = lookupSimpleName(name);
|
||
|
}
|
||
|
//System.err.println("Resolved to " + resolvedNamedEntity);
|
||
|
if (resolvedNamedEntity == null) {
|
||
|
if (!(getOwner() instanceof SubreferenceExpression)) {
|
||
|
getSource().annotate(ErrorType.INTERNAL_ERROR, "Failed to resolve '" + name + "'");
|
||
|
}
|
||
|
return new ExpressionResult.StartOfName(name);
|
||
|
} else if (resolvedNamedEntity instanceof TypeModel) {
|
||
|
return new ExpressionResult.PointsToType((TypeModel) resolvedNamedEntity);
|
||
|
} else if (resolvedNamedEntity instanceof StorageSlot) {
|
||
|
return new ExpressionResult.PointsToStorageSlot((StorageSlot) resolvedNamedEntity);
|
||
|
} else {
|
||
|
throw new Error("Reference resolved to invalid entity: " + resolvedNamedEntity);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public TypeSignature innerGenerate(BytecodeInstructionWriter w) {
|
||
|
if (getResolvedNamedEntity() instanceof FieldModel) {
|
||
|
FieldModel f = (FieldModel)getResolvedNamedEntity();
|
||
|
if (!f.isStatic()) {
|
||
|
OuterThisExpression.generatePossibleOuterThis(w, (UserTypeModel)getMethodOrField().getOwner(), f.getOwner());
|
||
|
}
|
||
|
w.genLoad(f.getFieldSignature());
|
||
|
return f.getFieldSignature().storageType;
|
||
|
} else if (getResolvedNamedEntity() instanceof LocalStorageModel) {
|
||
|
LocalStorageModel l = (LocalStorageModel)getResolvedNamedEntity();
|
||
|
// TODO: Handle upvalues!
|
||
|
w.genLoadLocalOrParam(l.getStorageType().getTypeSignature(), l.getIndex());
|
||
|
return l.getStorageType().getTypeSignature();
|
||
|
} else {
|
||
|
w.genError("TODO: innerGenerate for " + Type.of(this) + " with " + getResolvedNamedEntity());
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void generateStore(BytecodeInstructionWriter w, TypeSignature storing) {
|
||
|
if (getResolvedNamedEntity() instanceof FieldModel) {
|
||
|
FieldModel f = (FieldModel)getResolvedNamedEntity();
|
||
|
if (!f.isStatic()) {
|
||
|
OuterThisExpression.generatePossibleOuterThis(w, (UserTypeModel)getMethodOrField().getOwner(), f.getOwner());
|
||
|
}
|
||
|
w.genStore(f.getFieldSignature());
|
||
|
} else if (getResolvedNamedEntity() instanceof LocalStorageModel) {
|
||
|
LocalStorageModel l = (LocalStorageModel)getResolvedNamedEntity();
|
||
|
// TODO: Handle upvalues!
|
||
|
w.genStoreLocalOrParam(l.getStorageType().getTypeSignature(), l.getIndex());
|
||
|
} else {
|
||
|
w.genError("TODO: generateStore for " + getResolvedNamedEntity());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public TypeModel resolveType(Node n) {
|
||
|
return super.resolveType(n); // TODO: Better support for interfaces
|
||
|
}
|
||
|
}
|