Удаление неиспользуемых переменных, исправлена возможная ошибка приведения типа

This commit is contained in:
Victor 2016-06-26 12:57:20 +03:00
parent 46349bdd36
commit 1b9c5187f6
4 changed files with 76 additions and 19 deletions

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser;
import com.annimon.ownlang.Console;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.Statement;
import com.annimon.ownlang.parser.optimization.ConstantFolding;
@ -22,10 +23,20 @@ public final class Optimizer {
});
Node result = statement;
if (true || level >= 9) {
int iteration = 0, lastModifications = 0;
do {
lastModifications = optimization.optimizationsCount();
result = optimization.optimize(result);
iteration++;
} while (lastModifications != optimization.optimizationsCount());
Console.print("Performs " + iteration + " optimization iterations");
} else {
for (int i = 0; i < level; i++) {
result = optimization.optimize(result);
}
System.out.println(optimization.summaryInfo());
}
Console.println(optimization.summaryInfo());
return (Statement) result;
}
}

View File

@ -1,11 +1,13 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.lib.Value;
/**
* Wrapper for expressions, which can be used as statements.
*
* @author aNNiMON
*/
public final class ExprStatement implements Statement {
public final class ExprStatement implements Expression, Statement {
public final Expression expr;
@ -18,6 +20,11 @@ public final class ExprStatement implements Statement {
expr.eval();
}
@Override
public Value eval() {
return expr.eval();
}
@Override
public void accept(Visitor visitor) {
visitor.visit(this);

View File

@ -1,17 +1,23 @@
package com.annimon.ownlang.parser.optimization;
import com.annimon.ownlang.lib.Types;
import com.annimon.ownlang.parser.ast.AssignmentExpression;
import com.annimon.ownlang.parser.ast.ExprStatement;
import com.annimon.ownlang.parser.ast.IfStatement;
import com.annimon.ownlang.parser.ast.Node;
import com.annimon.ownlang.parser.ast.TernaryExpression;
import com.annimon.ownlang.parser.ast.ValueExpression;
import com.annimon.ownlang.parser.ast.VariableExpression;
import com.annimon.ownlang.parser.ast.WhileStatement;
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue;
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValueAsInt;
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isVariable;
import java.util.Map;
/**
* Performs dead code elimination.
*/
public class DeadCodeElimination extends OptimizationVisitor<Void> implements Optimizable {
public class DeadCodeElimination extends OptimizationVisitor<Map<String, VariableInfo>> implements Optimizable {
private int ifStatementEliminatedCount;
private int ternaryExpressionEliminatedCount;
@ -19,7 +25,8 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
@Override
public Node optimize(Node node) {
return node.accept(this, null);
final Map<String, VariableInfo> variableInfos = VariablesGrabber.getInfo(node);
return node.accept(this, variableInfos);
}
@Override
@ -45,7 +52,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
}
@Override
public Node visit(IfStatement s, Void t) {
public Node visit(IfStatement s, Map<String, VariableInfo> t) {
if (isValue(s.expression)) {
ifStatementEliminatedCount++;
// true statement
@ -62,7 +69,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
}
@Override
public Node visit(TernaryExpression s, Void t) {
public Node visit(TernaryExpression s, Map<String, VariableInfo> t) {
if (isValue(s.condition)) {
ternaryExpressionEliminatedCount++;
if (s.condition.eval().asInt() != 0) {
@ -74,11 +81,32 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
}
@Override
public Node visit(WhileStatement s, Void t) {
public Node visit(WhileStatement s, Map<String, VariableInfo> t) {
if (isValueAsInt(s.condition, 0)) {
whileStatementEliminatedCount++;
return new ExprStatement(s.condition);
}
return super.visit(s, t);
}
@Override
public Node visit(AssignmentExpression s, Map<String, VariableInfo> t) {
if (!isVariable((Node)s.target)) return super.visit(s, t);
final String variableName = ((VariableExpression) s.target).name;
if (!t.containsKey(variableName)) return super.visit(s, t);
final VariableInfo info = t.get(((VariableExpression) s.target).name);
if (info.modifications != 1 || info.value == null) {
return super.visit(s, t);
}
switch (info.value.type()) {
case Types.NUMBER:
case Types.STRING:
return new ValueExpression(info.value);
default:
return super.visit(s, t);
}
}
}

View File

@ -53,7 +53,11 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
if (node != statement) {
changed = true;
}
if (node instanceof Statement) {
result.add((Statement) node);
} else if (node instanceof Expression) {
result.add(new ExprStatement((Expression) node));
}
}
if (changed) {
return result;
@ -103,7 +107,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node condition = s.condition.accept(this, t);
final Node statement = s.statement.accept(this, t);
if (condition != s.condition || statement != s.statement) {
return new DoWhileStatement((Expression) condition, (Statement) statement);
return new DoWhileStatement((Expression) condition, consumeStatement(statement));
}
return s;
}
@ -125,8 +129,8 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node statement = s.statement.accept(this, t);
if (initialization != s.initialization || termination != s.termination
|| increment != s.increment || statement != s.statement) {
return new ForStatement((Statement) initialization,
(Expression) termination, (Statement) increment, (Statement) statement);
return new ForStatement(consumeStatement(initialization),
(Expression) termination, consumeStatement(increment), consumeStatement(statement));
}
return s;
}
@ -136,7 +140,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node container = s.container.accept(this, t);
final Node body = s.body.accept(this, t);
if (container != s.container || body != s.body) {
return new ForeachArrayStatement(s.variable, (Expression) container, (Statement) body);
return new ForeachArrayStatement(s.variable, (Expression) container, consumeStatement(body));
}
return s;
}
@ -146,7 +150,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node container = s.container.accept(this, t);
final Node body = s.body.accept(this, t);
if (container != s.container || body != s.body) {
return new ForeachMapStatement(s.key, s.value, (Expression) container, (Statement) body);
return new ForeachMapStatement(s.key, s.value, (Expression) container, consumeStatement(body));
}
return s;
}
@ -155,7 +159,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
public Node visit(FunctionDefineStatement s, T t) {
final Node body = s.body.accept(this, t);
if (body != s.body) {
return new FunctionDefineStatement(s.name, s.arguments, (Statement) body);
return new FunctionDefineStatement(s.name, s.arguments, consumeStatement(body));
}
return s;
}
@ -203,7 +207,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
elseStatement = null;
}
if (expression != s.expression || ifStatement != s.ifStatement || elseStatement != s.elseStatement) {
return new IfStatement((Expression) expression, (Statement) ifStatement, (Statement) elseStatement);
return new IfStatement((Expression) expression, consumeStatement(ifStatement), consumeStatement(elseStatement));
}
return s;
}
@ -244,7 +248,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node patternResult = pattern.result.accept(this, t);
if (patternResult != pattern.result) {
changed = true;
pattern.result = (Statement) patternResult;
pattern.result = consumeStatement(patternResult);
}
patterns.add(pattern);
}
@ -316,7 +320,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
final Node condition = s.condition.accept(this, t);
final Node statement = s.statement.accept(this, t);
if (condition != s.condition || statement != s.statement) {
return new WhileStatement((Expression) condition, (Statement) statement);
return new WhileStatement((Expression) condition, consumeStatement(statement));
}
return s;
}
@ -329,4 +333,11 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
}
return s;
}
protected Statement consumeStatement(Node node) {
if (node instanceof Statement) {
return (Statement) node;
}
return new ExprStatement((Expression) node);
}
}