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;
|
package com.annimon.ownlang.parser;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.Console;
|
||||||
import com.annimon.ownlang.parser.ast.Node;
|
import com.annimon.ownlang.parser.ast.Node;
|
||||||
import com.annimon.ownlang.parser.ast.Statement;
|
import com.annimon.ownlang.parser.ast.Statement;
|
||||||
import com.annimon.ownlang.parser.optimization.ConstantFolding;
|
import com.annimon.ownlang.parser.optimization.ConstantFolding;
|
||||||
@ -22,10 +23,20 @@ public final class Optimizer {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Node result = statement;
|
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++) {
|
for (int i = 0; i < level; i++) {
|
||||||
result = optimization.optimize(result);
|
result = optimization.optimize(result);
|
||||||
}
|
}
|
||||||
System.out.println(optimization.summaryInfo());
|
}
|
||||||
|
Console.println(optimization.summaryInfo());
|
||||||
return (Statement) result;
|
return (Statement) result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.annimon.ownlang.parser.ast;
|
package com.annimon.ownlang.parser.ast;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.lib.Value;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for expressions, which can be used as statements.
|
* Wrapper for expressions, which can be used as statements.
|
||||||
*
|
*
|
||||||
* @author aNNiMON
|
* @author aNNiMON
|
||||||
*/
|
*/
|
||||||
public final class ExprStatement implements Statement {
|
public final class ExprStatement implements Expression, Statement {
|
||||||
|
|
||||||
public final Expression expr;
|
public final Expression expr;
|
||||||
|
|
||||||
@ -18,6 +20,11 @@ public final class ExprStatement implements Statement {
|
|||||||
expr.eval();
|
expr.eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value eval() {
|
||||||
|
return expr.eval();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(Visitor visitor) {
|
public void accept(Visitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
package com.annimon.ownlang.parser.optimization;
|
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.ExprStatement;
|
||||||
import com.annimon.ownlang.parser.ast.IfStatement;
|
import com.annimon.ownlang.parser.ast.IfStatement;
|
||||||
import com.annimon.ownlang.parser.ast.Node;
|
import com.annimon.ownlang.parser.ast.Node;
|
||||||
import com.annimon.ownlang.parser.ast.TernaryExpression;
|
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 com.annimon.ownlang.parser.ast.WhileStatement;
|
||||||
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isValue;
|
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.isValueAsInt;
|
||||||
|
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isVariable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs dead code elimination.
|
* 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 ifStatementEliminatedCount;
|
||||||
private int ternaryExpressionEliminatedCount;
|
private int ternaryExpressionEliminatedCount;
|
||||||
@ -19,7 +25,8 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node optimize(Node node) {
|
public Node optimize(Node node) {
|
||||||
return node.accept(this, null);
|
final Map<String, VariableInfo> variableInfos = VariablesGrabber.getInfo(node);
|
||||||
|
return node.accept(this, variableInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,7 +52,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(IfStatement s, Void t) {
|
public Node visit(IfStatement s, Map<String, VariableInfo> t) {
|
||||||
if (isValue(s.expression)) {
|
if (isValue(s.expression)) {
|
||||||
ifStatementEliminatedCount++;
|
ifStatementEliminatedCount++;
|
||||||
// true statement
|
// true statement
|
||||||
@ -62,7 +69,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(TernaryExpression s, Void t) {
|
public Node visit(TernaryExpression s, Map<String, VariableInfo> t) {
|
||||||
if (isValue(s.condition)) {
|
if (isValue(s.condition)) {
|
||||||
ternaryExpressionEliminatedCount++;
|
ternaryExpressionEliminatedCount++;
|
||||||
if (s.condition.eval().asInt() != 0) {
|
if (s.condition.eval().asInt() != 0) {
|
||||||
@ -74,11 +81,32 @@ public class DeadCodeElimination extends OptimizationVisitor<Void> implements Op
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visit(WhileStatement s, Void t) {
|
public Node visit(WhileStatement s, Map<String, VariableInfo> t) {
|
||||||
if (isValueAsInt(s.condition, 0)) {
|
if (isValueAsInt(s.condition, 0)) {
|
||||||
whileStatementEliminatedCount++;
|
whileStatementEliminatedCount++;
|
||||||
return new ExprStatement(s.condition);
|
return new ExprStatement(s.condition);
|
||||||
}
|
}
|
||||||
return super.visit(s, t);
|
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) {
|
if (node != statement) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof Statement) {
|
||||||
result.add((Statement) node);
|
result.add((Statement) node);
|
||||||
|
} else if (node instanceof Expression) {
|
||||||
|
result.add(new ExprStatement((Expression) node));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
return result;
|
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 condition = s.condition.accept(this, t);
|
||||||
final Node statement = s.statement.accept(this, t);
|
final Node statement = s.statement.accept(this, t);
|
||||||
if (condition != s.condition || statement != s.statement) {
|
if (condition != s.condition || statement != s.statement) {
|
||||||
return new DoWhileStatement((Expression) condition, (Statement) statement);
|
return new DoWhileStatement((Expression) condition, consumeStatement(statement));
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -125,8 +129,8 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
final Node statement = s.statement.accept(this, t);
|
final Node statement = s.statement.accept(this, t);
|
||||||
if (initialization != s.initialization || termination != s.termination
|
if (initialization != s.initialization || termination != s.termination
|
||||||
|| increment != s.increment || statement != s.statement) {
|
|| increment != s.increment || statement != s.statement) {
|
||||||
return new ForStatement((Statement) initialization,
|
return new ForStatement(consumeStatement(initialization),
|
||||||
(Expression) termination, (Statement) increment, (Statement) statement);
|
(Expression) termination, consumeStatement(increment), consumeStatement(statement));
|
||||||
}
|
}
|
||||||
return s;
|
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 container = s.container.accept(this, t);
|
||||||
final Node body = s.body.accept(this, t);
|
final Node body = s.body.accept(this, t);
|
||||||
if (container != s.container || body != s.body) {
|
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;
|
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 container = s.container.accept(this, t);
|
||||||
final Node body = s.body.accept(this, t);
|
final Node body = s.body.accept(this, t);
|
||||||
if (container != s.container || body != s.body) {
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
@ -155,7 +159,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
public Node visit(FunctionDefineStatement s, T t) {
|
public Node visit(FunctionDefineStatement s, T t) {
|
||||||
final Node body = s.body.accept(this, t);
|
final Node body = s.body.accept(this, t);
|
||||||
if (body != s.body) {
|
if (body != s.body) {
|
||||||
return new FunctionDefineStatement(s.name, s.arguments, (Statement) body);
|
return new FunctionDefineStatement(s.name, s.arguments, consumeStatement(body));
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -203,7 +207,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
elseStatement = null;
|
elseStatement = null;
|
||||||
}
|
}
|
||||||
if (expression != s.expression || ifStatement != s.ifStatement || elseStatement != s.elseStatement) {
|
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;
|
return s;
|
||||||
}
|
}
|
||||||
@ -244,7 +248,7 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
final Node patternResult = pattern.result.accept(this, t);
|
final Node patternResult = pattern.result.accept(this, t);
|
||||||
if (patternResult != pattern.result) {
|
if (patternResult != pattern.result) {
|
||||||
changed = true;
|
changed = true;
|
||||||
pattern.result = (Statement) patternResult;
|
pattern.result = consumeStatement(patternResult);
|
||||||
}
|
}
|
||||||
patterns.add(pattern);
|
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 condition = s.condition.accept(this, t);
|
||||||
final Node statement = s.statement.accept(this, t);
|
final Node statement = s.statement.accept(this, t);
|
||||||
if (condition != s.condition || statement != s.statement) {
|
if (condition != s.condition || statement != s.statement) {
|
||||||
return new WhileStatement((Expression) condition, (Statement) statement);
|
return new WhileStatement((Expression) condition, consumeStatement(statement));
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -329,4 +333,11 @@ public abstract class OptimizationVisitor<T> implements ResultVisitor<Node, T> {
|
|||||||
}
|
}
|
||||||
return s;
|
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