22
33import com .annimon .ownlang .lib .Types ;
44import 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 ;
115import com .annimon .ownlang .parser .ast .Node ;
12- import com .annimon .ownlang .parser .ast .Statement ;
136import com .annimon .ownlang .parser .ast .ValueExpression ;
147import 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 ;
178import java .util .HashMap ;
189import java .util .Map ;
1910
2011/**
2112 * Performs constant propagation.
2213 */
23- public class ConstantPropagation implements Optimizer . Info {
14+ public class ConstantPropagation extends OptimizationVisitor < Map < String , Value >> implements Optimizable {
2415
2516 private final Map <String , Integer > propagatedVariables ;
2617
@@ -29,27 +20,10 @@ public ConstantPropagation() {
2920 }
3021
3122 @ 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 ) {
5024 final Map <String , VariableInfo > variables = new HashMap <>();
5125 // Find variables
52- s .accept (new VariablesGrabber (), variables );
26+ node .accept (new VariablesGrabber (), variables );
5327 // Filter only string/number values with 1 modification
5428 final Map <String , Value > candidates = new HashMap <>();
5529 for (Map .Entry <String , VariableInfo > e : variables .entrySet ()) {
@@ -64,87 +38,37 @@ public Node visit(Statement s) {
6438 }
6539 }
6640 // Replace VariableExpression with ValueExpression
67- return s .accept (new VariablesPropagator () , candidates );
41+ return node .accept (this , candidates );
6842 }
6943
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 ();
12347 }
12448
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 ());
13657 }
137- return super .visit (s , t );
13858 }
59+ return sb .toString ();
13960 }
14061
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 ));
14871 }
72+ return super .visit (s , t );
14973 }
15074}
0 commit comments