mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Удаление ненужных ExprStatement, исправлен NPE при оптимизации IfStatement
This commit is contained in:
parent
f79679224a
commit
51c6439f2b
@ -66,7 +66,6 @@ public class ConstantFolding extends OptimizationVisitor<Void> implements Optimi
|
|||||||
try {
|
try {
|
||||||
return new ValueExpression(s.eval());
|
return new ValueExpression(s.eval());
|
||||||
} catch (OperationIsNotSupportedException op) {
|
} catch (OperationIsNotSupportedException op) {
|
||||||
System.err.println(s);
|
|
||||||
binaryExpressionFoldingCount--;
|
binaryExpressionFoldingCount--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,17 @@ package com.annimon.ownlang.parser.optimization;
|
|||||||
|
|
||||||
import com.annimon.ownlang.lib.Types;
|
import com.annimon.ownlang.lib.Types;
|
||||||
import com.annimon.ownlang.parser.ast.AssignmentExpression;
|
import com.annimon.ownlang.parser.ast.AssignmentExpression;
|
||||||
|
import com.annimon.ownlang.parser.ast.BlockStatement;
|
||||||
import com.annimon.ownlang.parser.ast.ExprStatement;
|
import com.annimon.ownlang.parser.ast.ExprStatement;
|
||||||
|
import com.annimon.ownlang.parser.ast.Expression;
|
||||||
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.Statement;
|
||||||
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.ValueExpression;
|
||||||
import com.annimon.ownlang.parser.ast.VariableExpression;
|
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.isConstantValue;
|
||||||
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 static com.annimon.ownlang.parser.visitors.VisitorUtils.isVariable;
|
||||||
@ -22,6 +26,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
|
|||||||
private int ifStatementEliminatedCount;
|
private int ifStatementEliminatedCount;
|
||||||
private int ternaryExpressionEliminatedCount;
|
private int ternaryExpressionEliminatedCount;
|
||||||
private int whileStatementEliminatedCount;
|
private int whileStatementEliminatedCount;
|
||||||
|
private int assignmentExpressionEliminatedCount;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node optimize(Node node) {
|
public Node optimize(Node node) {
|
||||||
@ -32,7 +37,7 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
|
|||||||
@Override
|
@Override
|
||||||
public int optimizationsCount() {
|
public int optimizationsCount() {
|
||||||
return ifStatementEliminatedCount + ternaryExpressionEliminatedCount
|
return ifStatementEliminatedCount + ternaryExpressionEliminatedCount
|
||||||
+ whileStatementEliminatedCount;
|
+ whileStatementEliminatedCount + assignmentExpressionEliminatedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,6 +53,9 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
|
|||||||
if (whileStatementEliminatedCount > 0) {
|
if (whileStatementEliminatedCount > 0) {
|
||||||
sb.append("\nEliminated WhileStatement: ").append(whileStatementEliminatedCount);
|
sb.append("\nEliminated WhileStatement: ").append(whileStatementEliminatedCount);
|
||||||
}
|
}
|
||||||
|
if (whileStatementEliminatedCount > 0) {
|
||||||
|
sb.append("\nEliminated AssignmentExpression: ").append(assignmentExpressionEliminatedCount);
|
||||||
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +112,37 @@ public class DeadCodeElimination extends OptimizationVisitor<Map<String, Variabl
|
|||||||
switch (info.value.type()) {
|
switch (info.value.type()) {
|
||||||
case Types.NUMBER:
|
case Types.NUMBER:
|
||||||
case Types.STRING:
|
case Types.STRING:
|
||||||
|
assignmentExpressionEliminatedCount++;
|
||||||
return new ValueExpression(info.value);
|
return new ValueExpression(info.value);
|
||||||
default:
|
default:
|
||||||
return super.visit(s, t);
|
return super.visit(s, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visit(BlockStatement s, Map<String, VariableInfo> t) {
|
||||||
|
final BlockStatement result = new BlockStatement();
|
||||||
|
boolean changed = false;
|
||||||
|
for (Statement statement : s.statements) {
|
||||||
|
final Node node = statement.accept(this, t);
|
||||||
|
if (node != statement) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if (node instanceof ExprStatement
|
||||||
|
&& isConstantValue( ((ExprStatement) node).expr )) {
|
||||||
|
changed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node instanceof Statement) {
|
||||||
|
result.add((Statement) node);
|
||||||
|
} else if (node instanceof Expression) {
|
||||||
|
result.add(new ExprStatement((Expression) node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return super.visit(s, t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,8 @@ 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, consumeStatement(ifStatement), consumeStatement(elseStatement));
|
return new IfStatement((Expression) expression, consumeStatement(ifStatement),
|
||||||
|
(elseStatement == null ? null : consumeStatement(elseStatement)) );
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user