Improved the expression parser's optimizer.

Added optimizers for Conditional, For, SimpleFor and While.
Improved the Sequence optimizer.
Removed the optimizer TODOs from Break and Return.
This commit is contained in:
TomyLobo 2011-11-24 20:51:11 +01:00
parent 05b427316d
commit c1e151ac19
7 changed files with 55 additions and 9 deletions

View File

@ -47,6 +47,4 @@ public class Break extends Node {
public String toString() { public String toString() {
return doContinue ? "continue" : "break"; return doContinue ? "continue" : "break";
} }
//TODO: optimizer
} }

View File

@ -42,7 +42,7 @@ public class Conditional extends Node {
if (condition.getValue() > 0.0) { if (condition.getValue() > 0.0) {
return truePart.getValue(); return truePart.getValue();
} else { } else {
return falsePart == null ? 0 : falsePart.getValue(); return falsePart == null ? 0.0 : falsePart.getValue();
} }
} }
@ -62,5 +62,18 @@ public class Conditional extends Node {
} }
} }
//TODO: optimizer @Override
public RValue optimize() throws EvaluationException {
final RValue newCondition = condition.optimize();
if (newCondition instanceof Constant) {
if (newCondition.getValue() > 0) {
return truePart.optimize();
} else {
return falsePart == null ? new Constant(getPosition(), 0.0) : falsePart.optimize();
}
}
return new Conditional(getPosition(), newCondition, truePart.optimize(), falsePart.optimize());
}
} }

View File

@ -74,5 +74,17 @@ public class For extends Node {
return "for (" + init + "; " + condition + "; " + increment + ") { " + body + " }"; return "for (" + init + "; " + condition + "; " + increment + ") { " + body + " }";
} }
//TODO: optimizer @Override
public RValue optimize() throws EvaluationException {
final RValue newCondition = condition.optimize();
if (newCondition instanceof Constant && newCondition.getValue() <= 0) {
// If the condition is always false, the loop can be flattened.
// So we run the init part and then return 0.0.
return new Sequence(getPosition(), init, new Constant(getPosition(), 0.0)).optimize();
}
//return new Sequence(getPosition(), init.optimize(), new While(getPosition(), condition, new Sequence(getPosition(), body, increment), false)).optimize();
return new For(getPosition(), init.optimize(), newCondition, increment.optimize(), body.optimize());
}
} }

View File

@ -47,6 +47,4 @@ public class Return extends Node {
public String toString() { public String toString() {
return "return " + value; return "return " + value;
} }
//TODO: optimizer
} }

View File

@ -88,6 +88,10 @@ public class Sequence extends Node {
newSequence.add(droppedLast); newSequence.add(droppedLast);
} }
if (newSequence.size() == 1) {
return newSequence.get(0);
}
return new Sequence(getPosition(), newSequence.toArray(new RValue[newSequence.size()])); return new Sequence(getPosition(), newSequence.toArray(new RValue[newSequence.size()]));
} }
} }

View File

@ -78,5 +78,10 @@ public class SimpleFor extends Node {
return "for (" + counter + " = " + first + ", " + last + ") { " + body + " }"; return "for (" + counter + " = " + first + ", " + last + ") { " + body + " }";
} }
//TODO: optimizer @Override
public RValue optimize() throws EvaluationException {
// TODO: unroll small loops into Sequences
return new SimpleFor(getPosition(), (LValue) counter.optimize(), first.optimize(), last.optimize(), body.optimize());
}
} }

View File

@ -95,5 +95,21 @@ public class While extends Node {
} }
} }
//TODO: optimizer @Override
public RValue optimize() throws EvaluationException {
final RValue newCondition = condition.optimize();
if (newCondition instanceof Constant && newCondition.getValue() <= 0) {
// If the condition is always false, the loop can be flattened.
if (footChecked) {
// Foot-checked loops run at least once.
return body.optimize();
} else {
// Loops that never run always return 0.0.
return new Constant(getPosition(), 0.0);
}
}
return new While(getPosition(), newCondition, body.optimize(), footChecked);
}
} }