slcom/slangc/model/statements/VariableStatement.sauce

108 lines
3.2 KiB
Plaintext
Raw Normal View History

package slangc.model.statements;
import slang.data.List;
import slangc.api.BytecodeInstructionWriter;
import slangc.api.Reporter;
import slangc.bytecode.TypeSignature;
import slangc.model.InnerTypeScope;
import slangc.model.LocalVariableSlot;
import slangc.model.MemberModel;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.parser.Branch;
import slangc.parser.Node;
public class VariableStatement extends StatementModel implements StatementOwner {
private TypeModel type;
private List<LocalVariableSlot> slots = new List<LocalVariableSlot>();
public VariableStatement(StatementOwner owner, Branch source) {
super(owner, source);
type = owner.resolveType(source.getSubnode(1));
Branch l = (Branch) source.getSubnode(2);
for (int i = 0; i < l.countSubnodes(); i++) {
slots.append(new LocalVariableSlot(this, (Branch)l.getSubnode(i), type));
}
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> Variable statement:");
// do not recurse: type.dump(reporter, indent + incr, incr);
for (int i = 0; i < slots.count(); i++) {
slots.get(i).dump(reporter, indent + incr, incr);
}
}
@Override
public int resolveExpressions() {
int nresolved = 0;
for (int i = 0; i < slots.count(); i++) {
nresolved += slots.get(i).resolveExpressions();
}
return nresolved;
}
public boolean hasVariable(String name) {
for (int i = 0; i < slots.count(); i++) {
if (slots.get(i).getName().equals(name)) {
return true;
}
}
return false;
}
public LocalVariableSlot getVariable(String name) {
for (int i = 0; i < slots.count(); i++) {
if (slots.get(i).getName().equals(name)) {
return slots.get(i);
}
}
return null;
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
public MethodModel[] lookupSimpleMethod(String name) {
// TODO: Better interface support
return super.lookupSimpleMethod(name);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
@Override
public void innerGenerate(BytecodeInstructionWriter w) {
// The first pass declares each of the variables (this will reset them to default values)
for (int i = 0; i < slots.count(); i++) {
LocalVariableSlot s = slots.get(i);
w.genDeclareLocal(s.getStorageType().getTypeSignature(), s.getIndex());
}
// The second pass generates any initialisers
for (int i = 0; i < slots.count(); i++) {
LocalVariableSlot s = slots.get(i);
if (s.hasInitialiser()) {
TypeSignature storing = s.getInitialiser().generate(w);
if (!storing.mappableEquals(s.getInitialiser().getResult().getValueTypeWithNullType(s.getStorageType()).getTypeSignature())) {
w.genConvert(storing, s.getStorageType().getTypeSignature());
storing = s.getStorageType().getTypeSignature();
}
w.genStoreLocalOrParam(s.getStorageType().getTypeSignature(), s.getIndex());
}
}
}
}