-
Notifications
You must be signed in to change notification settings - Fork 68
/
TReturnNode.class.st
224 lines (171 loc) · 5.33 KB
/
TReturnNode.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
Class {
#name : #TReturnNode,
#superclass : #TParseNode,
#instVars : [
'expression'
],
#category : #'Slang-AST'
}
{ #category : #generated }
TReturnNode class >> expression: anExpression [
^ self new
expression: anExpression;
yourself
]
{ #category : #comparing }
TReturnNode >> = aNode [
super = aNode ifFalse: [ ^false ].
aNode isReturn ifFalse: [ ^false ].
expression = aNode expression ifFalse: [ ^ false ].
^ true
]
{ #category : #visiting }
TReturnNode >> accept: aVisitor [
^ aVisitor visitReturnNode: self
]
{ #category : #tranforming }
TReturnNode >> asCASTIn: aBuilder [
| cast |
(expression isSwitch or: [expression isCaseStmt]) ifTrue: [
^ expression asCASTIn: aBuilder addToEndOfCases: self ].
'void' = aBuilder currentMethod returnType ifTrue: [
"If the function is void, don't say 'return x' instead say ' x; return' "
| statements |
statements := OrderedCollection new.
expression isLeaf ifFalse: [
statements add: (expression asCASTIn: aBuilder) ].
statements add: CReturnStatementNode new.
^ (CCompoundStatementNode statements: statements)
needsBrackets: false "Slang compatibility";
yourself ].
cast := expression asCASTExpressionIn: aBuilder.
"If the expression is a sequence, inject the return at the last element.
It may be more clean to do that at the TAST level instead of the CAST level. I dunno."
cast isCompoundStatement ifTrue: [
cast last: (CReturnStatementNode expression: cast last).
^ cast ].
"Or else build a return"
^ CReturnStatementNode expression: cast.
]
{ #category : #transformations }
TReturnNode >> asReturnNode [
^self
]
{ #category : #transformations }
TReturnNode >> bindVariableUsesIn: aDictionary [
self expression: (expression bindVariableUsesIn: aDictionary)
]
{ #category : #transformations }
TReturnNode >> bindVariableUsesIn: aDictionary andConstantFoldIf: constantFold in: codeGen [
"Answer either the receiver, if it contains no references to the given variables, or a new node with the given variables rebound."
| newExpression |
newExpression := expression bindVariableUsesIn: aDictionary andConstantFoldIf: constantFold in: codeGen.
^newExpression = expression
ifTrue: [self]
ifFalse:
[self shallowCopy
setExpression: newExpression;
yourself]
]
{ #category : #transformations }
TReturnNode >> bindVariablesIn: aDictionary [
self expression: (expression bindVariablesIn: aDictionary)
]
{ #category : #transformations }
TReturnNode >> bindVariablesIn: aDictionary unless: cautionaryBlock [
(cautionaryBlock value: self) ifTrue: [^self].
self expression: (expression bindVariablesIn: aDictionary unless: cautionaryBlock)
]
{ #category : #accessing }
TReturnNode >> children [
^ { expression }
]
{ #category : #transformations }
TReturnNode >> copyWithoutReturn [
^expression
]
{ #category : #testing }
TReturnNode >> endsWithReturn [
^true
]
{ #category : #accessing }
TReturnNode >> expression [
^expression
]
{ #category : #accessing }
TReturnNode >> expression: anExpression [
expression := anExpression.
expression parent: self.
]
{ #category : #testing }
TReturnNode >> isReturn [
^true
]
{ #category : #comparing }
TReturnNode >> isSameAs: aTParseNode [
aTParseNode isReturn ifFalse: [ ^ false ].
^ expression isSameAs: aTParseNode expression
]
{ #category : #enumerating }
TReturnNode >> nodesDo: aBlock [
"Apply aBlock to all nodes in the receiver.
N.B. This is assumed to be bottom-up, leaves first."
expression nodesDo: aBlock.
aBlock value: self
]
{ #category : #enumerating }
TReturnNode >> nodesDo: aBlock parent: parent [
"Apply aBlock to all nodes in the receiver with each node's parent.
N.B. This is assumed to be bottom-up, leaves first."
expression nodesDo: aBlock parent: self.
aBlock value: self value: parent
]
{ #category : #enumerating }
TReturnNode >> nodesDo: aBlock parent: parent unless: cautionaryBlock [
(cautionaryBlock value: self value: parent) ifTrue: [^self].
expression nodesDo: aBlock parent: self unless: cautionaryBlock.
aBlock value: self value: parent
]
{ #category : #enumerating }
TReturnNode >> nodesDo: aBlock unless: cautionaryBlock [
(cautionaryBlock value: self) ifTrue: [^self].
expression nodesDo: aBlock unless: cautionaryBlock.
aBlock value: self.
]
{ #category : #copying }
TReturnNode >> postCopy [
self expression: expression copy
]
{ #category : #'C code generation' }
TReturnNode >> prependCASTIn: aBuilder expression: nodeExp [
^ CReturnStatementNode expression:
(nodeExp asCASTExpressionIn: aBuilder)
]
{ #category : #printing }
TReturnNode >> printOn: aStream level: level [
aStream nextPut: $^.
expression printOn: aStream level: level.
]
{ #category : #transformations }
TReturnNode >> removeAssertions [
expression removeAssertions
]
{ #category : #transformations }
TReturnNode >> replaceChild: aNode with: aReplacementNode [
expression == aNode ifFalse: [ self error: 'Node is not a child of current node' ].
self expression: aReplacementNode
]
{ #category : #transformations }
TReturnNode >> replaceNodesIn: aDictionary [
^aDictionary at: self ifAbsent: [
self expression: (expression replaceNodesIn: aDictionary).
self]
]
{ #category : #accessing }
TReturnNode >> setExpression: aNode [
self expression: aNode
]
{ #category : #'type inference' }
TReturnNode >> typeOrNilFrom: aCodeGenerator in: aTMethod [
^expression typeOrNilFrom: aCodeGenerator in: aTMethod
]