140 lines
4.5 KiB
Plaintext
140 lines
4.5 KiB
Plaintext
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;
|
|
}
|
|
}
|