Skip to content

Commit 6dbc045

Browse files
committed
Перегруженные операторы теперь не оптимизируются
1 parent 726e964 commit 6dbc045

File tree

4 files changed

+113
-33
lines changed

4 files changed

+113
-33
lines changed

src/com/annimon/ownlang/parser/visitors/ConstantFolding.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,28 @@
44
import com.annimon.ownlang.parser.Optimizer;
55
import com.annimon.ownlang.parser.ast.BinaryExpression;
66
import com.annimon.ownlang.parser.ast.ConditionalExpression;
7+
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
78
import com.annimon.ownlang.parser.ast.Node;
89
import com.annimon.ownlang.parser.ast.UnaryExpression;
910
import com.annimon.ownlang.parser.ast.ValueExpression;
11+
import java.util.HashSet;
12+
import java.util.Set;
1013

1114
/**
1215
* Performs constant folding optimization.
1316
*/
1417
public class ConstantFolding extends OptimizationVisitor<Void> implements Optimizer.Info {
1518

19+
private static final Set<String> OPERATORS = VisitorUtils.operators();
20+
1621
private int binaryExpressionFoldingCount;
1722
private int conditionalExpressionFoldingCount;
1823
private int unaryExpressionFoldingCount;
1924

25+
private final Set<String> overloadedOperators;
26+
2027
public ConstantFolding() {
21-
binaryExpressionFoldingCount = 0;
22-
conditionalExpressionFoldingCount = 0;
23-
unaryExpressionFoldingCount = 0;
28+
overloadedOperators = new HashSet<>();
2429
}
2530

2631
@Override
@@ -48,11 +53,15 @@ public String summaryInfo() {
4853

4954
@Override
5055
public Node visit(BinaryExpression s, Void t) {
56+
if (overloadedOperators.contains(s.operation.toString())) {
57+
return super.visit(s, t);
58+
}
5159
if ( (s.expr1 instanceof ValueExpression) && (s.expr2 instanceof ValueExpression) ) {
5260
binaryExpressionFoldingCount++;
5361
try {
5462
return new ValueExpression(s.eval());
5563
} catch (OperationIsNotSupportedException op) {
64+
System.err.println(s);
5665
binaryExpressionFoldingCount--;
5766
}
5867
}
@@ -61,6 +70,9 @@ public Node visit(BinaryExpression s, Void t) {
6170

6271
@Override
6372
public Node visit(ConditionalExpression s, Void t) {
73+
if (overloadedOperators.contains(s.operation.getName())) {
74+
return super.visit(s, t);
75+
}
6476
if ( (s.expr1 instanceof ValueExpression) && (s.expr2 instanceof ValueExpression) ) {
6577
conditionalExpressionFoldingCount++;
6678
try {
@@ -74,6 +86,9 @@ public Node visit(ConditionalExpression s, Void t) {
7486

7587
@Override
7688
public Node visit(UnaryExpression s, Void t) {
89+
if (overloadedOperators.contains(s.operation.toString())) {
90+
return super.visit(s, t);
91+
}
7792
if (s.expr1 instanceof ValueExpression) {
7893
unaryExpressionFoldingCount++;
7994
try {
@@ -84,4 +99,12 @@ public Node visit(UnaryExpression s, Void t) {
8499
}
85100
return super.visit(s, t);
86101
}
102+
103+
@Override
104+
public Node visit(FunctionDefineStatement s, Void t) {
105+
if (OPERATORS.contains(s.name)) {
106+
overloadedOperators.add(s.name);
107+
}
108+
return super.visit(s, t);
109+
}
87110
}

src/com/annimon/ownlang/parser/visitors/ExpressionSimplification.java

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
package com.annimon.ownlang.parser.visitors;
22

3-
import com.annimon.ownlang.lib.NumberValue;
4-
import com.annimon.ownlang.lib.Types;
5-
import com.annimon.ownlang.lib.Value;
63
import com.annimon.ownlang.parser.Optimizer;
74
import com.annimon.ownlang.parser.ast.BinaryExpression;
85
import com.annimon.ownlang.parser.ast.ConditionalExpression;
6+
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
97
import com.annimon.ownlang.parser.ast.Node;
108
import com.annimon.ownlang.parser.ast.UnaryExpression;
119
import com.annimon.ownlang.parser.ast.ValueExpression;
12-
import com.annimon.ownlang.parser.ast.VariableExpression;
10+
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isIntegerValue;
11+
import static com.annimon.ownlang.parser.visitors.VisitorUtils.isSameVariables;
12+
import java.util.HashSet;
13+
import java.util.Set;
1314

1415
/**
1516
* Performs expression simplification.
1617
*/
1718
public class ExpressionSimplification extends OptimizationVisitor<Void> implements Optimizer.Info {
1819

20+
private static final Set<String> OPERATORS = VisitorUtils.operators();
21+
1922
private int simplificationsCount;
2023

24+
private final Set<String> overloadedOperators;
25+
2126
public ExpressionSimplification() {
2227
simplificationsCount = 0;
28+
overloadedOperators = new HashSet<>();
2329
}
2430

2531
@Override
@@ -39,6 +45,9 @@ public String summaryInfo() {
3945

4046
@Override
4147
public Node visit(BinaryExpression s, Void t) {
48+
if (overloadedOperators.contains(s.operation.toString())) {
49+
return super.visit(s, t);
50+
}
4251
// operations with 0
4352
final boolean expr1IsZero = isIntegerValue(s.expr1, 0);
4453
if (expr1IsZero || isIntegerValue(s.expr2, 0)) {
@@ -108,6 +117,9 @@ public Node visit(BinaryExpression s, Void t) {
108117

109118
@Override
110119
public Node visit(ConditionalExpression s, Void t) {
120+
if (overloadedOperators.contains(s.operation.getName())) {
121+
return super.visit(s, t);
122+
}
111123
if (isIntegerValue(s.expr1, 0) && s.operation == ConditionalExpression.Operator.AND) {
112124
// 0 && x2 to 0
113125
simplificationsCount++;
@@ -121,26 +133,11 @@ public Node visit(ConditionalExpression s, Void t) {
121133
return super.visit(s, t);
122134
}
123135

124-
125-
private boolean isIntegerValue(Node node, int valueToCheck) {
126-
if (!(node instanceof ValueExpression)) return false;
127-
128-
final Value value = ((ValueExpression) node).value;
129-
if (value.type() != Types.NUMBER) return false;
130-
131-
final Number number = ((NumberValue) value).raw();
132-
if ( (number instanceof Integer) || (number instanceof Short) || (number instanceof Byte)) {
133-
return number.intValue() == valueToCheck;
134-
}
135-
return false;
136-
}
137-
138-
private boolean isSameVariables(Node n1, Node n2) {
139-
if ( (n1 instanceof VariableExpression) && (n2 instanceof VariableExpression) ) {
140-
final VariableExpression v1 = (VariableExpression) n1;
141-
final VariableExpression v2 = (VariableExpression) n2;
142-
return v1.name.equals(v2.name);
136+
@Override
137+
public Node visit(FunctionDefineStatement s, Void t) {
138+
if (OPERATORS.contains(s.name)) {
139+
overloadedOperators.add(s.name);
143140
}
144-
return false;
141+
return super.visit(s, t);
145142
}
146143
}

src/com/annimon/ownlang/parser/visitors/LintVisitor.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,14 @@
22

33
import com.annimon.ownlang.parser.ast.IncludeStatement;
44
import com.annimon.ownlang.parser.ast.Statement;
5-
import com.annimon.ownlang.parser.ast.ValueExpression;
65
import com.annimon.ownlang.parser.ast.Visitor;
7-
import java.io.IOException;
86

97
public abstract class LintVisitor extends AbstractVisitor {
108

119
protected void applyVisitor(IncludeStatement s, Visitor visitor) {
12-
if (!(s.expression instanceof ValueExpression)) return;
13-
try {
14-
final Statement program = s.loadProgram(s.expression.eval().asString());
10+
final Statement program = VisitorUtils.includeProgram(s);
11+
if (program != null) {
1512
program.accept(visitor);
16-
} catch (IOException ex) {
1713
}
1814
}
1915
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.annimon.ownlang.parser.visitors;
2+
3+
import com.annimon.ownlang.lib.NumberValue;
4+
import com.annimon.ownlang.lib.Types;
5+
import com.annimon.ownlang.lib.Value;
6+
import com.annimon.ownlang.parser.ast.BinaryExpression;
7+
import com.annimon.ownlang.parser.ast.ConditionalExpression;
8+
import com.annimon.ownlang.parser.ast.IncludeStatement;
9+
import com.annimon.ownlang.parser.ast.Node;
10+
import com.annimon.ownlang.parser.ast.Statement;
11+
import com.annimon.ownlang.parser.ast.UnaryExpression;
12+
import com.annimon.ownlang.parser.ast.ValueExpression;
13+
import com.annimon.ownlang.parser.ast.VariableExpression;
14+
import java.io.IOException;
15+
import java.util.HashSet;
16+
import java.util.Set;
17+
18+
public final class VisitorUtils {
19+
20+
public static Statement includeProgram(IncludeStatement s) {
21+
if (!(s.expression instanceof ValueExpression)) return null;
22+
try {
23+
return s.loadProgram(s.expression.eval().asString());
24+
} catch (IOException ex) {
25+
return null;
26+
}
27+
}
28+
29+
public static boolean isIntegerValue(Node node, int valueToCheck) {
30+
if (!(node instanceof ValueExpression)) return false;
31+
32+
final Value value = ((ValueExpression) node).value;
33+
if (value.type() != Types.NUMBER) return false;
34+
35+
final Number number = ((NumberValue) value).raw();
36+
if ( (number instanceof Integer) || (number instanceof Short) || (number instanceof Byte)) {
37+
return number.intValue() == valueToCheck;
38+
}
39+
return false;
40+
}
41+
42+
public static boolean isSameVariables(Node n1, Node n2) {
43+
if ( (n1 instanceof VariableExpression) && (n2 instanceof VariableExpression) ) {
44+
final VariableExpression v1 = (VariableExpression) n1;
45+
final VariableExpression v2 = (VariableExpression) n2;
46+
return v1.name.equals(v2.name);
47+
}
48+
return false;
49+
}
50+
51+
public static Set<String> operators() {
52+
final Set<String> operators = new HashSet<>();
53+
for (BinaryExpression.Operator op : BinaryExpression.Operator.values()) {
54+
operators.add(op.toString());
55+
}
56+
for (UnaryExpression.Operator op : UnaryExpression.Operator.values()) {
57+
operators.add(op.toString());
58+
}
59+
for (ConditionalExpression.Operator op : ConditionalExpression.Operator.values()) {
60+
operators.add(op.getName());
61+
}
62+
return operators;
63+
}
64+
}

0 commit comments

Comments
 (0)