32 Fold constants." |
32 Fold constants." |
33 |
33 |
34 ^ self receiver:r selector:s fold:true |
34 ^ self receiver:r selector:s fold:true |
35 ! |
35 ! |
36 |
36 |
37 receiver:r selector:s fold:folding |
37 receiver:r selector:selectorString fold:folding |
38 "return a new UnaryNode for sending selector s to receiver r. |
38 "return a new UnaryNode for sending selector selectorString to receiver r. |
39 If folding is true, fold constant expressions." |
39 If folding is true, fold constant expressions." |
40 |
40 |
41 |result recVal sym| |
41 |result recVal selector| |
42 |
42 |
43 " |
43 " |
44 The constant folding code can usually not optimize things - this may change |
44 The constant folding code can usually not optimize things - this may change |
45 when some kind of constant declaration is added to smalltalk. |
45 when some kind of constant declaration is added to smalltalk. |
46 " |
46 " |
47 folding ifTrue:[ |
47 folding ifTrue:[ |
48 "do constant folding ..." |
48 "do constant folding ..." |
49 r isConstant ifTrue:[ |
49 r isConstant ifTrue:[ |
50 "check if we can do it ..." |
50 "check if we can do it ..." |
51 recVal := r evaluate. |
51 recVal := r evaluate. |
52 s knownAsSymbol ifTrue:[ |
52 selectorString knownAsSymbol ifTrue:[ |
53 (recVal respondsTo:sym) ifTrue:[ |
53 selector := selectorString asSymbol. |
|
54 (recVal respondsTo:selector) ifTrue:[ |
54 " |
55 " |
55 we could do much more here - but then, we need a dependency from |
56 we could do much more here - but then, we need a dependency from |
56 the folded selectors method to the method we generate code for ... |
57 the folded selectors method to the method we generate code for ... |
57 limit optimizations to those that will never change |
58 limit optimizations to those that will never change |
58 (or, if you change them, it will crash badly anyway ...) |
59 (or, if you change them, it will crash badly anyway ...) |
59 " |
60 " |
60 Number domainErrorSignal handle:[:ex | |
61 SignalSet anySignal "Number domainErrorSignal" handle:[:ex | |
|
62 "in case of an error, abort fold and return original" |
61 ex return |
63 ex return |
62 ] do:[ |
64 ] do:[ |
63 sym := s asSymbol. |
|
64 recVal respondsToArithmetic ifTrue:[ |
65 recVal respondsToArithmetic ifTrue:[ |
65 (#( negated abs asPoint degreesToRadians radiansToDegrees |
66 (#( negated abs asPoint degreesToRadians radiansToDegrees |
66 exp ln log sqrt reciprocal |
67 exp ln log sqrt reciprocal |
67 arcCos arcSin arcTan sin cos tan) includes:sym) |
68 arcCos arcSin arcTan sin cos tan) includes:selector) |
68 ifTrue:[ |
69 ifTrue:[ |
69 result := recVal perform:sym. |
70 result := recVal perform:selector. |
70 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
71 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
71 value:result |
72 value:result |
72 ] |
73 ] |
73 ]. |
74 ]. |
74 (recVal isMemberOf:Character) ifTrue:[ |
75 (recVal isMemberOf:Character) ifTrue:[ |
75 (#( asciiValue asInteger digitValue) includes:sym) |
76 (#( asciiValue asInteger digitValue) includes:selector) |
76 ifTrue:[ |
77 ifTrue:[ |
77 result := recVal perform:sym. |
78 result := recVal perform:selector. |
78 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
79 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
79 value:result |
80 value:result |
80 ] |
81 ] |
81 ]. |
82 ]. |
82 (recVal isMemberOf:String) ifTrue:[ |
83 (recVal isMemberOf:String) ifTrue:[ |
83 (sym == #withCRs) ifTrue:[ |
84 (selector == #withCRs) ifTrue:[ |
84 result := recVal perform:sym. |
85 result := recVal perform:selector. |
85 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
86 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
86 value:result |
87 value:result |
87 ] |
88 ] |
88 ]. |
89 ]. |
89 ^ (self basicNew) receiver:r selector:s args:nil lineno:0 |
90 (recVal isMemberOf:Array) ifTrue:[ |
|
91 (#(asFloatArray asDoubleArray) includes:selector) ifTrue:[ |
|
92 result := recVal perform:selector. |
|
93 ^ ConstantNode type:(ConstantNode typeOfConstant:result) |
|
94 value:result |
|
95 ] |
|
96 ]. |
|
97 ^ (self basicNew) receiver:r selector:selector args:nil lineno:0 |
90 ]. |
98 ]. |
91 "when we reach here, something went wrong (something like 0.0 log)" |
99 "when we reach here, something went wrong (something like 0.0 log)" |
92 ^ 'error occured when evaluating constant expression' |
100 ^ 'error occured when evaluating constant expression' |
93 ] |
101 ] |
94 ] |
102 ] |
95 ] |
103 ] |
96 ]. |
104 ]. |
97 ^ (self basicNew) receiver:r selector:s args:nil lineno:0 |
105 ^ (self basicNew) receiver:r selector:selectorString args:nil lineno:0 |
98 ! ! |
106 ! ! |
99 |
107 |
100 !UnaryNode methodsFor:'queries'! |
108 !UnaryNode methodsFor:'queries'! |
101 |
109 |
102 isUnaryMessage |
110 isUnaryMessage |