resin 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/amber/css/amber-normalize.css +73 -73
- data/amber/css/amber-normalize.less +1 -1
- data/amber/css/amber.css +106 -106
- data/amber/css/helios.css +242 -0
- data/amber/images/hsplitter.png +0 -0
- data/amber/images/vsplitter.png +0 -0
- data/amber/js/Benchfib.deploy.js +116 -38
- data/amber/js/Benchfib.js +120 -42
- data/amber/js/Canvas.deploy.js +674 -403
- data/amber/js/Canvas.js +682 -411
- data/amber/js/Compiler-AST.deploy.js +1150 -0
- data/amber/js/Compiler-AST.js +1591 -0
- data/amber/js/Compiler-Core.deploy.js +1562 -0
- data/amber/js/Compiler-Core.js +1972 -0
- data/amber/js/Compiler-Exceptions.deploy.js +114 -0
- data/amber/js/Compiler-Exceptions.js +161 -0
- data/amber/js/Compiler-IR.deploy.js +2326 -0
- data/amber/js/Compiler-IR.js +3146 -0
- data/amber/js/Compiler-Inlining.deploy.js +1147 -0
- data/amber/js/Compiler-Inlining.js +1514 -0
- data/amber/js/Compiler-Semantic.deploy.js +1207 -0
- data/amber/js/Compiler-Semantic.js +1628 -0
- data/amber/js/Compiler-Tests.deploy.js +646 -60
- data/amber/js/Compiler-Tests.js +843 -82
- data/amber/js/Compiler.deploy.js +1097 -159
- data/amber/js/Compiler.js +1414 -161
- data/amber/js/Examples.deploy.js +31 -15
- data/amber/js/Examples.js +33 -17
- data/amber/js/Helios-Announcements.deploy.js +127 -0
- data/amber/js/Helios-Announcements.js +157 -0
- data/amber/js/Helios-Browser.deploy.js +1473 -0
- data/amber/js/Helios-Browser.js +1953 -0
- data/amber/js/Helios-Commands.deploy.js +403 -0
- data/amber/js/Helios-Commands.js +563 -0
- data/amber/js/Helios-Core.deploy.js +1070 -0
- data/amber/js/Helios-Core.js +1445 -0
- data/amber/js/Helios-Environments.deploy.js +132 -0
- data/amber/js/Helios-Environments.js +179 -0
- data/amber/js/Helios-Inspector.deploy.js +855 -0
- data/amber/js/Helios-Inspector.js +1155 -0
- data/amber/js/Helios-KeyBindings.deploy.js +753 -0
- data/amber/js/Helios-KeyBindings.js +1023 -0
- data/amber/js/Helios-Layout.deploy.js +383 -0
- data/amber/js/Helios-Layout.js +523 -0
- data/amber/js/Helios-Workspace.deploy.js +799 -0
- data/amber/js/Helios-Workspace.js +1074 -0
- data/amber/js/IDE.deploy.js +2541 -1490
- data/amber/js/IDE.js +2721 -1660
- data/amber/js/Importer-Exporter.deploy.js +671 -0
- data/amber/js/Importer-Exporter.js +816 -0
- data/amber/js/Kernel-Announcements.deploy.js +137 -20
- data/amber/js/Kernel-Announcements.js +176 -22
- data/amber/js/Kernel-Classes.deploy.js +555 -168
- data/amber/js/Kernel-Classes.js +662 -205
- data/amber/js/Kernel-Collections.deploy.js +1403 -618
- data/amber/js/Kernel-Collections.js +1545 -690
- data/amber/js/Kernel-Exceptions.deploy.js +109 -45
- data/amber/js/Kernel-Exceptions.js +123 -49
- data/amber/js/Kernel-Methods.deploy.js +196 -81
- data/amber/js/Kernel-Methods.js +214 -89
- data/amber/js/Kernel-Objects.deploy.js +1542 -1117
- data/amber/js/Kernel-Objects.js +1593 -1148
- data/amber/js/Kernel-Tests.deploy.js +1725 -772
- data/amber/js/Kernel-Tests.js +2301 -1123
- data/amber/js/Kernel-Transcript.deploy.js +23 -25
- data/amber/js/Kernel-Transcript.js +24 -26
- data/amber/js/SUnit.deploy.js +204 -131
- data/amber/js/SUnit.js +222 -139
- data/amber/js/Spaces.deploy.js +240 -0
- data/amber/js/Spaces.js +326 -0
- data/amber/js/amber.js +26 -7
- data/amber/js/boot.js +65 -47
- data/amber/js/init.js +1 -1
- data/amber/js/lib/CodeMirror/amber.css +21 -21
- data/amber/js/lib/CodeMirror/codemirror.css +119 -13
- data/amber/js/lib/CodeMirror/codemirror.js +2219 -1220
- data/amber/js/lib/CodeMirror/smalltalk.js +134 -129
- data/amber/js/lib/bootstrap/css/bootstrap.css +5837 -0
- data/amber/js/lib/bootstrap/css/bootstrap.min.css +841 -0
- data/amber/js/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/amber/js/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- data/amber/js/lib/bootstrap/js/bootstrap.js +2038 -0
- data/amber/js/lib/bootstrap/js/bootstrap.min.js +7 -0
- data/amber/js/lib/jQuery/jquery-1.8.2.min.js +2 -0
- data/amber/js/lib/jQuery/jquery-ui-1.8.24.custom.min.js +125 -0
- data/amber/st/Compiler-AST.st +505 -0
- data/amber/st/Compiler-Core.st +835 -0
- data/amber/st/Compiler-Exceptions.st +87 -0
- data/amber/st/Compiler-IR.st +1097 -0
- data/amber/st/Compiler-Inlining.st +650 -0
- data/amber/st/Compiler-Semantic.st +558 -0
- data/amber/st/Compiler-Tests.st +285 -381
- data/amber/st/Compiler.st +725 -2
- data/amber/st/Helios-Announcements.st +104 -0
- data/amber/st/Helios-Browser.st +708 -0
- data/amber/st/Helios-Commands.st +223 -0
- data/amber/st/Helios-Core.st +532 -0
- data/amber/st/Helios-Environments.st +98 -0
- data/amber/st/Helios-Inspector.st +367 -0
- data/amber/st/Helios-KeyBindings.st +337 -0
- data/amber/st/Helios-Layout.st +199 -0
- data/amber/st/Helios-Workspace.st +367 -0
- data/amber/st/IDE.st +75 -53
- data/amber/st/Importer-Exporter.st +386 -0
- data/amber/st/Kernel-Announcements.st +92 -0
- data/amber/st/Kernel-Classes.st +137 -15
- data/amber/st/Kernel-Collections.st +137 -47
- data/amber/st/Kernel-Exceptions.st +14 -0
- data/amber/st/Kernel-Methods.st +9 -1
- data/amber/st/Kernel-Objects.st +29 -5
- data/amber/st/Kernel-Tests.st +545 -199
- data/amber/st/SUnit.st +10 -0
- data/amber/st/Spaces.st +142 -0
- data/lib/resin/app.rb +1 -1
- metadata +86 -31
- data/amber/js/lib/jQuery/jquery-1.4.4.min.js +0 -167
- data/amber/js/lib/jQuery/jquery-1.6.4.min.js +0 -4
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
Smalltalk current createPackage: 'Compiler-Semantic' properties: #{}!
|
|
2
|
+
Object subclass: #LexicalScope
|
|
3
|
+
instanceVariableNames: 'node instruction temps args outerScope'
|
|
4
|
+
package: 'Compiler-Semantic'!
|
|
5
|
+
!LexicalScope commentStamp!
|
|
6
|
+
I represent a lexical scope where variable names are associated with ScopeVars
|
|
7
|
+
Instances are used for block scopes. Method scopes are instances of MethodLexicalScope.
|
|
8
|
+
|
|
9
|
+
I am attached to a ScopeVar and method/block nodes.
|
|
10
|
+
Each context (method/closure) get a fresh scope that inherits from its outer scope.!
|
|
11
|
+
|
|
12
|
+
!LexicalScope methodsFor: 'accessing'!
|
|
13
|
+
|
|
14
|
+
allVariableNames
|
|
15
|
+
^ self args keys, self temps keys
|
|
16
|
+
!
|
|
17
|
+
|
|
18
|
+
args
|
|
19
|
+
^ args ifNil: [ args := Dictionary new ]
|
|
20
|
+
!
|
|
21
|
+
|
|
22
|
+
bindingFor: aStringOrNode
|
|
23
|
+
^ self pseudoVars at: aStringOrNode value ifAbsent: [
|
|
24
|
+
self args at: aStringOrNode value ifAbsent: [
|
|
25
|
+
self temps at: aStringOrNode value ifAbsent: [ nil ]]]
|
|
26
|
+
!
|
|
27
|
+
|
|
28
|
+
instruction
|
|
29
|
+
^ instruction
|
|
30
|
+
!
|
|
31
|
+
|
|
32
|
+
instruction: anIRInstruction
|
|
33
|
+
instruction := anIRInstruction
|
|
34
|
+
!
|
|
35
|
+
|
|
36
|
+
lookupVariable: aNode
|
|
37
|
+
| lookup |
|
|
38
|
+
lookup := (self bindingFor: aNode).
|
|
39
|
+
lookup ifNil: [
|
|
40
|
+
lookup := self outerScope ifNotNil: [
|
|
41
|
+
(self outerScope lookupVariable: aNode) ]].
|
|
42
|
+
^ lookup
|
|
43
|
+
!
|
|
44
|
+
|
|
45
|
+
methodScope
|
|
46
|
+
^ self outerScope ifNotNil: [
|
|
47
|
+
self outerScope methodScope ]
|
|
48
|
+
!
|
|
49
|
+
|
|
50
|
+
node
|
|
51
|
+
"Answer the node in which I am defined"
|
|
52
|
+
|
|
53
|
+
^ node
|
|
54
|
+
!
|
|
55
|
+
|
|
56
|
+
node: aNode
|
|
57
|
+
node := aNode
|
|
58
|
+
!
|
|
59
|
+
|
|
60
|
+
outerScope
|
|
61
|
+
^ outerScope
|
|
62
|
+
!
|
|
63
|
+
|
|
64
|
+
outerScope: aLexicalScope
|
|
65
|
+
outerScope := aLexicalScope
|
|
66
|
+
!
|
|
67
|
+
|
|
68
|
+
pseudoVars
|
|
69
|
+
^ self methodScope pseudoVars
|
|
70
|
+
!
|
|
71
|
+
|
|
72
|
+
scopeLevel
|
|
73
|
+
^ (self outerScope
|
|
74
|
+
ifNil: [ 0 ]
|
|
75
|
+
ifNotNil: [ self outerScope scopeLevel ]) + 1
|
|
76
|
+
!
|
|
77
|
+
|
|
78
|
+
temps
|
|
79
|
+
^ temps ifNil: [ temps := Dictionary new ]
|
|
80
|
+
! !
|
|
81
|
+
|
|
82
|
+
!LexicalScope methodsFor: 'adding'!
|
|
83
|
+
|
|
84
|
+
addArg: aString
|
|
85
|
+
self args at: aString put: (ArgVar on: aString).
|
|
86
|
+
(self args at: aString) scope: self
|
|
87
|
+
!
|
|
88
|
+
|
|
89
|
+
addTemp: aString
|
|
90
|
+
self temps at: aString put: (TempVar on: aString).
|
|
91
|
+
(self temps at: aString) scope: self
|
|
92
|
+
! !
|
|
93
|
+
|
|
94
|
+
!LexicalScope methodsFor: 'testing'!
|
|
95
|
+
|
|
96
|
+
canInlineNonLocalReturns
|
|
97
|
+
^ self isInlined and: [ self outerScope canInlineNonLocalReturns ]
|
|
98
|
+
!
|
|
99
|
+
|
|
100
|
+
isBlockScope
|
|
101
|
+
^ self isMethodScope not
|
|
102
|
+
!
|
|
103
|
+
|
|
104
|
+
isInlined
|
|
105
|
+
^ self instruction isInlined
|
|
106
|
+
!
|
|
107
|
+
|
|
108
|
+
isMethodScope
|
|
109
|
+
^ false
|
|
110
|
+
! !
|
|
111
|
+
|
|
112
|
+
LexicalScope subclass: #MethodLexicalScope
|
|
113
|
+
instanceVariableNames: 'iVars pseudoVars unknownVariables localReturn nonLocalReturns'
|
|
114
|
+
package: 'Compiler-Semantic'!
|
|
115
|
+
!MethodLexicalScope commentStamp!
|
|
116
|
+
I represent a method scope.!
|
|
117
|
+
|
|
118
|
+
!MethodLexicalScope methodsFor: 'accessing'!
|
|
119
|
+
|
|
120
|
+
allVariableNames
|
|
121
|
+
^ super allVariableNames, self iVars keys
|
|
122
|
+
!
|
|
123
|
+
|
|
124
|
+
bindingFor: aNode
|
|
125
|
+
^ (super bindingFor: aNode) ifNil: [
|
|
126
|
+
self iVars at: aNode value ifAbsent: [ nil ]]
|
|
127
|
+
!
|
|
128
|
+
|
|
129
|
+
iVars
|
|
130
|
+
^ iVars ifNil: [ iVars := Dictionary new ]
|
|
131
|
+
!
|
|
132
|
+
|
|
133
|
+
localReturn
|
|
134
|
+
^ localReturn ifNil: [ false ]
|
|
135
|
+
!
|
|
136
|
+
|
|
137
|
+
localReturn: aBoolean
|
|
138
|
+
localReturn := aBoolean
|
|
139
|
+
!
|
|
140
|
+
|
|
141
|
+
methodScope
|
|
142
|
+
^ self
|
|
143
|
+
!
|
|
144
|
+
|
|
145
|
+
nonLocalReturns
|
|
146
|
+
^ nonLocalReturns ifNil: [ nonLocalReturns := OrderedCollection new ]
|
|
147
|
+
!
|
|
148
|
+
|
|
149
|
+
pseudoVars
|
|
150
|
+
pseudoVars ifNil: [
|
|
151
|
+
pseudoVars := Dictionary new.
|
|
152
|
+
Smalltalk current pseudoVariableNames do: [ :each |
|
|
153
|
+
pseudoVars at: each put: ((PseudoVar on: each)
|
|
154
|
+
scope: self methodScope;
|
|
155
|
+
yourself) ]].
|
|
156
|
+
^ pseudoVars
|
|
157
|
+
!
|
|
158
|
+
|
|
159
|
+
unknownVariables
|
|
160
|
+
^ unknownVariables ifNil: [ unknownVariables := OrderedCollection new ]
|
|
161
|
+
! !
|
|
162
|
+
|
|
163
|
+
!MethodLexicalScope methodsFor: 'adding'!
|
|
164
|
+
|
|
165
|
+
addIVar: aString
|
|
166
|
+
self iVars at: aString put: (InstanceVar on: aString).
|
|
167
|
+
(self iVars at: aString) scope: self
|
|
168
|
+
!
|
|
169
|
+
|
|
170
|
+
addNonLocalReturn: aScope
|
|
171
|
+
self nonLocalReturns add: aScope
|
|
172
|
+
!
|
|
173
|
+
|
|
174
|
+
removeNonLocalReturn: aScope
|
|
175
|
+
self nonLocalReturns remove: aScope ifAbsent: []
|
|
176
|
+
! !
|
|
177
|
+
|
|
178
|
+
!MethodLexicalScope methodsFor: 'testing'!
|
|
179
|
+
|
|
180
|
+
canInlineNonLocalReturns
|
|
181
|
+
^ true
|
|
182
|
+
!
|
|
183
|
+
|
|
184
|
+
hasLocalReturn
|
|
185
|
+
^ self localReturn
|
|
186
|
+
!
|
|
187
|
+
|
|
188
|
+
hasNonLocalReturn
|
|
189
|
+
^ self nonLocalReturns notEmpty
|
|
190
|
+
!
|
|
191
|
+
|
|
192
|
+
isMethodScope
|
|
193
|
+
^ true
|
|
194
|
+
! !
|
|
195
|
+
|
|
196
|
+
Object subclass: #ScopeVar
|
|
197
|
+
instanceVariableNames: 'scope name'
|
|
198
|
+
package: 'Compiler-Semantic'!
|
|
199
|
+
!ScopeVar commentStamp!
|
|
200
|
+
I am an entry in a LexicalScope that gets associated with variable nodes of the same name.
|
|
201
|
+
There are 4 different subclasses of vars: temp vars, local vars, args, and unknown/global vars.!
|
|
202
|
+
|
|
203
|
+
!ScopeVar methodsFor: 'accessing'!
|
|
204
|
+
|
|
205
|
+
alias
|
|
206
|
+
^ self name asVariableName
|
|
207
|
+
!
|
|
208
|
+
|
|
209
|
+
name
|
|
210
|
+
^ name
|
|
211
|
+
!
|
|
212
|
+
|
|
213
|
+
name: aString
|
|
214
|
+
name := aString
|
|
215
|
+
!
|
|
216
|
+
|
|
217
|
+
scope
|
|
218
|
+
^ scope
|
|
219
|
+
!
|
|
220
|
+
|
|
221
|
+
scope: aScope
|
|
222
|
+
scope := aScope
|
|
223
|
+
! !
|
|
224
|
+
|
|
225
|
+
!ScopeVar methodsFor: 'testing'!
|
|
226
|
+
|
|
227
|
+
isArgVar
|
|
228
|
+
^ false
|
|
229
|
+
!
|
|
230
|
+
|
|
231
|
+
isClassRefVar
|
|
232
|
+
^ false
|
|
233
|
+
!
|
|
234
|
+
|
|
235
|
+
isInstanceVar
|
|
236
|
+
^ false
|
|
237
|
+
!
|
|
238
|
+
|
|
239
|
+
isPseudoVar
|
|
240
|
+
^ false
|
|
241
|
+
!
|
|
242
|
+
|
|
243
|
+
isTempVar
|
|
244
|
+
^ false
|
|
245
|
+
!
|
|
246
|
+
|
|
247
|
+
isUnknownVar
|
|
248
|
+
^ false
|
|
249
|
+
!
|
|
250
|
+
|
|
251
|
+
validateAssignment
|
|
252
|
+
(self isArgVar or: [ self isPseudoVar ]) ifTrue: [
|
|
253
|
+
InvalidAssignmentError new
|
|
254
|
+
variableName: self name;
|
|
255
|
+
signal]
|
|
256
|
+
! !
|
|
257
|
+
|
|
258
|
+
!ScopeVar class methodsFor: 'instance creation'!
|
|
259
|
+
|
|
260
|
+
on: aString
|
|
261
|
+
^ self new
|
|
262
|
+
name: aString;
|
|
263
|
+
yourself
|
|
264
|
+
! !
|
|
265
|
+
|
|
266
|
+
ScopeVar subclass: #AliasVar
|
|
267
|
+
instanceVariableNames: 'node'
|
|
268
|
+
package: 'Compiler-Semantic'!
|
|
269
|
+
!AliasVar commentStamp!
|
|
270
|
+
I am an internally defined variable by the compiler!
|
|
271
|
+
|
|
272
|
+
!AliasVar methodsFor: 'accessing'!
|
|
273
|
+
|
|
274
|
+
node
|
|
275
|
+
^ node
|
|
276
|
+
!
|
|
277
|
+
|
|
278
|
+
node: aNode
|
|
279
|
+
node := aNode
|
|
280
|
+
! !
|
|
281
|
+
|
|
282
|
+
ScopeVar subclass: #ArgVar
|
|
283
|
+
instanceVariableNames: ''
|
|
284
|
+
package: 'Compiler-Semantic'!
|
|
285
|
+
!ArgVar commentStamp!
|
|
286
|
+
I am an argument of a method or block.!
|
|
287
|
+
|
|
288
|
+
!ArgVar methodsFor: 'testing'!
|
|
289
|
+
|
|
290
|
+
isArgVar
|
|
291
|
+
^ true
|
|
292
|
+
! !
|
|
293
|
+
|
|
294
|
+
ScopeVar subclass: #ClassRefVar
|
|
295
|
+
instanceVariableNames: ''
|
|
296
|
+
package: 'Compiler-Semantic'!
|
|
297
|
+
!ClassRefVar commentStamp!
|
|
298
|
+
I am an class reference variable!
|
|
299
|
+
|
|
300
|
+
!ClassRefVar methodsFor: 'accessing'!
|
|
301
|
+
|
|
302
|
+
alias
|
|
303
|
+
^ '(smalltalk.', self name, ' || ', self name, ')'
|
|
304
|
+
! !
|
|
305
|
+
|
|
306
|
+
!ClassRefVar methodsFor: 'testing'!
|
|
307
|
+
|
|
308
|
+
isClassRefVar
|
|
309
|
+
^ true
|
|
310
|
+
! !
|
|
311
|
+
|
|
312
|
+
ScopeVar subclass: #InstanceVar
|
|
313
|
+
instanceVariableNames: ''
|
|
314
|
+
package: 'Compiler-Semantic'!
|
|
315
|
+
!InstanceVar commentStamp!
|
|
316
|
+
I am an instance variable of a method or block.!
|
|
317
|
+
|
|
318
|
+
!InstanceVar methodsFor: 'testing'!
|
|
319
|
+
|
|
320
|
+
alias
|
|
321
|
+
^ 'self["@', self name, '"]'
|
|
322
|
+
!
|
|
323
|
+
|
|
324
|
+
isInstanceVar
|
|
325
|
+
^ true
|
|
326
|
+
! !
|
|
327
|
+
|
|
328
|
+
ScopeVar subclass: #PseudoVar
|
|
329
|
+
instanceVariableNames: ''
|
|
330
|
+
package: 'Compiler-Semantic'!
|
|
331
|
+
!PseudoVar commentStamp!
|
|
332
|
+
I am an pseudo variable.
|
|
333
|
+
|
|
334
|
+
The five Smalltalk pseudo variables are: 'self', 'super', 'nil', 'true' and 'false'!
|
|
335
|
+
|
|
336
|
+
!PseudoVar methodsFor: 'accessing'!
|
|
337
|
+
|
|
338
|
+
alias
|
|
339
|
+
^ self name
|
|
340
|
+
! !
|
|
341
|
+
|
|
342
|
+
!PseudoVar methodsFor: 'testing'!
|
|
343
|
+
|
|
344
|
+
isPseudoVar
|
|
345
|
+
^ true
|
|
346
|
+
! !
|
|
347
|
+
|
|
348
|
+
ScopeVar subclass: #TempVar
|
|
349
|
+
instanceVariableNames: ''
|
|
350
|
+
package: 'Compiler-Semantic'!
|
|
351
|
+
!TempVar commentStamp!
|
|
352
|
+
I am an temporary variable of a method or block.!
|
|
353
|
+
|
|
354
|
+
!TempVar methodsFor: 'testing'!
|
|
355
|
+
|
|
356
|
+
isTempVar
|
|
357
|
+
^ true
|
|
358
|
+
! !
|
|
359
|
+
|
|
360
|
+
ScopeVar subclass: #UnknownVar
|
|
361
|
+
instanceVariableNames: ''
|
|
362
|
+
package: 'Compiler-Semantic'!
|
|
363
|
+
!UnknownVar commentStamp!
|
|
364
|
+
I am an unknown variable. Amber uses unknown variables as JavaScript globals!
|
|
365
|
+
|
|
366
|
+
!UnknownVar methodsFor: 'testing'!
|
|
367
|
+
|
|
368
|
+
isUnknownVar
|
|
369
|
+
^ true
|
|
370
|
+
! !
|
|
371
|
+
|
|
372
|
+
NodeVisitor subclass: #SemanticAnalyzer
|
|
373
|
+
instanceVariableNames: 'currentScope theClass classReferences messageSends'
|
|
374
|
+
package: 'Compiler-Semantic'!
|
|
375
|
+
!SemanticAnalyzer commentStamp!
|
|
376
|
+
I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.!
|
|
377
|
+
|
|
378
|
+
!SemanticAnalyzer methodsFor: 'accessing'!
|
|
379
|
+
|
|
380
|
+
classReferences
|
|
381
|
+
^ classReferences ifNil: [ classReferences := Set new ]
|
|
382
|
+
!
|
|
383
|
+
|
|
384
|
+
messageSends
|
|
385
|
+
^ messageSends ifNil: [ messageSends := Dictionary new ]
|
|
386
|
+
!
|
|
387
|
+
|
|
388
|
+
theClass
|
|
389
|
+
^ theClass
|
|
390
|
+
!
|
|
391
|
+
|
|
392
|
+
theClass: aClass
|
|
393
|
+
theClass := aClass
|
|
394
|
+
! !
|
|
395
|
+
|
|
396
|
+
!SemanticAnalyzer methodsFor: 'error handling'!
|
|
397
|
+
|
|
398
|
+
errorShadowingVariable: aString
|
|
399
|
+
ShadowingVariableError new
|
|
400
|
+
variableName: aString;
|
|
401
|
+
signal
|
|
402
|
+
!
|
|
403
|
+
|
|
404
|
+
errorUnknownVariable: aNode
|
|
405
|
+
"Throw an error if the variable is undeclared in the global JS scope (i.e. window)"
|
|
406
|
+
|
|
407
|
+
| notDefined |
|
|
408
|
+
|
|
409
|
+
notDefined := <eval('typeof ' + aNode._value() + ' == "undefined"')>.
|
|
410
|
+
|
|
411
|
+
notDefined
|
|
412
|
+
ifTrue: [
|
|
413
|
+
UnknownVariableError new
|
|
414
|
+
variableName: aNode value;
|
|
415
|
+
signal ]
|
|
416
|
+
ifFalse: [
|
|
417
|
+
currentScope methodScope unknownVariables add: aNode value. ]
|
|
418
|
+
! !
|
|
419
|
+
|
|
420
|
+
!SemanticAnalyzer methodsFor: 'factory'!
|
|
421
|
+
|
|
422
|
+
newBlockScope
|
|
423
|
+
^ self newScopeOfClass: LexicalScope
|
|
424
|
+
!
|
|
425
|
+
|
|
426
|
+
newMethodScope
|
|
427
|
+
^ self newScopeOfClass: MethodLexicalScope
|
|
428
|
+
!
|
|
429
|
+
|
|
430
|
+
newScopeOfClass: aLexicalScopeClass
|
|
431
|
+
^ aLexicalScopeClass new
|
|
432
|
+
outerScope: currentScope;
|
|
433
|
+
yourself
|
|
434
|
+
! !
|
|
435
|
+
|
|
436
|
+
!SemanticAnalyzer methodsFor: 'scope'!
|
|
437
|
+
|
|
438
|
+
popScope
|
|
439
|
+
currentScope ifNotNil: [
|
|
440
|
+
currentScope := currentScope outerScope ]
|
|
441
|
+
!
|
|
442
|
+
|
|
443
|
+
pushScope: aScope
|
|
444
|
+
aScope outerScope: currentScope.
|
|
445
|
+
currentScope := aScope
|
|
446
|
+
!
|
|
447
|
+
|
|
448
|
+
validateVariableScope: aString
|
|
449
|
+
"Validate the variable scope in by doing a recursive lookup, up to the method scope"
|
|
450
|
+
|
|
451
|
+
(currentScope lookupVariable: aString) ifNotNil: [
|
|
452
|
+
self errorShadowingVariable: aString ]
|
|
453
|
+
! !
|
|
454
|
+
|
|
455
|
+
!SemanticAnalyzer methodsFor: 'visiting'!
|
|
456
|
+
|
|
457
|
+
visitAssignmentNode: aNode
|
|
458
|
+
super visitAssignmentNode: aNode.
|
|
459
|
+
aNode left beAssigned
|
|
460
|
+
!
|
|
461
|
+
|
|
462
|
+
visitBlockNode: aNode
|
|
463
|
+
self pushScope: self newBlockScope.
|
|
464
|
+
aNode scope: currentScope.
|
|
465
|
+
currentScope node: aNode.
|
|
466
|
+
|
|
467
|
+
aNode parameters do: [ :each |
|
|
468
|
+
self validateVariableScope: each.
|
|
469
|
+
currentScope addArg: each ].
|
|
470
|
+
|
|
471
|
+
super visitBlockNode: aNode.
|
|
472
|
+
self popScope
|
|
473
|
+
!
|
|
474
|
+
|
|
475
|
+
visitCascadeNode: aNode
|
|
476
|
+
"Populate the receiver into all children"
|
|
477
|
+
aNode nodes do: [ :each |
|
|
478
|
+
each receiver: aNode receiver ].
|
|
479
|
+
super visitCascadeNode: aNode.
|
|
480
|
+
aNode nodes first superSend ifTrue: [
|
|
481
|
+
aNode nodes do: [ :each | each superSend: true ]]
|
|
482
|
+
!
|
|
483
|
+
|
|
484
|
+
visitClassReferenceNode: aNode
|
|
485
|
+
self classReferences add: aNode value.
|
|
486
|
+
aNode binding: (ClassRefVar new name: aNode value; yourself)
|
|
487
|
+
!
|
|
488
|
+
|
|
489
|
+
visitMethodNode: aNode
|
|
490
|
+
self pushScope: self newMethodScope.
|
|
491
|
+
aNode scope: currentScope.
|
|
492
|
+
currentScope node: aNode.
|
|
493
|
+
|
|
494
|
+
self theClass allInstanceVariableNames do: [:each |
|
|
495
|
+
currentScope addIVar: each ].
|
|
496
|
+
aNode arguments do: [ :each |
|
|
497
|
+
self validateVariableScope: each.
|
|
498
|
+
currentScope addArg: each ].
|
|
499
|
+
|
|
500
|
+
super visitMethodNode: aNode.
|
|
501
|
+
|
|
502
|
+
aNode
|
|
503
|
+
classReferences: self classReferences;
|
|
504
|
+
messageSends: self messageSends keys.
|
|
505
|
+
self popScope
|
|
506
|
+
!
|
|
507
|
+
|
|
508
|
+
visitReturnNode: aNode
|
|
509
|
+
aNode scope: currentScope.
|
|
510
|
+
currentScope isMethodScope
|
|
511
|
+
ifTrue: [ currentScope localReturn: true ]
|
|
512
|
+
ifFalse: [ currentScope methodScope addNonLocalReturn: currentScope ].
|
|
513
|
+
super visitReturnNode: aNode
|
|
514
|
+
!
|
|
515
|
+
|
|
516
|
+
visitSendNode: aNode
|
|
517
|
+
|
|
518
|
+
aNode receiver value = 'super'
|
|
519
|
+
ifTrue: [
|
|
520
|
+
aNode superSend: true.
|
|
521
|
+
aNode receiver value: 'self' ]
|
|
522
|
+
ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
|
|
523
|
+
aNode shouldBeInlined: true.
|
|
524
|
+
aNode receiver isValueNode ifFalse: [ aNode receiver shouldBeAliased: true ] ] ].
|
|
525
|
+
|
|
526
|
+
self messageSends at: aNode selector ifAbsentPut: [ Set new ].
|
|
527
|
+
(self messageSends at: aNode selector) add: aNode.
|
|
528
|
+
|
|
529
|
+
aNode index: (self messageSends at: aNode selector) size.
|
|
530
|
+
|
|
531
|
+
super visitSendNode: aNode
|
|
532
|
+
!
|
|
533
|
+
|
|
534
|
+
visitSequenceNode: aNode
|
|
535
|
+
aNode temps do: [ :each |
|
|
536
|
+
self validateVariableScope: each.
|
|
537
|
+
currentScope addTemp: each ].
|
|
538
|
+
|
|
539
|
+
super visitSequenceNode: aNode
|
|
540
|
+
!
|
|
541
|
+
|
|
542
|
+
visitVariableNode: aNode
|
|
543
|
+
"Bind a ScopeVar to aNode by doing a lookup in the current scope.
|
|
544
|
+
If no ScopeVar is found, bind a UnknowVar and throw an error"
|
|
545
|
+
|
|
546
|
+
aNode binding: ((currentScope lookupVariable: aNode) ifNil: [
|
|
547
|
+
self errorUnknownVariable: aNode.
|
|
548
|
+
UnknownVar new name: aNode value; yourself ])
|
|
549
|
+
! !
|
|
550
|
+
|
|
551
|
+
!SemanticAnalyzer class methodsFor: 'instance creation'!
|
|
552
|
+
|
|
553
|
+
on: aClass
|
|
554
|
+
^ self new
|
|
555
|
+
theClass: aClass;
|
|
556
|
+
yourself
|
|
557
|
+
! !
|
|
558
|
+
|