Skip to content

Commit 50c7036

Browse files
committed
Optimize constant condition cases in ifelse()
1 parent f696e06 commit 50c7036

File tree

1 file changed

+46
-3
lines changed

1 file changed

+46
-3
lines changed

src/main/java/com/laytonsmith/core/functions/ControlFlow.java

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,52 @@ public Set<Optimizable.OptimizationOption> optimizationOptions() {
469469
@Override
470470
public ParseTree optimizeDynamic(Target t, Environment env,
471471
Set<Class<? extends Environment.EnvironmentImpl>> envs,
472-
List<ParseTree> children, FileOptions fileOptions)
473-
throws ConfigCompileException, ConfigRuntimeException {
474-
// TODO: Redo this optimization.
472+
List<ParseTree> children, FileOptions fileOptions) throws ConfigCompileException {
473+
474+
// Check for too few arguments.
475+
if(children.size() < 2) {
476+
throw new ConfigCompileException("Too few arguments passed to " + this.getName() + "()", t);
477+
}
478+
479+
// Optimize per condition code pair for constant conditions.
480+
boolean foundDynamicCond = false;
481+
for(int i = 0; i < children.size(); i += 2) {
482+
ParseTree condNode = children.get(i);
483+
if(condNode.isConst()) {
484+
if(ArgumentValidation.getBooleanish(condNode.getData(), t)) {
485+
486+
// Optimize to true condition code block if no dynamic condition was present before this.
487+
if(!foundDynamicCond) {
488+
ParseTree codeNode = children.get(i + 1);
489+
return codeNode;
490+
}
491+
492+
// Remove condition code block pairs and else code block after this static true condition.
493+
for(int j = children.size() - 1; j >= i + 2; j--) {
494+
children.remove(j);
495+
}
496+
return null;
497+
} else {
498+
499+
// Remove this constant false condition and its code block.
500+
children.remove(i + 1);
501+
children.remove(i);
502+
i -= 2; // Compensate for next loop increment.
503+
}
504+
} else {
505+
foundDynamicCond = true;
506+
}
507+
}
508+
509+
// Remove this ifelse() if no children are left.
510+
if(children.size() == 0) {
511+
return Optimizable.REMOVE_ME;
512+
}
513+
514+
// Optimize this ifelse() to its else code block if only that code block is remaining.
515+
if(children.size() == 1) {
516+
return children.get(0);
517+
}
475518
return null;
476519
}
477520

0 commit comments

Comments
 (0)