2
2
3
3
import com .annimon .ownlang .lib .Types ;
4
4
import com .annimon .ownlang .lib .Value ;
5
- import com .annimon .ownlang .parser .Optimizer ;
6
- import com .annimon .ownlang .parser .ast .Argument ;
7
- import com .annimon .ownlang .parser .ast .AssignmentExpression ;
8
- import com .annimon .ownlang .parser .ast .DestructuringAssignmentStatement ;
9
- import com .annimon .ownlang .parser .ast .FunctionDefineStatement ;
10
- import com .annimon .ownlang .parser .ast .MatchExpression ;
11
5
import com .annimon .ownlang .parser .ast .Node ;
12
- import com .annimon .ownlang .parser .ast .Statement ;
13
6
import com .annimon .ownlang .parser .ast .ValueExpression ;
14
7
import com .annimon .ownlang .parser .ast .VariableExpression ;
15
- import static com .annimon .ownlang .parser .visitors .VisitorUtils .isValue ;
16
- import static com .annimon .ownlang .parser .visitors .VisitorUtils .isVariable ;
17
8
import java .util .HashMap ;
18
9
import java .util .Map ;
19
10
20
11
/**
21
12
* Performs constant propagation.
22
13
*/
23
- public class ConstantPropagation implements Optimizer . Info {
14
+ public class ConstantPropagation extends OptimizationVisitor < Map < String , Value >> implements Optimizable {
24
15
25
16
private final Map <String , Integer > propagatedVariables ;
26
17
@@ -29,27 +20,10 @@ public ConstantPropagation() {
29
20
}
30
21
31
22
@ Override
32
- public int optimizationsCount () {
33
- return propagatedVariables .size ();
34
- }
35
-
36
- @ Override
37
- public String summaryInfo () {
38
- if (optimizationsCount () == 0 ) return "" ;
39
- final StringBuilder sb = new StringBuilder ();
40
- if (propagatedVariables .size () > 0 ) {
41
- sb .append ("\n Constant propagations: " ).append (propagatedVariables .size ());
42
- for (Map .Entry <String , Integer > e : propagatedVariables .entrySet ()) {
43
- sb .append ("\n " ).append (e .getKey ()).append (": " ).append (e .getValue ());
44
- }
45
- }
46
- return sb .toString ();
47
- }
48
-
49
- public Node visit (Statement s ) {
23
+ public Node optimize (Node node ) {
50
24
final Map <String , VariableInfo > variables = new HashMap <>();
51
25
// Find variables
52
- s .accept (new VariablesGrabber (), variables );
26
+ node .accept (new VariablesGrabber (), variables );
53
27
// Filter only string/number values with 1 modification
54
28
final Map <String , Value > candidates = new HashMap <>();
55
29
for (Map .Entry <String , VariableInfo > e : variables .entrySet ()) {
@@ -64,87 +38,37 @@ public Node visit(Statement s) {
64
38
}
65
39
}
66
40
// Replace VariableExpression with ValueExpression
67
- return s .accept (new VariablesPropagator () , candidates );
41
+ return node .accept (this , candidates );
68
42
}
69
43
70
- private class VariablesGrabber extends OptimizationVisitor <Map <String , VariableInfo >> {
71
-
72
- @ Override
73
- public Node visit (AssignmentExpression s , Map <String , VariableInfo > t ) {
74
- if (!isVariable ((Node )s .target )) {
75
- return super .visit (s , t );
76
- }
77
-
78
- final String variableName = ((VariableExpression ) s .target ).name ;
79
- final VariableInfo var = variableInfo (t , variableName );
80
-
81
- if (s .operation == null && isValue (s .expression )) {
82
- var .value = ((ValueExpression ) s .expression ).value ;
83
- }
84
- t .put (variableName , var );
85
- return super .visit (s , t );
86
- }
87
-
88
- @ Override
89
- public Node visit (DestructuringAssignmentStatement s , Map <String , VariableInfo > t ) {
90
- for (String variableName : s .variables ) {
91
- if (variableName == null ) continue ;
92
- t .put (variableName , variableInfo (t , variableName ));
93
- }
94
- return super .visit (s , t );
95
- }
96
-
97
- @ Override
98
- public Node visit (FunctionDefineStatement s , Map <String , VariableInfo > t ) {
99
- for (Argument argument : s .arguments ) {
100
- final String variableName = argument .getName ();
101
- t .put (variableName , variableInfo (t , variableName ));
102
- }
103
- return super .visit (s , t );
104
- }
105
-
106
- @ Override
107
- public Node visit (MatchExpression s , Map <String , VariableInfo > t ) {
108
- // no visit match expression
109
- return s ;
110
- }
111
-
112
- private VariableInfo variableInfo (Map <String , VariableInfo > t , final String variableName ) {
113
- final VariableInfo var ;
114
- if (t .containsKey (variableName )) {
115
- var = t .get (variableName );
116
- var .modifications ++;
117
- } else {
118
- var = new VariableInfo ();
119
- var .modifications = 1 ;
120
- }
121
- return var ;
122
- }
44
+ @ Override
45
+ public int optimizationsCount () {
46
+ return propagatedVariables .size ();
123
47
}
124
48
125
- private class VariablesPropagator extends OptimizationVisitor <Map <String , Value >> {
126
-
127
- @ Override
128
- public Node visit (VariableExpression s , Map <String , Value > t ) {
129
- if (t .containsKey (s .name )) {
130
- if (!propagatedVariables .containsKey (s .name )) {
131
- propagatedVariables .put (s .name , 1 );
132
- } else {
133
- propagatedVariables .put (s .name , 1 + propagatedVariables .get (s .name ));
134
- }
135
- return new ValueExpression (t .get (s .name ));
49
+ @ Override
50
+ public String summaryInfo () {
51
+ if (optimizationsCount () == 0 ) return "" ;
52
+ final StringBuilder sb = new StringBuilder ();
53
+ if (propagatedVariables .size () > 0 ) {
54
+ sb .append ("\n Constant propagations: " ).append (propagatedVariables .size ());
55
+ for (Map .Entry <String , Integer > e : propagatedVariables .entrySet ()) {
56
+ sb .append ("\n " ).append (e .getKey ()).append (": " ).append (e .getValue ());
136
57
}
137
- return super .visit (s , t );
138
58
}
59
+ return sb .toString ();
139
60
}
140
61
141
- private static class VariableInfo {
142
- Value value ;
143
- int modifications ;
144
-
145
- @ Override
146
- public String toString () {
147
- return (value == null ? "?" : value ) + " (" + modifications + " mods)" ;
62
+ @ Override
63
+ public Node visit (VariableExpression s , Map <String , Value > t ) {
64
+ if (t .containsKey (s .name )) {
65
+ if (!propagatedVariables .containsKey (s .name )) {
66
+ propagatedVariables .put (s .name , 1 );
67
+ } else {
68
+ propagatedVariables .put (s .name , 1 + propagatedVariables .get (s .name ));
69
+ }
70
+ return new ValueExpression (t .get (s .name ));
148
71
}
72
+ return super .visit (s , t );
149
73
}
150
74
}
0 commit comments