resin 0.2.1 → 0.2.2

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.
Files changed (60) hide show
  1. data/README.markdown +2 -0
  2. data/amber/bin/nodecompile.js +3 -3
  3. data/amber/css/amber.css +47 -23
  4. data/amber/images/off.amber.png +0 -0
  5. data/amber/images/offHover.amber.png +0 -0
  6. data/amber/images/sprite.amber.png +0 -0
  7. data/amber/images/tinylogo.amber.png +0 -0
  8. data/amber/js/Benchfib.deploy.js +34 -34
  9. data/amber/js/Benchfib.js +49 -49
  10. data/amber/js/Canvas.deploy.js +937 -937
  11. data/amber/js/Canvas.js +1622 -1622
  12. data/amber/js/Compiler-Tests.deploy.js +97 -0
  13. data/amber/js/Compiler-Tests.js +137 -0
  14. data/amber/js/Compiler.deploy.js +1030 -924
  15. data/amber/js/Compiler.js +1613 -1467
  16. data/amber/js/Documentation.deploy.js +417 -417
  17. data/amber/js/Documentation.js +728 -728
  18. data/amber/js/Examples.deploy.js +24 -13
  19. data/amber/js/Examples.js +36 -19
  20. data/amber/js/IDE.deploy.js +1583 -1527
  21. data/amber/js/IDE.js +2586 -2510
  22. data/amber/js/Kernel-Announcements.deploy.js +19 -19
  23. data/amber/js/Kernel-Announcements.js +28 -28
  24. data/amber/js/Kernel-Classes.deploy.js +332 -229
  25. data/amber/js/Kernel-Classes.js +532 -384
  26. data/amber/js/Kernel-Collections.deploy.js +1516 -1712
  27. data/amber/js/Kernel-Collections.js +2436 -2712
  28. data/amber/js/Kernel-Exceptions.deploy.js +85 -62
  29. data/amber/js/Kernel-Exceptions.js +131 -98
  30. data/amber/js/Kernel-Methods.deploy.js +326 -378
  31. data/amber/js/Kernel-Methods.js +473 -525
  32. data/amber/js/Kernel-Objects.deploy.js +1777 -2428
  33. data/amber/js/Kernel-Objects.js +2599 -3426
  34. data/amber/js/Kernel-Tests.deploy.js +871 -772
  35. data/amber/js/Kernel-Tests.js +1207 -1083
  36. data/amber/js/Kernel-Transcript.deploy.js +57 -57
  37. data/amber/js/Kernel-Transcript.js +94 -94
  38. data/amber/js/SUnit.deploy.js +116 -116
  39. data/amber/js/SUnit.js +211 -211
  40. data/amber/js/amber.js +10 -11
  41. data/amber/js/boot.js +132 -156
  42. data/amber/js/init.js +2 -2
  43. data/amber/js/parser.js +2095 -3014
  44. data/amber/js/parser.pegjs +1 -1
  45. data/amber/st/Benchfib.st +22 -22
  46. data/amber/st/Canvas.st +471 -471
  47. data/amber/st/Compiler-Tests.st +471 -0
  48. data/amber/st/Compiler.st +858 -794
  49. data/amber/st/Examples.st +22 -5
  50. data/amber/st/IDE.st +1326 -1291
  51. data/amber/st/Kernel-Announcements.st +2 -2
  52. data/amber/st/Kernel-Classes.st +148 -90
  53. data/amber/st/Kernel-Collections.st +950 -1061
  54. data/amber/st/Kernel-Exceptions.st +33 -25
  55. data/amber/st/Kernel-Methods.st +151 -151
  56. data/amber/st/Kernel-Objects.st +891 -1036
  57. data/amber/st/Kernel-Tests.st +622 -544
  58. data/amber/st/Kernel-Transcript.st +38 -38
  59. data/amber/st/SUnit.st +53 -53
  60. metadata +27 -20
@@ -1,122 +1,175 @@
1
1
  Smalltalk current createPackage: 'Compiler' properties: #{}!
2
- Object subclass: #NodeVisitor
3
- instanceVariableNames: ''
4
- category: 'Compiler'!
2
+ Object subclass: #ChunkParser
3
+ instanceVariableNames: 'stream'
4
+ package: 'Compiler'!
5
5
 
6
- !NodeVisitor methodsFor: 'visiting'!
6
+ !ChunkParser methodsFor: 'accessing'!
7
7
 
8
- visit: aNode
9
- aNode accept: self
8
+ stream: aStream
9
+ stream := aStream
10
+ ! !
11
+
12
+ !ChunkParser methodsFor: 'reading'!
13
+
14
+ nextChunk
15
+ "The chunk format (Smalltalk Interchange Format or Fileout format)
16
+ is a trivial format but can be a bit tricky to understand:
17
+ - Uses the exclamation mark as delimiter of chunks.
18
+ - Inside a chunk a normal exclamation mark must be doubled.
19
+ - A non empty chunk must be a valid Smalltalk expression.
20
+ - A chunk on top level with a preceding empty chunk is an instruction chunk:
21
+ - The object created by the expression then takes over reading chunks.
22
+
23
+ This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
24
+
25
+ | char result chunk |
26
+ result := '' writeStream.
27
+ [char := stream next.
28
+ char notNil] whileTrue: [
29
+ char = '!!' ifTrue: [
30
+ stream peek = '!!'
31
+ ifTrue: [stream next "skipping the escape double"]
32
+ ifFalse: [^result contents trimBoth "chunk end marker found"]].
33
+ result nextPut: char].
34
+ ^nil "a chunk needs to end with !!"
35
+ ! !
36
+
37
+ !ChunkParser class methodsFor: 'not yet classified'!
38
+
39
+ on: aStream
40
+ ^self new stream: aStream
41
+ ! !
42
+
43
+ Object subclass: #Compiler
44
+ instanceVariableNames: 'currentClass source unknownVariables'
45
+ package: 'Compiler'!
46
+
47
+ !Compiler methodsFor: 'accessing'!
48
+
49
+ codeGeneratorClass
50
+ ^FunCodeGenerator
10
51
  !
11
52
 
12
- visitNode: aNode
53
+ currentClass
54
+ ^currentClass
13
55
  !
14
56
 
15
- visitMethodNode: aNode
16
- self visitNode: aNode
57
+ currentClass: aClass
58
+ currentClass := aClass
17
59
  !
18
60
 
19
- visitSequenceNode: aNode
20
- self visitNode: aNode
61
+ source
62
+ ^source ifNil: ['']
21
63
  !
22
64
 
23
- visitBlockSequenceNode: aNode
24
- self visitSequenceNode: aNode
65
+ source: aString
66
+ source := aString
25
67
  !
26
68
 
27
- visitBlockNode: aNode
28
- self visitNode: aNode
69
+ unknownVariables
70
+ ^unknownVariables
29
71
  !
30
72
 
31
- visitReturnNode: aNode
32
- self visitNode: aNode
73
+ unknownVariables: aCollection
74
+ unknownVariables := aCollection
75
+ ! !
76
+
77
+ !Compiler methodsFor: 'compiling'!
78
+
79
+ compile: aString
80
+ ^self compileNode: (self parse: aString)
33
81
  !
34
82
 
35
- visitSendNode: aNode
36
- self visitNode: aNode
83
+ compile: aString forClass: aClass
84
+ self currentClass: aClass.
85
+ self source: aString.
86
+ ^self compile: aString
37
87
  !
38
88
 
39
- visitCascadeNode: aNode
40
- self visitNode: aNode
89
+ compileExpression: aString
90
+ self currentClass: DoIt.
91
+ self source: 'doIt ^[', aString, '] value'.
92
+ ^self compileNode: (self parse: self source)
41
93
  !
42
94
 
43
- visitValueNode: aNode
44
- self visitNode: aNode
95
+ compileNode: aNode
96
+ | generator result |
97
+ generator := self codeGeneratorClass new.
98
+ generator
99
+ source: self source;
100
+ currentClass: self currentClass.
101
+ result := generator compileNode: aNode.
102
+ self unknownVariables: generator unknownVariables.
103
+ ^result
45
104
  !
46
105
 
47
- visitVariableNode: aNode
106
+ eval: aString
107
+ <return eval(aString)>
48
108
  !
49
109
 
50
- visitAssignmentNode: aNode
51
- self visitNode: aNode
110
+ evaluateExpression: aString
111
+ "Unlike #eval: evaluate a Smalltalk expression and answer the returned object"
112
+ | result |
113
+ DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).
114
+ result := DoIt new doIt.
115
+ DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').
116
+ ^result
52
117
  !
53
118
 
54
- visitClassReferenceNode: aNode
55
- self
56
- nextPutAll: 'smalltalk.';
57
- nextPutAll: aNode value
119
+ install: aString forClass: aBehavior category: anotherString
120
+ | compiled |
121
+ compiled := self eval: (self compile: aString forClass: aBehavior).
122
+ compiled category: anotherString.
123
+ aBehavior addCompiledMethod: compiled.
124
+ ^compiled
58
125
  !
59
126
 
60
- visitJSStatementNode: aNode
61
- self
62
- nextPutAll: 'function(){';
63
- nextPutAll: aNode source;
64
- nextPutAll: '})()'
127
+ parse: aString
128
+ ^Smalltalk current parse: aString
65
129
  !
66
130
 
67
- visitDynamicArrayNode: aNode
68
- self visitNode: aNode
131
+ parseExpression: aString
132
+ ^self parse: 'doIt ^[', aString, '] value'
69
133
  !
70
134
 
71
- visitDynamicDictionaryNode: aNode
72
- self visitNode: aNode
73
- ! !
135
+ recompile: aClass
136
+ aClass methodDictionary do: [:each |
137
+ self install: each source forClass: aClass category: each category].
138
+ self setupClass: aClass.
139
+ aClass isMetaclass ifFalse: [self recompile: aClass class]
140
+ !
74
141
 
75
- Object subclass: #DoIt
76
- instanceVariableNames: ''
77
- category: 'Compiler'!
142
+ recompileAll
143
+ Smalltalk current classes do: [:each |
144
+ Transcript show: each; cr.
145
+ [self recompile: each] valueWithTimeout: 100]
146
+ !
78
147
 
79
- Object subclass: #Importer
80
- instanceVariableNames: ''
81
- category: 'Compiler'!
148
+ setupClass: aClass
149
+ <smalltalk.init(aClass)>
150
+ ! !
82
151
 
83
- !Importer methodsFor: 'fileIn'!
152
+ !Compiler class methodsFor: 'compiling'!
84
153
 
85
- import: aStream
86
- | chunk result parser lastEmpty |
87
- parser := ChunkParser on: aStream.
88
- lastEmpty := false.
89
- [chunk := parser nextChunk.
90
- chunk isNil] whileFalse: [
91
- chunk isEmpty
92
- ifTrue: [lastEmpty := true]
93
- ifFalse: [
94
- result := Compiler new loadExpression: chunk.
95
- lastEmpty
96
- ifTrue: [
97
- lastEmpty := false.
98
- result scanFrom: parser]]]
154
+ recompile: aClass
155
+ self new recompile: aClass
156
+ !
157
+
158
+ recompileAll
159
+ Smalltalk current classes do: [:each |
160
+ self recompile: each]
99
161
  ! !
100
162
 
163
+ Object subclass: #DoIt
164
+ instanceVariableNames: ''
165
+ package: 'Compiler'!
166
+
101
167
  Object subclass: #Exporter
102
168
  instanceVariableNames: ''
103
- category: 'Compiler'!
169
+ package: 'Compiler'!
104
170
 
105
171
  !Exporter methodsFor: 'fileOut'!
106
172
 
107
- exportPackage: packageName
108
- "Export a given package by name."
109
-
110
- | package |
111
- ^String streamContents: [:stream |
112
- package := Smalltalk current packageAt: packageName.
113
- self exportPackageDefinitionOf: package on: stream.
114
- "Export classes in dependency order"
115
- package sortedClasses do: [:each |
116
- stream nextPutAll: (self exportClass: each)].
117
- self exportPackageExtensionsOf: package on: stream]
118
- !
119
-
120
173
  exportAll
121
174
  "Export all packages in the system."
122
175
 
@@ -133,10 +186,34 @@ exportClass: aClass
133
186
  self exportMethodsOf: aClass on: stream.
134
187
  self exportMetaDefinitionOf: aClass on: stream.
135
188
  self exportMethodsOf: aClass class on: stream]
189
+ !
190
+
191
+ exportPackage: packageName
192
+ "Export a given package by name."
193
+
194
+ | package |
195
+ ^String streamContents: [:stream |
196
+ package := Smalltalk current packageAt: packageName.
197
+ self exportPackageDefinitionOf: package on: stream.
198
+
199
+ "Export classes in dependency order.
200
+ Update (issue #171): Remove duplicates for export"
201
+ package sortedClasses asSet do: [:each |
202
+ stream nextPutAll: (self exportClass: each)].
203
+ self exportPackageExtensionsOf: package on: stream]
136
204
  ! !
137
205
 
138
206
  !Exporter methodsFor: 'private'!
139
207
 
208
+ classNameFor: aClass
209
+ ^aClass isMetaclass
210
+ ifTrue: [aClass instanceClass name, '.klass']
211
+ ifFalse: [
212
+ aClass isNil
213
+ ifTrue: ['nil']
214
+ ifFalse: [aClass name]]
215
+ !
216
+
140
217
  exportDefinitionOf: aClass on: aStream
141
218
  aStream
142
219
  nextPutAll: 'smalltalk.addClass(';
@@ -156,7 +233,7 @@ exportDefinitionOf: aClass on: aStream
156
233
  nextPutAll: 'smalltalk.';
157
234
  nextPutAll: (self classNameFor: aClass);
158
235
  nextPutAll: '.comment=';
159
- nextPutAll: 'unescape(''', aClass comment escaped, ''')'].
236
+ nextPutAll: aClass comment asJavascript].
160
237
  aStream lf
161
238
  !
162
239
 
@@ -171,32 +248,16 @@ exportMetaDefinitionOf: aClass on: aStream
171
248
  aStream nextPutAll: '];', String lf]
172
249
  !
173
250
 
174
- exportMethodsOf: aClass on: aStream
175
- aClass methodDictionary values do: [:each |
176
- (each category match: '^\*') ifFalse: [
177
- self exportMethod: each of: aClass on: aStream]].
178
- aStream lf
179
- !
180
-
181
- classNameFor: aClass
182
- ^aClass isMetaclass
183
- ifTrue: [aClass instanceClass name, '.klass']
184
- ifFalse: [
185
- aClass isNil
186
- ifTrue: ['nil']
187
- ifFalse: [aClass name]]
188
- !
189
-
190
251
  exportMethod: aMethod of: aClass on: aStream
191
252
  aStream
192
253
  nextPutAll: 'smalltalk.addMethod(';lf;
193
- nextPutAll: 'unescape(''', aMethod selector asSelector escaped, '''),';lf;
254
+ nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
194
255
  nextPutAll: 'smalltalk.method({';lf;
195
- nextPutAll: 'selector: unescape(''', aMethod selector escaped, '''),';lf;
256
+ nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
196
257
  nextPutAll: 'category: ''', aMethod category, ''',';lf;
197
258
  nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;
198
259
  nextPutAll: 'args: ', aMethod arguments asJavascript, ','; lf;
199
- nextPutAll: 'source: unescape(''', aMethod source escaped, '''),';lf;
260
+ nextPutAll: 'source: ', aMethod source asJavascript, ',';lf;
200
261
  nextPutAll: 'messageSends: ', aMethod messageSends asJavascript, ',';lf;
201
262
  nextPutAll: 'referencedClasses: ', aMethod referencedClasses asJavascript.
202
263
  aStream
@@ -206,13 +267,13 @@ exportMethod: aMethod of: aClass on: aStream
206
267
  nextPutAll: ');';lf;lf
207
268
  !
208
269
 
209
- exportPackageExtensionsOf: package on: aStream
210
- | name |
211
- name := package name.
212
- Smalltalk current classes, (Smalltalk current classes collect: [:each | each class]) do: [:each |
213
- each methodDictionary values do: [:method |
214
- method category = ('*', name) ifTrue: [
215
- self exportMethod: method of: each on: aStream]]]
270
+ exportMethodsOf: aClass on: aStream
271
+ "Issue #143: sort methods alphabetically"
272
+
273
+ ((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:each |
274
+ (each category match: '^\*') ifFalse: [
275
+ self exportMethod: each of: aClass on: aStream]].
276
+ aStream lf
216
277
  !
217
278
 
218
279
  exportPackageDefinitionOf: package on: aStream
@@ -220,61 +281,202 @@ exportPackageDefinitionOf: package on: aStream
220
281
  nextPutAll: 'smalltalk.addPackage(';
221
282
  nextPutAll: '''', package name, ''', ', package propertiesAsJSON , ');'.
222
283
  aStream lf
223
- ! !
224
-
225
- Object subclass: #ChunkParser
226
- instanceVariableNames: 'stream'
227
- category: 'Compiler'!
284
+ !
228
285
 
229
- !ChunkParser methodsFor: 'accessing'!
286
+ exportPackageExtensionsOf: package on: aStream
287
+ "Issue #143: sort classes and methods alphabetically"
230
288
 
231
- stream: aStream
232
- stream := aStream
289
+ | name |
290
+ name := package name.
291
+ (Package sortedClasses: Smalltalk current classes) do: [:each |
292
+ {each. each class} do: [:aClass |
293
+ ((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector]) do: [:method |
294
+ (method category match: '^\*', name) ifTrue: [
295
+ self exportMethod: method of: aClass on: aStream ]]]]
233
296
  ! !
234
297
 
235
- !ChunkParser methodsFor: 'reading'!
298
+ Exporter subclass: #ChunkExporter
299
+ instanceVariableNames: ''
300
+ package: 'Compiler'!
236
301
 
237
- nextChunk
238
- "The chunk format (Smalltalk Interchange Format or Fileout format)
239
- is a trivial format but can be a bit tricky to understand:
240
- - Uses the exclamation mark as delimiter of chunks.
241
- - Inside a chunk a normal exclamation mark must be doubled.
242
- - A non empty chunk must be a valid Smalltalk expression.
243
- - A chunk on top level with a preceding empty chunk is an instruction chunk:
244
- - The object created by the expression then takes over reading chunks.
302
+ !ChunkExporter methodsFor: 'not yet classified'!
245
303
 
246
- This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
304
+ chunkEscape: aString
305
+ "Replace all occurrences of !! with !!!! and trim at both ends."
247
306
 
248
- | char result chunk |
249
- result := '' writeStream.
250
- [char := stream next.
251
- char notNil] whileTrue: [
252
- char = '!!' ifTrue: [
253
- stream peek = '!!'
254
- ifTrue: [stream next "skipping the escape double"]
255
- ifFalse: [^result contents trimBoth "chunk end marker found"]].
256
- result nextPut: char].
257
- ^nil "a chunk needs to end with !!"
258
- ! !
307
+ ^(aString replace: '!!' with: '!!!!') trimBoth
308
+ !
259
309
 
260
- !ChunkParser class methodsFor: 'not yet classified'!
310
+ classNameFor: aClass
311
+ ^aClass isMetaclass
312
+ ifTrue: [aClass instanceClass name, ' class']
313
+ ifFalse: [
314
+ aClass isNil
315
+ ifTrue: ['nil']
316
+ ifFalse: [aClass name]]
317
+ !
261
318
 
262
- on: aStream
263
- ^self new stream: aStream
264
- ! !
319
+ exportDefinitionOf: aClass on: aStream
320
+ "Chunk format."
321
+
322
+ aStream
323
+ nextPutAll: (self classNameFor: aClass superclass);
324
+ nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;
325
+ nextPutAll: ' instanceVariableNames: '''.
326
+ aClass instanceVariableNames
327
+ do: [:each | aStream nextPutAll: each]
328
+ separatedBy: [aStream nextPutAll: ' '].
329
+ aStream
330
+ nextPutAll: ''''; lf;
331
+ nextPutAll: ' package: ''', aClass category, '''!!'; lf.
332
+ aClass comment notEmpty ifTrue: [
333
+ aStream
334
+ nextPutAll: '!!', (self classNameFor: aClass), ' commentStamp!!';lf;
335
+ nextPutAll: (self chunkEscape: aClass comment), '!!';lf].
336
+ aStream lf
337
+ !
338
+
339
+ exportMetaDefinitionOf: aClass on: aStream
340
+
341
+ aClass class instanceVariableNames isEmpty ifFalse: [
342
+ aStream
343
+ nextPutAll: (self classNameFor: aClass class);
344
+ nextPutAll: ' instanceVariableNames: '''.
345
+ aClass class instanceVariableNames
346
+ do: [:each | aStream nextPutAll: each]
347
+ separatedBy: [aStream nextPutAll: ' '].
348
+ aStream
349
+ nextPutAll: '''!!'; lf; lf]
350
+ !
351
+
352
+ exportMethod: aMethod of: aClass on: aStream
353
+ aStream
354
+ lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;
355
+ nextPutAll: '!!'
356
+ !
357
+
358
+ exportMethods: methods category: category of: aClass on: aStream
359
+ "Issue #143: sort methods alphabetically"
360
+
361
+ aStream
362
+ nextPutAll: '!!', (self classNameFor: aClass);
363
+ nextPutAll: ' methodsFor: ''', category, '''!!'.
364
+ (methods sorted: [:a :b | a selector <= b selector]) do: [:each |
365
+ self exportMethod: each of: aClass on: aStream].
366
+ aStream nextPutAll: ' !!'; lf; lf
367
+ !
368
+
369
+ exportMethodsOf: aClass on: aStream
370
+ "Issue #143: sort protocol alphabetically"
371
+
372
+ | map |
373
+ map := Dictionary new.
374
+ aClass protocolsDo: [:category :methods |
375
+ (category match: '^\*') ifFalse: [ map at: category put: methods ]].
376
+ (map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |
377
+ methods := map at: category.
378
+ self
379
+ exportMethods: methods
380
+ category: category
381
+ of: aClass
382
+ on: aStream ]
383
+ !
384
+
385
+ exportPackageDefinitionOf: package on: aStream
386
+ "Chunk format."
387
+
388
+ aStream
389
+ nextPutAll: 'Smalltalk current createPackage: ''', package name,
390
+ ''' properties: ', package properties storeString, '!!'; lf.
391
+ !
392
+
393
+ exportPackageExtensionsOf: package on: aStream
394
+ "We need to override this one too since we need to group
395
+ all methods in a given protocol under a leading methodsFor: chunk
396
+ for that class."
397
+
398
+ "Issue #143: sort protocol alphabetically"
399
+
400
+ | name map |
401
+ name := package name.
402
+ (Package sortedClasses: Smalltalk current classes) do: [:each |
403
+ {each. each class} do: [:aClass |
404
+ map := Dictionary new.
405
+ aClass protocolsDo: [:category :methods |
406
+ (category match: '^\*', name) ifTrue: [ map at: category put: methods ]].
407
+ (map keys sorted: [:a :b | a <= b ]) do: [:category | | methods |
408
+ methods := map at: category.
409
+ self exportMethods: methods category: category of: aClass on: aStream ]]]
410
+ ! !
411
+
412
+ Exporter subclass: #StrippedExporter
413
+ instanceVariableNames: ''
414
+ package: 'Compiler'!
415
+
416
+ !StrippedExporter methodsFor: 'private'!
417
+
418
+ exportDefinitionOf: aClass on: aStream
419
+ aStream
420
+ nextPutAll: 'smalltalk.addClass(';
421
+ nextPutAll: '''', (self classNameFor: aClass), ''', ';
422
+ nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
423
+ nextPutAll: ', ['.
424
+ aClass instanceVariableNames
425
+ do: [:each | aStream nextPutAll: '''', each, '''']
426
+ separatedBy: [aStream nextPutAll: ', '].
427
+ aStream
428
+ nextPutAll: '], ''';
429
+ nextPutAll: aClass category, '''';
430
+ nextPutAll: ');'.
431
+ aStream lf
432
+ !
433
+
434
+ exportMethod: aMethod of: aClass on: aStream
435
+ aStream
436
+ nextPutAll: 'smalltalk.addMethod(';lf;
437
+ nextPutAll: aMethod selector asSelector asJavascript, ',';lf;
438
+ nextPutAll: 'smalltalk.method({';lf;
439
+ nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
440
+ nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
441
+ nextPutAll: '}),';lf;
442
+ nextPutAll: 'smalltalk.', (self classNameFor: aClass);
443
+ nextPutAll: ');';lf;lf
444
+ ! !
445
+
446
+ Object subclass: #Importer
447
+ instanceVariableNames: ''
448
+ package: 'Compiler'!
449
+
450
+ !Importer methodsFor: 'fileIn'!
451
+
452
+ import: aStream
453
+ | chunk result parser lastEmpty |
454
+ parser := ChunkParser on: aStream.
455
+ lastEmpty := false.
456
+ [chunk := parser nextChunk.
457
+ chunk isNil] whileFalse: [
458
+ chunk isEmpty
459
+ ifTrue: [lastEmpty := true]
460
+ ifFalse: [
461
+ result := Compiler new evaluateExpression: chunk.
462
+ lastEmpty
463
+ ifTrue: [
464
+ lastEmpty := false.
465
+ result scanFrom: parser]]]
466
+ ! !
265
467
 
266
468
  Object subclass: #Node
267
469
  instanceVariableNames: 'nodes'
268
- category: 'Compiler'!
470
+ package: 'Compiler'!
269
471
 
270
472
  !Node methodsFor: 'accessing'!
271
473
 
272
- nodes
273
- ^nodes ifNil: [nodes := Array new]
274
- !
275
-
276
474
  addNode: aNode
277
475
  self nodes add: aNode
476
+ !
477
+
478
+ nodes
479
+ ^nodes ifNil: [nodes := Array new]
278
480
  ! !
279
481
 
280
482
  !Node methodsFor: 'building'!
@@ -285,15 +487,15 @@ nodes: aCollection
285
487
 
286
488
  !Node methodsFor: 'testing'!
287
489
 
288
- isValueNode
490
+ isBlockNode
289
491
  ^false
290
492
  !
291
493
 
292
- isBlockNode
494
+ isBlockSequenceNode
293
495
  ^false
294
496
  !
295
497
 
296
- isBlockSequenceNode
498
+ isValueNode
297
499
  ^false
298
500
  ! !
299
501
 
@@ -303,227 +505,181 @@ accept: aVisitor
303
505
  aVisitor visitNode: self
304
506
  ! !
305
507
 
306
- Node subclass: #SequenceNode
307
- instanceVariableNames: 'temps'
308
- category: 'Compiler'!
508
+ Node subclass: #AssignmentNode
509
+ instanceVariableNames: 'left right'
510
+ package: 'Compiler'!
309
511
 
310
- !SequenceNode methodsFor: 'accessing'!
512
+ !AssignmentNode methodsFor: 'accessing'!
311
513
 
312
- temps
313
- ^temps ifNil: [#()]
514
+ left
515
+ ^left
314
516
  !
315
517
 
316
- temps: aCollection
317
- temps := aCollection
318
- ! !
518
+ left: aNode
519
+ left := aNode.
520
+ left assigned: true
521
+ !
319
522
 
320
- !SequenceNode methodsFor: 'testing'!
523
+ right
524
+ ^right
525
+ !
321
526
 
322
- asBlockSequenceNode
323
- ^BlockSequenceNode new
324
- nodes: self nodes;
325
- temps: self temps;
326
- yourself
527
+ right: aNode
528
+ right := aNode
327
529
  ! !
328
530
 
329
- !SequenceNode methodsFor: 'visiting'!
531
+ !AssignmentNode methodsFor: 'visiting'!
330
532
 
331
533
  accept: aVisitor
332
- aVisitor visitSequenceNode: self
534
+ aVisitor visitAssignmentNode: self
333
535
  ! !
334
536
 
335
- Node subclass: #DynamicDictionaryNode
336
- instanceVariableNames: ''
337
- category: 'Compiler'!
537
+ Node subclass: #BlockNode
538
+ instanceVariableNames: 'parameters inlined'
539
+ package: 'Compiler'!
338
540
 
339
- !DynamicDictionaryNode methodsFor: 'visiting'!
541
+ !BlockNode methodsFor: 'accessing'!
340
542
 
341
- accept: aVisitor
342
- aVisitor visitDynamicDictionaryNode: self
543
+ inlined
544
+ ^inlined ifNil: [false]
545
+ !
546
+
547
+ inlined: aBoolean
548
+ inlined := aBoolean
549
+ !
550
+
551
+ parameters
552
+ ^parameters ifNil: [parameters := Array new]
553
+ !
554
+
555
+ parameters: aCollection
556
+ parameters := aCollection
343
557
  ! !
344
558
 
345
- Node subclass: #ReturnNode
346
- instanceVariableNames: ''
347
- category: 'Compiler'!
559
+ !BlockNode methodsFor: 'testing'!
348
560
 
349
- !ReturnNode methodsFor: 'visiting'!
561
+ isBlockNode
562
+ ^true
563
+ ! !
564
+
565
+ !BlockNode methodsFor: 'visiting'!
350
566
 
351
567
  accept: aVisitor
352
- aVisitor visitReturnNode: self
568
+ aVisitor visitBlockNode: self
353
569
  ! !
354
570
 
355
- Node subclass: #ValueNode
356
- instanceVariableNames: 'value'
357
- category: 'Compiler'!
571
+ Node subclass: #CascadeNode
572
+ instanceVariableNames: 'receiver'
573
+ package: 'Compiler'!
358
574
 
359
- !ValueNode methodsFor: 'accessing'!
575
+ !CascadeNode methodsFor: 'accessing'!
360
576
 
361
- value
362
- ^value
577
+ receiver
578
+ ^receiver
363
579
  !
364
580
 
365
- value: anObject
366
- value := anObject
581
+ receiver: aNode
582
+ receiver := aNode
367
583
  ! !
368
584
 
369
- !ValueNode methodsFor: 'testing'!
585
+ !CascadeNode methodsFor: 'visiting'!
370
586
 
371
- isValueNode
372
- ^true
587
+ accept: aVisitor
588
+ aVisitor visitCascadeNode: self
373
589
  ! !
374
590
 
375
- !ValueNode methodsFor: 'visiting'!
591
+ Node subclass: #DynamicArrayNode
592
+ instanceVariableNames: ''
593
+ package: 'Compiler'!
594
+
595
+ !DynamicArrayNode methodsFor: 'visiting'!
376
596
 
377
597
  accept: aVisitor
378
- aVisitor visitValueNode: self
598
+ aVisitor visitDynamicArrayNode: self
379
599
  ! !
380
600
 
381
- ValueNode subclass: #VariableNode
382
- instanceVariableNames: 'assigned'
383
- category: 'Compiler'!
601
+ Node subclass: #DynamicDictionaryNode
602
+ instanceVariableNames: ''
603
+ package: 'Compiler'!
384
604
 
385
- !VariableNode methodsFor: 'accessing'!
605
+ !DynamicDictionaryNode methodsFor: 'visiting'!
386
606
 
387
- assigned
388
- ^assigned ifNil: [false]
607
+ accept: aVisitor
608
+ aVisitor visitDynamicDictionaryNode: self
609
+ ! !
610
+
611
+ Node subclass: #JSStatementNode
612
+ instanceVariableNames: 'source'
613
+ package: 'Compiler'!
614
+
615
+ !JSStatementNode methodsFor: 'accessing'!
616
+
617
+ source
618
+ ^source ifNil: ['']
389
619
  !
390
620
 
391
- assigned: aBoolean
392
- assigned := aBoolean
621
+ source: aString
622
+ source := aString
393
623
  ! !
394
624
 
395
- !VariableNode methodsFor: 'visiting'!
625
+ !JSStatementNode methodsFor: 'visiting'!
396
626
 
397
627
  accept: aVisitor
398
- aVisitor visitVariableNode: self
628
+ aVisitor visitJSStatementNode: self
399
629
  ! !
400
630
 
401
- Exporter subclass: #ChunkExporter
402
- instanceVariableNames: ''
403
- category: 'Compiler'!
631
+ Node subclass: #MethodNode
632
+ instanceVariableNames: 'selector arguments source'
633
+ package: 'Compiler'!
404
634
 
405
- !ChunkExporter methodsFor: 'not yet classified'!
635
+ !MethodNode methodsFor: 'accessing'!
406
636
 
407
- exportDefinitionOf: aClass on: aStream
408
- "Chunk format."
637
+ arguments
638
+ ^arguments ifNil: [#()]
639
+ !
409
640
 
410
- aStream
411
- nextPutAll: (self classNameFor: aClass superclass);
412
- nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;
413
- nextPutAll: ' instanceVariableNames: '''.
414
- aClass instanceVariableNames
415
- do: [:each | aStream nextPutAll: each]
416
- separatedBy: [aStream nextPutAll: ' '].
417
- aStream
418
- nextPutAll: ''''; lf;
419
- nextPutAll: ' category: ''', aClass category, '''!!'; lf.
420
- aClass comment notEmpty ifTrue: [
421
- aStream
422
- nextPutAll: '!!', (self classNameFor: aClass), ' commentStamp!!';lf;
423
- nextPutAll: (self chunkEscape: aClass comment), '!!';lf].
424
- aStream lf
641
+ arguments: aCollection
642
+ arguments := aCollection
425
643
  !
426
644
 
427
- exportMethod: aMethod of: aClass on: aStream
428
- aStream
429
- lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;
430
- nextPutAll: '!!'
431
- !
432
-
433
- exportMethodsOf: aClass on: aStream
434
-
435
- aClass protocolsDo: [:category :methods |
436
- (category match: '^\*') ifFalse: [
437
- self
438
- exportMethods: methods
439
- category: category
440
- of: aClass
441
- on: aStream]]
442
- !
443
-
444
- exportMetaDefinitionOf: aClass on: aStream
445
-
446
- aClass class instanceVariableNames isEmpty ifFalse: [
447
- aStream
448
- nextPutAll: (self classNameFor: aClass class);
449
- nextPutAll: ' instanceVariableNames: '''.
450
- aClass class instanceVariableNames
451
- do: [:each | aStream nextPutAll: each]
452
- separatedBy: [aStream nextPutAll: ' '].
453
- aStream
454
- nextPutAll: '''!!'; lf; lf]
455
- !
456
-
457
- classNameFor: aClass
458
- ^aClass isMetaclass
459
- ifTrue: [aClass instanceClass name, ' class']
460
- ifFalse: [
461
- aClass isNil
462
- ifTrue: ['nil']
463
- ifFalse: [aClass name]]
645
+ selector
646
+ ^selector
464
647
  !
465
648
 
466
- chunkEscape: aString
467
- "Replace all occurrences of !! with !!!! and trim at both ends."
468
-
469
- ^(aString replace: '!!' with: '!!!!') trimBoth
649
+ selector: aString
650
+ selector := aString
470
651
  !
471
652
 
472
- exportMethods: methods category: category of: aClass on: aStream
473
-
474
- aStream
475
- nextPutAll: '!!', (self classNameFor: aClass);
476
- nextPutAll: ' methodsFor: ''', category, '''!!'.
477
- methods do: [:each |
478
- self exportMethod: each of: aClass on: aStream].
479
- aStream nextPutAll: ' !!'; lf; lf
653
+ source
654
+ ^source
480
655
  !
481
656
 
482
- exportPackageExtensionsOf: package on: aStream
483
- "We need to override this one too since we need to group
484
- all methods in a given protocol under a leading methodsFor: chunk
485
- for that class."
486
-
487
- | name |
488
- name := package name.
489
- Smalltalk current classes, (Smalltalk current classes collect: [:each | each class]) do: [:each |
490
- each protocolsDo: [:category :methods |
491
- category = ('*', name) ifTrue: [
492
- self exportMethods: methods category: category of: each on: aStream]]]
493
- !
657
+ source: aString
658
+ source := aString
659
+ ! !
494
660
 
495
- exportPackageDefinitionOf: package on: aStream
496
- "Chunk format."
661
+ !MethodNode methodsFor: 'visiting'!
497
662
 
498
- aStream
499
- nextPutAll: 'Smalltalk current createPackage: ''', package name,
500
- ''' properties: ', package properties storeString, '!!'; lf.
663
+ accept: aVisitor
664
+ aVisitor visitMethodNode: self
501
665
  ! !
502
666
 
503
- VariableNode subclass: #ClassReferenceNode
667
+ Node subclass: #ReturnNode
504
668
  instanceVariableNames: ''
505
- category: 'Compiler'!
669
+ package: 'Compiler'!
506
670
 
507
- !ClassReferenceNode methodsFor: 'visiting'!
671
+ !ReturnNode methodsFor: 'visiting'!
508
672
 
509
673
  accept: aVisitor
510
- aVisitor visitClassReferenceNode: self
674
+ aVisitor visitReturnNode: self
511
675
  ! !
512
676
 
513
677
  Node subclass: #SendNode
514
678
  instanceVariableNames: 'selector arguments receiver'
515
- category: 'Compiler'!
679
+ package: 'Compiler'!
516
680
 
517
681
  !SendNode methodsFor: 'accessing'!
518
682
 
519
- selector
520
- ^selector
521
- !
522
-
523
- selector: aString
524
- selector := aString
525
- !
526
-
527
683
  arguments
528
684
  ^arguments ifNil: [arguments := #()]
529
685
  !
@@ -532,6 +688,18 @@ arguments: aCollection
532
688
  arguments := aCollection
533
689
  !
534
690
 
691
+ cascadeNodeWithMessages: aCollection
692
+ | first |
693
+ first := SendNode new
694
+ selector: self selector;
695
+ arguments: self arguments;
696
+ yourself.
697
+ ^CascadeNode new
698
+ receiver: self receiver;
699
+ nodes: (Array with: first), aCollection;
700
+ yourself
701
+ !
702
+
535
703
  receiver
536
704
  ^receiver
537
705
  !
@@ -540,6 +708,14 @@ receiver: aNode
540
708
  receiver := aNode
541
709
  !
542
710
 
711
+ selector
712
+ ^selector
713
+ !
714
+
715
+ selector: aString
716
+ selector := aString
717
+ !
718
+
543
719
  valueForReceiver: anObject
544
720
  ^SendNode new
545
721
  receiver: (self receiver
@@ -548,18 +724,6 @@ valueForReceiver: anObject
548
724
  selector: self selector;
549
725
  arguments: self arguments;
550
726
  yourself
551
- !
552
-
553
- cascadeNodeWithMessages: aCollection
554
- | first |
555
- first := SendNode new
556
- selector: self selector;
557
- arguments: self arguments;
558
- yourself.
559
- ^CascadeNode new
560
- receiver: self receiver;
561
- nodes: (Array with: first), aCollection;
562
- yourself
563
727
  ! !
564
728
 
565
729
  !SendNode methodsFor: 'visiting'!
@@ -568,199 +732,257 @@ accept: aVisitor
568
732
  aVisitor visitSendNode: self
569
733
  ! !
570
734
 
571
- Node subclass: #JSStatementNode
572
- instanceVariableNames: 'source'
573
- category: 'Compiler'!
735
+ Node subclass: #SequenceNode
736
+ instanceVariableNames: 'temps'
737
+ package: 'Compiler'!
574
738
 
575
- !JSStatementNode methodsFor: 'accessing'!
739
+ !SequenceNode methodsFor: 'accessing'!
576
740
 
577
- source
578
- ^source ifNil: ['']
741
+ temps
742
+ ^temps ifNil: [#()]
579
743
  !
580
744
 
581
- source: aString
582
- source := aString
745
+ temps: aCollection
746
+ temps := aCollection
583
747
  ! !
584
748
 
585
- !JSStatementNode methodsFor: 'visiting'!
749
+ !SequenceNode methodsFor: 'testing'!
750
+
751
+ asBlockSequenceNode
752
+ ^BlockSequenceNode new
753
+ nodes: self nodes;
754
+ temps: self temps;
755
+ yourself
756
+ ! !
757
+
758
+ !SequenceNode methodsFor: 'visiting'!
586
759
 
587
760
  accept: aVisitor
588
- aVisitor visitJSStatementNode: self
761
+ aVisitor visitSequenceNode: self
589
762
  ! !
590
763
 
591
- Node subclass: #AssignmentNode
592
- instanceVariableNames: 'left right'
593
- category: 'Compiler'!
764
+ SequenceNode subclass: #BlockSequenceNode
765
+ instanceVariableNames: ''
766
+ package: 'Compiler'!
594
767
 
595
- !AssignmentNode methodsFor: 'accessing'!
768
+ !BlockSequenceNode methodsFor: 'testing'!
596
769
 
597
- left
598
- ^left
599
- !
770
+ isBlockSequenceNode
771
+ ^true
772
+ ! !
600
773
 
601
- left: aNode
602
- left := aNode.
603
- left assigned: true
774
+ !BlockSequenceNode methodsFor: 'visiting'!
775
+
776
+ accept: aVisitor
777
+ aVisitor visitBlockSequenceNode: self
778
+ ! !
779
+
780
+ Node subclass: #ValueNode
781
+ instanceVariableNames: 'value'
782
+ package: 'Compiler'!
783
+
784
+ !ValueNode methodsFor: 'accessing'!
785
+
786
+ value
787
+ ^value
604
788
  !
605
789
 
606
- right
607
- ^right
790
+ value: anObject
791
+ value := anObject
792
+ ! !
793
+
794
+ !ValueNode methodsFor: 'testing'!
795
+
796
+ isValueNode
797
+ ^true
798
+ ! !
799
+
800
+ !ValueNode methodsFor: 'visiting'!
801
+
802
+ accept: aVisitor
803
+ aVisitor visitValueNode: self
804
+ ! !
805
+
806
+ ValueNode subclass: #VariableNode
807
+ instanceVariableNames: 'assigned'
808
+ package: 'Compiler'!
809
+
810
+ !VariableNode methodsFor: 'accessing'!
811
+
812
+ assigned
813
+ ^assigned ifNil: [false]
608
814
  !
609
815
 
610
- right: aNode
611
- right := aNode
816
+ assigned: aBoolean
817
+ assigned := aBoolean
612
818
  ! !
613
819
 
614
- !AssignmentNode methodsFor: 'visiting'!
820
+ !VariableNode methodsFor: 'visiting'!
615
821
 
616
822
  accept: aVisitor
617
- aVisitor visitAssignmentNode: self
823
+ aVisitor visitVariableNode: self
618
824
  ! !
619
825
 
620
- Node subclass: #DynamicArrayNode
826
+ VariableNode subclass: #ClassReferenceNode
621
827
  instanceVariableNames: ''
622
- category: 'Compiler'!
828
+ package: 'Compiler'!
623
829
 
624
- !DynamicArrayNode methodsFor: 'visiting'!
830
+ !ClassReferenceNode methodsFor: 'visiting'!
625
831
 
626
832
  accept: aVisitor
627
- aVisitor visitDynamicArrayNode: self
833
+ aVisitor visitClassReferenceNode: self
628
834
  ! !
629
835
 
630
- NodeVisitor subclass: #Compiler
631
- instanceVariableNames: 'stream nestedBlocks earlyReturn currentClass currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced source argVariables'
632
- category: 'Compiler'!
836
+ Object subclass: #NodeVisitor
837
+ instanceVariableNames: ''
838
+ package: 'Compiler'!
633
839
 
634
- !Compiler methodsFor: 'accessing'!
840
+ !NodeVisitor methodsFor: 'visiting'!
635
841
 
636
- parser
637
- ^SmalltalkParser new
842
+ visit: aNode
843
+ aNode accept: self
638
844
  !
639
845
 
640
- currentClass
641
- ^currentClass
846
+ visitAssignmentNode: aNode
847
+ self visitNode: aNode
642
848
  !
643
849
 
644
- currentClass: aClass
645
- currentClass := aClass
850
+ visitBlockNode: aNode
851
+ self visitNode: aNode
646
852
  !
647
853
 
648
- unknownVariables
649
- ^unknownVariables copy
854
+ visitBlockSequenceNode: aNode
855
+ self visitNode: aNode
650
856
  !
651
857
 
652
- pseudoVariables
653
- ^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
858
+ visitCascadeNode: aNode
859
+ self visitNode: aNode
654
860
  !
655
861
 
656
- tempVariables
657
- ^tempVariables copy
862
+ visitClassReferenceNode: aNode
863
+ self visitNode: aNode
658
864
  !
659
865
 
660
- knownVariables
661
- ^self pseudoVariables
662
- addAll: self tempVariables;
663
- addAll: self argVariables;
664
- yourself
866
+ visitDynamicArrayNode: aNode
867
+ self visitNode: aNode
665
868
  !
666
869
 
667
- classNameFor: aClass
668
- ^aClass isMetaclass
669
- ifTrue: [aClass instanceClass name, '.klass']
670
- ifFalse: [
671
- aClass isNil
672
- ifTrue: ['nil']
673
- ifFalse: [aClass name]]
870
+ visitDynamicDictionaryNode: aNode
871
+ self visitNode: aNode
674
872
  !
675
873
 
676
- source
677
- ^source ifNil: ['']
874
+ visitJSStatementNode: aNode
875
+ self visitNode: aNode
678
876
  !
679
877
 
680
- source: aString
681
- source := aString
878
+ visitMethodNode: aNode
879
+ self visitNode: aNode
682
880
  !
683
881
 
684
- argVariables
685
- ^argVariables copy
882
+ visitNode: aNode
686
883
  !
687
884
 
688
- safeVariableNameFor: aString
689
- ^(Smalltalk current reservedWords includes: aString)
690
- ifTrue: [aString, '_']
691
- ifFalse: [aString]
692
- ! !
885
+ visitReturnNode: aNode
886
+ self visitNode: aNode
887
+ !
693
888
 
694
- !Compiler methodsFor: 'compiling'!
889
+ visitSendNode: aNode
890
+ self visitNode: aNode
891
+ !
695
892
 
696
- loadExpression: aString
697
- | result |
698
- DoIt addCompiledMethod: (self eval: (self compileExpression: aString)).
699
- result := DoIt new doIt.
700
- DoIt removeCompiledMethod: (DoIt methodDictionary at: 'doIt').
701
- ^result
893
+ visitSequenceNode: aNode
894
+ self visitNode: aNode
702
895
  !
703
896
 
704
- load: aString forClass: aClass
705
- | compiled |
706
- compiled := self eval: (self compile: aString forClass: aClass).
707
- self setupClass: aClass.
708
- ^compiled
897
+ visitValueNode: aNode
898
+ self visitNode: aNode
709
899
  !
710
900
 
711
- compile: aString forClass: aClass
712
- self currentClass: aClass.
713
- self source: aString.
714
- ^self compile: aString
901
+ visitVariableNode: aNode
902
+ self visitNode: aNode
903
+ ! !
904
+
905
+ NodeVisitor subclass: #AbstractCodeGenerator
906
+ instanceVariableNames: 'currentClass source'
907
+ package: 'Compiler'!
908
+
909
+ !AbstractCodeGenerator methodsFor: 'accessing'!
910
+
911
+ classNameFor: aClass
912
+ ^aClass isMetaclass
913
+ ifTrue: [aClass instanceClass name, '.klass']
914
+ ifFalse: [
915
+ aClass isNil
916
+ ifTrue: ['nil']
917
+ ifFalse: [aClass name]]
715
918
  !
716
919
 
717
- compileExpression: aString
718
- self currentClass: DoIt.
719
- self source: 'doIt ^[', aString, '] value'.
720
- ^self compileNode: (self parse: self source)
920
+ currentClass
921
+ ^currentClass
721
922
  !
722
923
 
723
- eval: aString
724
- <return eval(aString)>
924
+ currentClass: aClass
925
+ currentClass := aClass
725
926
  !
726
927
 
727
- compile: aString
728
- ^self compileNode: (self parse: aString)
928
+ pseudoVariables
929
+ ^#('self' 'super' 'true' 'false' 'nil' 'thisContext')
729
930
  !
730
931
 
731
- compileNode: aNode
732
- stream := '' writeStream.
733
- self visit: aNode.
734
- ^stream contents
932
+ safeVariableNameFor: aString
933
+ ^(Smalltalk current reservedWords includes: aString)
934
+ ifTrue: [aString, '_']
935
+ ifFalse: [aString]
735
936
  !
736
937
 
737
- parse: aString
738
- ^Smalltalk current parse: aString
938
+ source
939
+ ^source ifNil: ['']
739
940
  !
740
941
 
741
- parseExpression: aString
742
- ^self parse: 'doIt ^[', aString, '] value'
942
+ source: aString
943
+ source := aString
944
+ ! !
945
+
946
+ !AbstractCodeGenerator methodsFor: 'compiling'!
947
+
948
+ compileNode: aNode
949
+ self subclassResponsibility
950
+ ! !
951
+
952
+ AbstractCodeGenerator subclass: #FunCodeGenerator
953
+ instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables'
954
+ package: 'Compiler'!
955
+
956
+ !FunCodeGenerator methodsFor: 'accessing'!
957
+
958
+ argVariables
959
+ ^argVariables copy
743
960
  !
744
961
 
745
- recompile: aClass
746
- aClass methodDictionary do: [:each || method |
747
- method := self load: each source forClass: aClass.
748
- method category: each category.
749
- aClass addCompiledMethod: method].
750
- aClass isMetaclass ifFalse: [self recompile: aClass class]
962
+ knownVariables
963
+ ^self pseudoVariables
964
+ addAll: self tempVariables;
965
+ addAll: self argVariables;
966
+ yourself
751
967
  !
752
968
 
753
- recompileAll
754
- Smalltalk current classes do: [:each |
755
- Transcript show: each; cr.
756
- [self recompile: each] valueWithTimeout: 100]
969
+ tempVariables
970
+ ^tempVariables copy
757
971
  !
758
972
 
759
- setupClass: aClass
760
- <smalltalk.init(aClass)>
973
+ unknownVariables
974
+ ^unknownVariables copy
975
+ ! !
976
+
977
+ !FunCodeGenerator methodsFor: 'compiling'!
978
+
979
+ compileNode: aNode
980
+ stream := '' writeStream.
981
+ self visit: aNode.
982
+ ^stream contents
761
983
  ! !
762
984
 
763
- !Compiler methodsFor: 'initialization'!
985
+ !FunCodeGenerator methodsFor: 'initialization'!
764
986
 
765
987
  initialize
766
988
  super initialize.
@@ -772,12 +994,107 @@ initialize
772
994
  classReferenced := #()
773
995
  ! !
774
996
 
775
- !Compiler methodsFor: 'optimizations'!
997
+ !FunCodeGenerator methodsFor: 'optimizations'!
776
998
 
777
999
  checkClass: aClassName for: receiver
778
1000
  stream nextPutAll: '((($receiver = ', receiver, ').klass === smalltalk.', aClassName, ') ? '
779
1001
  !
780
1002
 
1003
+ inline: aSelector receiver: receiver argumentNodes: aCollection
1004
+ | inlined |
1005
+ inlined := false.
1006
+
1007
+ "-- Booleans --"
1008
+
1009
+ (aSelector = 'ifFalse:') ifTrue: [
1010
+ aCollection first isBlockNode ifTrue: [
1011
+ self checkClass: 'Boolean' for: receiver.
1012
+ stream nextPutAll: '(!! $receiver ? '.
1013
+ self visit: aCollection first.
1014
+ stream nextPutAll: '() : nil)'.
1015
+ inlined := true]].
1016
+
1017
+ (aSelector = 'ifTrue:') ifTrue: [
1018
+ aCollection first isBlockNode ifTrue: [
1019
+ self checkClass: 'Boolean' for: receiver.
1020
+ stream nextPutAll: '($receiver ? '.
1021
+ self visit: aCollection first.
1022
+ stream nextPutAll: '() : nil)'.
1023
+ inlined := true]].
1024
+
1025
+ (aSelector = 'ifTrue:ifFalse:') ifTrue: [
1026
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
1027
+ self checkClass: 'Boolean' for: receiver.
1028
+ stream nextPutAll: '($receiver ? '.
1029
+ self visit: aCollection first.
1030
+ stream nextPutAll: '() : '.
1031
+ self visit: aCollection second.
1032
+ stream nextPutAll: '())'.
1033
+ inlined := true]].
1034
+
1035
+ (aSelector = 'ifFalse:ifTrue:') ifTrue: [
1036
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
1037
+ self checkClass: 'Boolean' for: receiver.
1038
+ stream nextPutAll: '(!! $receiver ? '.
1039
+ self visit: aCollection first.
1040
+ stream nextPutAll: '() : '.
1041
+ self visit: aCollection second.
1042
+ stream nextPutAll: '())'.
1043
+ inlined := true]].
1044
+
1045
+ "-- Numbers --"
1046
+
1047
+ (aSelector = '<') ifTrue: [
1048
+ self checkClass: 'Number' for: receiver.
1049
+ stream nextPutAll: '$receiver <'.
1050
+ self visit: aCollection first.
1051
+ inlined := true].
1052
+
1053
+ (aSelector = '<=') ifTrue: [
1054
+ self checkClass: 'Number' for: receiver.
1055
+ stream nextPutAll: '$receiver <='.
1056
+ self visit: aCollection first.
1057
+ inlined := true].
1058
+
1059
+ (aSelector = '>') ifTrue: [
1060
+ self checkClass: 'Number' for: receiver.
1061
+ stream nextPutAll: '$receiver >'.
1062
+ self visit: aCollection first.
1063
+ inlined := true].
1064
+
1065
+ (aSelector = '>=') ifTrue: [
1066
+ self checkClass: 'Number' for: receiver.
1067
+ stream nextPutAll: '$receiver >='.
1068
+ self visit: aCollection first.
1069
+ inlined := true].
1070
+
1071
+ (aSelector = '+') ifTrue: [
1072
+ self checkClass: 'Number' for: receiver.
1073
+ stream nextPutAll: '$receiver +'.
1074
+ self visit: aCollection first.
1075
+ inlined := true].
1076
+
1077
+ (aSelector = '-') ifTrue: [
1078
+ self checkClass: 'Number' for: receiver.
1079
+ stream nextPutAll: '$receiver -'.
1080
+ self visit: aCollection first.
1081
+ inlined := true].
1082
+
1083
+ (aSelector = '*') ifTrue: [
1084
+ self checkClass: 'Number' for: receiver.
1085
+ stream nextPutAll: '$receiver *'.
1086
+ self visit: aCollection first.
1087
+ inlined := true].
1088
+
1089
+ (aSelector = '/') ifTrue: [
1090
+ self checkClass: 'Number' for: receiver.
1091
+ stream nextPutAll: '$receiver /'.
1092
+ self visit: aCollection first.
1093
+ inlined := true].
1094
+
1095
+ ^inlined
1096
+ !
1097
+
781
1098
  inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
782
1099
  | inlined |
783
1100
  inlined := false.
@@ -923,113 +1240,124 @@ isNode: aNode ofClass: aClass
923
1240
  ^aNode isValueNode and: [
924
1241
  aNode value class = aClass or: [
925
1242
  aNode value = 'self' and: [self currentClass = aClass]]]
926
- !
1243
+ ! !
927
1244
 
928
- inline: aSelector receiver: receiver argumentNodes: aCollection
929
- | inlined |
930
- inlined := false.
1245
+ !FunCodeGenerator methodsFor: 'testing'!
931
1246
 
932
- "-- Booleans --"
1247
+ performOptimizations
1248
+ ^self class performOptimizations
1249
+ ! !
933
1250
 
934
- (aSelector = 'ifFalse:') ifTrue: [
935
- aCollection first isBlockNode ifTrue: [
936
- self checkClass: 'Boolean' for: receiver.
937
- stream nextPutAll: '(!! $receiver ? '.
938
- self visit: aCollection first.
939
- stream nextPutAll: '() : nil)'.
940
- inlined := true]].
1251
+ !FunCodeGenerator methodsFor: 'visiting'!
941
1252
 
942
- (aSelector = 'ifTrue:') ifTrue: [
943
- aCollection first isBlockNode ifTrue: [
944
- self checkClass: 'Boolean' for: receiver.
945
- stream nextPutAll: '($receiver ? '.
946
- self visit: aCollection first.
947
- stream nextPutAll: '() : nil)'.
948
- inlined := true]].
1253
+ send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
1254
+ ^String streamContents: [:str || tmp |
1255
+ tmp := stream.
1256
+ str nextPutAll: 'smalltalk.send('.
1257
+ str nextPutAll: aReceiver.
1258
+ str nextPutAll: ', "', aSelector asSelector, '", ['.
1259
+ stream := str.
1260
+ aCollection
1261
+ do: [:each | self visit: each]
1262
+ separatedBy: [stream nextPutAll: ', '].
1263
+ stream := tmp.
1264
+ str nextPutAll: ']'.
1265
+ aBoolean ifTrue: [
1266
+ str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass), '.superclass || nil'].
1267
+ str nextPutAll: ')']
1268
+ !
949
1269
 
950
- (aSelector = 'ifTrue:ifFalse:') ifTrue: [
951
- (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
952
- self checkClass: 'Boolean' for: receiver.
953
- stream nextPutAll: '($receiver ? '.
954
- self visit: aCollection first.
955
- stream nextPutAll: '() : '.
956
- self visit: aCollection second.
957
- stream nextPutAll: '())'.
958
- inlined := true]].
1270
+ visit: aNode
1271
+ aNode accept: self
1272
+ !
959
1273
 
960
- (aSelector = 'ifFalse:ifTrue:') ifTrue: [
961
- (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
962
- self checkClass: 'Boolean' for: receiver.
963
- stream nextPutAll: '(!! $receiver ? '.
964
- self visit: aCollection first.
965
- stream nextPutAll: '() : '.
966
- self visit: aCollection second.
967
- stream nextPutAll: '())'.
968
- inlined := true]].
969
-
970
- "-- Numbers --"
971
-
972
- (aSelector = '<') ifTrue: [
973
- self checkClass: 'Number' for: receiver.
974
- stream nextPutAll: '$receiver <'.
975
- self visit: aCollection first.
976
- inlined := true].
977
-
978
- (aSelector = '<=') ifTrue: [
979
- self checkClass: 'Number' for: receiver.
980
- stream nextPutAll: '$receiver <='.
981
- self visit: aCollection first.
982
- inlined := true].
983
-
984
- (aSelector = '>') ifTrue: [
985
- self checkClass: 'Number' for: receiver.
986
- stream nextPutAll: '$receiver >'.
987
- self visit: aCollection first.
988
- inlined := true].
989
-
990
- (aSelector = '>=') ifTrue: [
991
- self checkClass: 'Number' for: receiver.
992
- stream nextPutAll: '$receiver >='.
993
- self visit: aCollection first.
994
- inlined := true].
995
-
996
- (aSelector = '+') ifTrue: [
997
- self checkClass: 'Number' for: receiver.
998
- stream nextPutAll: '$receiver +'.
999
- self visit: aCollection first.
1000
- inlined := true].
1274
+ visitAssignmentNode: aNode
1275
+ stream nextPutAll: '('.
1276
+ self visit: aNode left.
1277
+ stream nextPutAll: '='.
1278
+ self visit: aNode right.
1279
+ stream nextPutAll: ')'
1280
+ !
1001
1281
 
1002
- (aSelector = '-') ifTrue: [
1003
- self checkClass: 'Number' for: receiver.
1004
- stream nextPutAll: '$receiver -'.
1005
- self visit: aCollection first.
1006
- inlined := true].
1282
+ visitBlockNode: aNode
1283
+ stream nextPutAll: '(function('.
1284
+ aNode parameters
1285
+ do: [:each |
1286
+ tempVariables add: each.
1287
+ stream nextPutAll: each]
1288
+ separatedBy: [stream nextPutAll: ', '].
1289
+ stream nextPutAll: '){'.
1290
+ aNode nodes do: [:each | self visit: each].
1291
+ stream nextPutAll: '})'
1292
+ !
1007
1293
 
1008
- (aSelector = '*') ifTrue: [
1009
- self checkClass: 'Number' for: receiver.
1010
- stream nextPutAll: '$receiver *'.
1011
- self visit: aCollection first.
1012
- inlined := true].
1294
+ visitBlockSequenceNode: aNode
1295
+ | index |
1296
+ nestedBlocks := nestedBlocks + 1.
1297
+ aNode nodes isEmpty
1298
+ ifTrue: [
1299
+ stream nextPutAll: 'return nil;']
1300
+ ifFalse: [
1301
+ aNode temps do: [:each | | temp |
1302
+ temp := self safeVariableNameFor: each.
1303
+ tempVariables add: temp.
1304
+ stream nextPutAll: 'var ', temp, '=nil;'; lf].
1305
+ index := 0.
1306
+ aNode nodes do: [:each |
1307
+ index := index + 1.
1308
+ index = aNode nodes size ifTrue: [
1309
+ stream nextPutAll: 'return '].
1310
+ self visit: each.
1311
+ stream nextPutAll: ';']].
1312
+ nestedBlocks := nestedBlocks - 1
1313
+ !
1013
1314
 
1014
- (aSelector = '/') ifTrue: [
1015
- self checkClass: 'Number' for: receiver.
1016
- stream nextPutAll: '$receiver /'.
1017
- self visit: aCollection first.
1018
- inlined := true].
1315
+ visitCascadeNode: aNode
1316
+ | index |
1317
+ index := 0.
1318
+ (tempVariables includes: '$rec') ifFalse: [
1319
+ tempVariables add: '$rec'].
1320
+ stream nextPutAll: '(function($rec){'.
1321
+ aNode nodes do: [:each |
1322
+ index := index + 1.
1323
+ index = aNode nodes size ifTrue: [
1324
+ stream nextPutAll: 'return '].
1325
+ each receiver: (VariableNode new value: '$rec').
1326
+ self visit: each.
1327
+ stream nextPutAll: ';'].
1328
+ stream nextPutAll: '})('.
1329
+ self visit: aNode receiver.
1330
+ stream nextPutAll: ')'
1331
+ !
1019
1332
 
1020
- ^inlined
1021
- ! !
1333
+ visitClassReferenceNode: aNode
1334
+ (referencedClasses includes: aNode value) ifFalse: [
1335
+ referencedClasses add: aNode value].
1336
+ stream nextPutAll: '(smalltalk.', aNode value, ' || ', aNode value, ')'
1337
+ !
1022
1338
 
1023
- !Compiler methodsFor: 'testing'!
1339
+ visitDynamicArrayNode: aNode
1340
+ stream nextPutAll: '['.
1341
+ aNode nodes
1342
+ do: [:each | self visit: each]
1343
+ separatedBy: [stream nextPutAll: ','].
1344
+ stream nextPutAll: ']'
1345
+ !
1024
1346
 
1025
- performOptimizations
1026
- ^self class performOptimizations
1027
- ! !
1347
+ visitDynamicDictionaryNode: aNode
1348
+ stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
1349
+ aNode nodes
1350
+ do: [:each | self visit: each]
1351
+ separatedBy: [stream nextPutAll: ','].
1352
+ stream nextPutAll: '])'
1353
+ !
1028
1354
 
1029
- !Compiler methodsFor: 'visiting'!
1355
+ visitFailure: aFailure
1356
+ self error: aFailure asString
1357
+ !
1030
1358
 
1031
- visit: aNode
1032
- aNode accept: self
1359
+ visitJSStatementNode: aNode
1360
+ stream nextPutAll: aNode source
1033
1361
  !
1034
1362
 
1035
1363
  visitMethodNode: aNode
@@ -1045,7 +1373,7 @@ visitMethodNode: aNode
1045
1373
  stream
1046
1374
  nextPutAll: 'smalltalk.method({'; lf;
1047
1375
  nextPutAll: 'selector: "', aNode selector, '",'; lf.
1048
- stream nextPutAll: 'source: unescape("', self source escaped, '"),';lf.
1376
+ stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
1049
1377
  stream nextPutAll: 'fn: function('.
1050
1378
  aNode arguments
1051
1379
  do: [:each |
@@ -1060,14 +1388,14 @@ visitMethodNode: aNode
1060
1388
  aNode nodes do: [:each |
1061
1389
  self visit: each].
1062
1390
  earlyReturn ifTrue: [
1063
- str nextPutAll: 'try{'].
1391
+ str nextPutAll: 'var $early={};'; lf; nextPutAll: 'try{'].
1064
1392
  str nextPutAll: stream contents.
1065
1393
  stream := str.
1066
1394
  stream
1067
1395
  lf;
1068
1396
  nextPutAll: 'return self;'.
1069
1397
  earlyReturn ifTrue: [
1070
- stream lf; nextPutAll: '} catch(e) {if(e.name === ''stReturn'' && e.selector === ', currentSelector printString, '){return e.fn()} throw(e)}'].
1398
+ stream lf; nextPutAll: '} catch(e) {if(e===$early)return e[0]; throw e}'].
1071
1399
  stream nextPutAll: '}'.
1072
1400
  stream
1073
1401
  nextPutAll: ',', String lf, 'messageSends: ';
@@ -1081,65 +1409,18 @@ visitMethodNode: aNode
1081
1409
  stream nextPutAll: '})'
1082
1410
  !
1083
1411
 
1084
- visitBlockNode: aNode
1085
- stream nextPutAll: '(function('.
1086
- aNode parameters
1087
- do: [:each |
1088
- tempVariables add: each.
1089
- stream nextPutAll: each]
1090
- separatedBy: [stream nextPutAll: ', '].
1091
- stream nextPutAll: '){'.
1092
- aNode nodes do: [:each | self visit: each].
1093
- stream nextPutAll: '})'
1094
- !
1095
-
1096
- visitSequenceNode: aNode
1097
- aNode temps do: [:each || temp |
1098
- temp := self safeVariableNameFor: each.
1099
- tempVariables add: temp.
1100
- stream nextPutAll: 'var ', temp, '=nil;'; lf].
1101
- aNode nodes do: [:each |
1102
- self visit: each.
1103
- stream nextPutAll: ';']
1104
- separatedBy: [stream lf]
1105
- !
1106
-
1107
- visitBlockSequenceNode: aNode
1108
- | index |
1109
- nestedBlocks := nestedBlocks + 1.
1110
- aNode nodes isEmpty
1111
- ifTrue: [
1112
- stream nextPutAll: 'return nil;']
1113
- ifFalse: [
1114
- aNode temps do: [:each | | temp |
1115
- temp := self safeVariableNameFor: each.
1116
- tempVariables add: temp.
1117
- stream nextPutAll: 'var ', temp, '=nil;'; lf].
1118
- index := 0.
1119
- aNode nodes do: [:each |
1120
- index := index + 1.
1121
- index = aNode nodes size ifTrue: [
1122
- stream nextPutAll: 'return '].
1123
- self visit: each.
1124
- stream nextPutAll: ';']].
1125
- nestedBlocks := nestedBlocks - 1
1126
- !
1127
-
1128
1412
  visitReturnNode: aNode
1129
1413
  nestedBlocks > 0 ifTrue: [
1130
1414
  earlyReturn := true].
1131
- earlyReturn
1415
+ nestedBlocks > 0
1132
1416
  ifTrue: [
1133
1417
  stream
1134
- nextPutAll: '(function(){throw(';
1135
- nextPutAll: '{name: ''stReturn'', selector: ';
1136
- nextPutAll: currentSelector printString;
1137
- nextPutAll: ', fn: function(){return ']
1418
+ nextPutAll: '(function(){throw $early=[']
1138
1419
  ifFalse: [stream nextPutAll: 'return '].
1139
1420
  aNode nodes do: [:each |
1140
1421
  self visit: each].
1141
- earlyReturn ifTrue: [
1142
- stream nextPutAll: '}})})()']
1422
+ nestedBlocks > 0 ifTrue: [
1423
+ stream nextPutAll: ']})()']
1143
1424
  !
1144
1425
 
1145
1426
  visitSendNode: aNode
@@ -1162,42 +1443,21 @@ visitSendNode: aNode
1162
1443
  ifFalse: [stream nextPutAll: (self send: aNode selector to: receiver arguments: aNode arguments superSend: superSend)]
1163
1444
  !
1164
1445
 
1165
- visitCascadeNode: aNode
1166
- | index |
1167
- index := 0.
1168
- (tempVariables includes: '$rec') ifFalse: [
1169
- tempVariables add: '$rec'].
1170
- stream nextPutAll: '(function($rec){'.
1446
+ visitSequenceNode: aNode
1447
+ aNode temps do: [:each || temp |
1448
+ temp := self safeVariableNameFor: each.
1449
+ tempVariables add: temp.
1450
+ stream nextPutAll: 'var ', temp, '=nil;'; lf].
1171
1451
  aNode nodes do: [:each |
1172
- index := index + 1.
1173
- index = aNode nodes size ifTrue: [
1174
- stream nextPutAll: 'return '].
1175
- each receiver: (VariableNode new value: '$rec').
1176
1452
  self visit: each.
1177
- stream nextPutAll: ';'].
1178
- stream nextPutAll: '})('.
1179
- self visit: aNode receiver.
1180
- stream nextPutAll: ')'
1453
+ stream nextPutAll: ';']
1454
+ separatedBy: [stream lf]
1181
1455
  !
1182
1456
 
1183
1457
  visitValueNode: aNode
1184
1458
  stream nextPutAll: aNode value asJavascript
1185
1459
  !
1186
1460
 
1187
- visitAssignmentNode: aNode
1188
- stream nextPutAll: '('.
1189
- self visit: aNode left.
1190
- stream nextPutAll: '='.
1191
- self visit: aNode right.
1192
- stream nextPutAll: ')'
1193
- !
1194
-
1195
- visitClassReferenceNode: aNode
1196
- (referencedClasses includes: aNode value) ifFalse: [
1197
- referencedClasses add: aNode value].
1198
- stream nextPutAll: '(smalltalk.', aNode value, ' || ', aNode value, ')'
1199
- !
1200
-
1201
1461
  visitVariableNode: aNode
1202
1462
  | varName |
1203
1463
  (self currentClass allInstanceVariableNames includes: aNode value)
@@ -1214,52 +1474,11 @@ visitVariableNode: aNode
1214
1474
  aNode value = 'thisContext'
1215
1475
  ifTrue: [stream nextPutAll: '(smalltalk.getThisContext())']
1216
1476
  ifFalse: [stream nextPutAll: varName]]]
1217
- !
1218
-
1219
- visitJSStatementNode: aNode
1220
- stream nextPutAll: (aNode source replace: '>>' with: '>')
1221
- !
1222
-
1223
- visitFailure: aFailure
1224
- self error: aFailure asString
1225
- !
1226
-
1227
- send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
1228
- ^String streamContents: [:str || tmp |
1229
- tmp := stream.
1230
- str nextPutAll: 'smalltalk.send('.
1231
- str nextPutAll: aReceiver.
1232
- str nextPutAll: ', "', aSelector asSelector, '", ['.
1233
- stream := str.
1234
- aCollection
1235
- do: [:each | self visit: each]
1236
- separatedBy: [stream nextPutAll: ', '].
1237
- stream := tmp.
1238
- str nextPutAll: ']'.
1239
- aBoolean ifTrue: [
1240
- str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
1241
- str nextPutAll: ')']
1242
- !
1243
-
1244
- visitDynamicArrayNode: aNode
1245
- stream nextPutAll: '['.
1246
- aNode nodes
1247
- do: [:each | self visit: each]
1248
- separatedBy: [stream nextPutAll: ','].
1249
- stream nextPutAll: ']'
1250
- !
1251
-
1252
- visitDynamicDictionaryNode: aNode
1253
- stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
1254
- aNode nodes
1255
- do: [:each | self visit: each]
1256
- separatedBy: [stream nextPutAll: ','].
1257
- stream nextPutAll: '])'
1258
1477
  ! !
1259
1478
 
1260
- Compiler class instanceVariableNames: 'performOptimizations'!
1479
+ FunCodeGenerator class instanceVariableNames: 'performOptimizations'!
1261
1480
 
1262
- !Compiler class methodsFor: 'accessing'!
1481
+ !FunCodeGenerator class methodsFor: 'accessing'!
1263
1482
 
1264
1483
  performOptimizations
1265
1484
  ^performOptimizations ifNil: [true]
@@ -1269,158 +1488,3 @@ performOptimizations: aBoolean
1269
1488
  performOptimizations := aBoolean
1270
1489
  ! !
1271
1490
 
1272
- !Compiler class methodsFor: 'compiling'!
1273
-
1274
- recompile: aClass
1275
- aClass methodDictionary do: [:each || method |
1276
- method := self new load: each source forClass: aClass.
1277
- method category: each category.
1278
- aClass addCompiledMethod: method].
1279
- aClass isMetaclass ifFalse: [self recompile: aClass class]
1280
- !
1281
-
1282
- recompileAll
1283
- Smalltalk current classes do: [:each |
1284
- self recompile: each]
1285
- ! !
1286
-
1287
- SequenceNode subclass: #BlockSequenceNode
1288
- instanceVariableNames: ''
1289
- category: 'Compiler'!
1290
-
1291
- !BlockSequenceNode methodsFor: 'testing'!
1292
-
1293
- isBlockSequenceNode
1294
- ^true
1295
- ! !
1296
-
1297
- !BlockSequenceNode methodsFor: 'visiting'!
1298
-
1299
- accept: aVisitor
1300
- aVisitor visitBlockSequenceNode: self
1301
- ! !
1302
-
1303
- Node subclass: #BlockNode
1304
- instanceVariableNames: 'parameters inlined'
1305
- category: 'Compiler'!
1306
-
1307
- !BlockNode methodsFor: 'accessing'!
1308
-
1309
- parameters
1310
- ^parameters ifNil: [parameters := Array new]
1311
- !
1312
-
1313
- parameters: aCollection
1314
- parameters := aCollection
1315
- !
1316
-
1317
- inlined
1318
- ^inlined ifNil: [false]
1319
- !
1320
-
1321
- inlined: aBoolean
1322
- inlined := aBoolean
1323
- ! !
1324
-
1325
- !BlockNode methodsFor: 'testing'!
1326
-
1327
- isBlockNode
1328
- ^true
1329
- ! !
1330
-
1331
- !BlockNode methodsFor: 'visiting'!
1332
-
1333
- accept: aVisitor
1334
- aVisitor visitBlockNode: self
1335
- ! !
1336
-
1337
- Node subclass: #CascadeNode
1338
- instanceVariableNames: 'receiver'
1339
- category: 'Compiler'!
1340
-
1341
- !CascadeNode methodsFor: 'accessing'!
1342
-
1343
- receiver
1344
- ^receiver
1345
- !
1346
-
1347
- receiver: aNode
1348
- receiver := aNode
1349
- ! !
1350
-
1351
- !CascadeNode methodsFor: 'visiting'!
1352
-
1353
- accept: aVisitor
1354
- aVisitor visitCascadeNode: self
1355
- ! !
1356
-
1357
- Node subclass: #MethodNode
1358
- instanceVariableNames: 'selector arguments source'
1359
- category: 'Compiler'!
1360
-
1361
- !MethodNode methodsFor: 'accessing'!
1362
-
1363
- selector
1364
- ^selector
1365
- !
1366
-
1367
- selector: aString
1368
- selector := aString
1369
- !
1370
-
1371
- arguments
1372
- ^arguments ifNil: [#()]
1373
- !
1374
-
1375
- arguments: aCollection
1376
- arguments := aCollection
1377
- !
1378
-
1379
- source
1380
- ^source
1381
- !
1382
-
1383
- source: aString
1384
- source := aString
1385
- ! !
1386
-
1387
- !MethodNode methodsFor: 'visiting'!
1388
-
1389
- accept: aVisitor
1390
- aVisitor visitMethodNode: self
1391
- ! !
1392
-
1393
- Exporter subclass: #StrippedExporter
1394
- instanceVariableNames: ''
1395
- category: 'Compiler'!
1396
-
1397
- !StrippedExporter methodsFor: 'private'!
1398
-
1399
- exportDefinitionOf: aClass on: aStream
1400
- aStream
1401
- nextPutAll: 'smalltalk.addClass(';
1402
- nextPutAll: '''', (self classNameFor: aClass), ''', ';
1403
- nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
1404
- nextPutAll: ', ['.
1405
- aClass instanceVariableNames
1406
- do: [:each | aStream nextPutAll: '''', each, '''']
1407
- separatedBy: [aStream nextPutAll: ', '].
1408
- aStream
1409
- nextPutAll: '], ''';
1410
- nextPutAll: aClass category, '''';
1411
- nextPutAll: ');'.
1412
- aStream lf
1413
- !
1414
-
1415
- exportMethod: aMethod of: aClass on: aStream
1416
- aStream
1417
- nextPutAll: 'smalltalk.addMethod(';lf;
1418
- nextPutAll: 'unescape(''', aMethod selector asSelector escaped, '''),';lf;
1419
- nextPutAll: 'smalltalk.method({';lf;
1420
- nextPutAll: 'selector: unescape(''', aMethod selector escaped, '''),';lf;
1421
- nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
1422
- nextPutAll: '}),';lf;
1423
- nextPutAll: 'smalltalk.', (self classNameFor: aClass);
1424
- nextPutAll: ');';lf;lf
1425
- ! !
1426
-