slcom/slangc/model/statements/ForStatement.sauce

140 lines
4.5 KiB
Plaintext
Raw Permalink Normal View History

package slangc.model.statements;
import slangc.api.BytecodeInstructionWriter;
import slangc.api.Reporter;
import slangc.bytecode.TypeSignature;
import slangc.model.ClauseModel;
import slangc.model.ExpressionModel;
import slangc.model.ExpressionOwner;
import slangc.model.InnerTypeScope;
import slangc.model.LocalVariableSlot;
import slangc.model.MemberModel;
import slangc.model.Named;
import slangc.model.StatementModel;
import slangc.model.StatementOwner;
import slangc.model.TypeModel;
import slangc.model.clauses.Expressions;
import slangc.model.clauses.ExpressionsOrVariables;
import slangc.model.clauses.Variables;
import slangc.parser.Branch;
import slangc.parser.Node;
public class ForStatement extends StatementModel implements StatementOwner, ExpressionOwner {
private ExpressionsOrVariables initials;
private Expressions conditions; // Note: should probably contain exactly 0 or 1 expressions!
private Expressions increments;
private StatementModel innerStatement;
public ForStatement(StatementOwner owner, Branch source) {
super(owner, source);
initials = (ExpressionsOrVariables) ClauseModel.construct(this, (Branch) source.getSubnode(2));
conditions = (Expressions) ClauseModel.construct(this, (Branch) source.getSubnode(4));
increments = (Expressions) ClauseModel.construct(this, (Branch) source.getSubnode(6));
innerStatement = StatementModel.construct(this, source.getSubnode(8));
}
@Override
public void dump(Reporter reporter, String indent, String incr) {
reporter.note("DUMP", indent + "> For:");
initials.dump(reporter, indent + incr, incr);
conditions.dump(reporter, indent + incr, incr);
increments.dump(reporter, indent + incr, incr);
innerStatement.dump(reporter, indent + incr, incr);
}
@Override
public int resolveExpressions() {
return initials.resolveExpressions()
+ conditions.resolveExpressions()
+ increments.resolveExpressions()
+ innerStatement.resolveExpressions();
}
//@Override
public TypeModel resolveType(Node subnode) {
return getOwner().resolveType(subnode);
}
//@Override
public MemberModel getMethodOrField() {
return getOwner().getMethodOrField();
}
//@Override
public InnerTypeScope getTypeScope() {
return getOwner().getTypeScope();
}
//@Override
public TypeModel getExpectedResult(ExpressionModel e) {
// TODO Auto-generated method stub
return null;
}
@Override
public Named lookupSimpleName(String name) {
if (initials instanceof Variables) {
Variables vars = (Variables) initials;
if (vars.hasVariable(name)) {
return vars.getVariable(name);
}
}
return super.lookupSimpleName(name);
}
public MethodModel[] lookupSimpleMethod(String name) {
// TODO: Better interface support
return super.lookupSimpleMethod(name);
}
@Override
public void innerGenerate(BytecodeInstructionWriter w) {
BytecodeInstructionWriter.Label beginLabel = w.newLabel("for_begin");
BytecodeInstructionWriter.Label endLabel = w.newLabel("for_end");
w.pushContinue(beginLabel);
w.pushBreak(endLabel);
if (initials instanceof Expressions) {
for (int i = 0; i < ((Expressions)initials).countExpressions(); i++) {
TypeSignature cr = ((Expressions)initials).getExpression(i).generate(w);
if (!cr.mappableEquals(TypeSignature.VOID)) {
w.genDrop(cr);
}
}
} else {
for (int i = 0; i < ((Variables)initials).countVariables(); i++) {
LocalVariableSlot s = ((Variables)initials).getVariable(i);
w.genDeclareLocal(s.getStorageType().getTypeSignature(), s.getIndex());
}
for (int i = 0; i < ((Variables)initials).countVariables(); i++) {
LocalVariableSlot s = ((Variables)initials).getVariable(i);
if (s.hasInitialiser()) {
s.getInitialiser().generate(w);
w.genStoreLocalOrParam(s.getStorageType().getTypeSignature(), s.getIndex());
}
}
}
w.labelHere(beginLabel);
if (conditions.countExpressions() != 0) {
TypeSignature xt = conditions.getExpression(0).generate(w);
w.genJump(BytecodeInstructionWriter.JumpOp.IFFALSE, endLabel);
}
getInnerStatement().generate(w);
for (int i = 0; i < increments.countExpressions(); i++) {
TypeSignature cr = increments.getExpression(i).generate(w);
if (!cr.mappableEquals(TypeSignature.VOID)) {
w.genDrop(cr);
}
}
w.genJump(BytecodeInstructionWriter.JumpOp.GOTO, beginLabel);
w.labelHere(endLabel);
w.popBreak(endLabel);
w.popContinue(beginLabel);
}
public StatementModel getInnerStatement() {
return innerStatement;
}
}