mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Удаление неиспользуемых переменных, исправлена возможная ошибка приведения типа
This commit is contained in:
parent
46349bdd36
commit
1b9c5187f6
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user