resin 0.0.1 → 0.0.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.
- data/amber/images/amber.svg +706 -0
- data/amber/js/Canvas.deploy.js +1311 -400
- data/amber/js/Canvas.js +1750 -424
- data/amber/js/Compiler.deploy.js +615 -615
- data/amber/js/Compiler.js +1367 -1367
- data/amber/js/IDE.deploy.js +1381 -1345
- data/amber/js/IDE.js +1949 -1903
- data/amber/js/Kernel-Announcements.deploy.js +37 -37
- data/amber/js/Kernel-Announcements.js +52 -52
- data/amber/js/Kernel-Collections.deploy.js +961 -950
- data/amber/js/Kernel-Collections.js +2064 -2053
- data/amber/js/Kernel-Methods.deploy.js +323 -260
- data/amber/js/Kernel-Methods.js +395 -327
- data/amber/js/Kernel-Objects.deploy.js +1846 -1104
- data/amber/js/Kernel-Objects.js +2142 -1194
- data/amber/js/boot.js +44 -29
- data/amber/js/parser.js +234 -17
- data/amber/js/parser.pegjs +9 -6
- data/amber/st/Canvas.st +474 -146
- data/amber/st/Compiler.st +418 -417
- data/amber/st/IDE.st +803 -772
- data/amber/st/Kernel-Announcements.st +27 -27
- data/amber/st/Kernel-Collections.st +289 -268
- data/amber/st/Kernel-Methods.st +104 -100
- data/amber/st/Kernel-Objects.st +277 -80
- metadata +18 -17
data/amber/st/Compiler.st
CHANGED
@@ -1,45 +1,81 @@
|
|
1
1
|
Smalltalk current createPackage: 'Compiler' properties: #{}!
|
2
|
-
Object subclass: #
|
3
|
-
instanceVariableNames: '
|
2
|
+
Object subclass: #NodeVisitor
|
3
|
+
instanceVariableNames: ''
|
4
4
|
category: 'Compiler'!
|
5
5
|
|
6
|
-
!
|
6
|
+
!NodeVisitor methodsFor: 'visiting'!
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
!
|
8
|
+
visit: aNode
|
9
|
+
aNode accept: self
|
10
|
+
!
|
11
11
|
|
12
|
-
|
12
|
+
visitNode: aNode
|
13
|
+
!
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
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.
|
15
|
+
visitMethodNode: aNode
|
16
|
+
self visitNode: aNode
|
17
|
+
!
|
22
18
|
|
23
|
-
|
19
|
+
visitSequenceNode: aNode
|
20
|
+
self visitNode: aNode
|
21
|
+
!
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
-
! !
|
23
|
+
visitBlockSequenceNode: aNode
|
24
|
+
self visitSequenceNode: aNode
|
25
|
+
!
|
36
26
|
|
37
|
-
|
27
|
+
visitBlockNode: aNode
|
28
|
+
self visitNode: aNode
|
29
|
+
!
|
38
30
|
|
39
|
-
|
40
|
-
|
31
|
+
visitReturnNode: aNode
|
32
|
+
self visitNode: aNode
|
33
|
+
!
|
34
|
+
|
35
|
+
visitSendNode: aNode
|
36
|
+
self visitNode: aNode
|
37
|
+
!
|
38
|
+
|
39
|
+
visitCascadeNode: aNode
|
40
|
+
self visitNode: aNode
|
41
|
+
!
|
42
|
+
|
43
|
+
visitValueNode: aNode
|
44
|
+
self visitNode: aNode
|
45
|
+
!
|
46
|
+
|
47
|
+
visitVariableNode: aNode
|
48
|
+
!
|
49
|
+
|
50
|
+
visitAssignmentNode: aNode
|
51
|
+
self visitNode: aNode
|
52
|
+
!
|
53
|
+
|
54
|
+
visitClassReferenceNode: aNode
|
55
|
+
self
|
56
|
+
nextPutAll: 'smalltalk.';
|
57
|
+
nextPutAll: aNode value
|
58
|
+
!
|
59
|
+
|
60
|
+
visitJSStatementNode: aNode
|
61
|
+
self
|
62
|
+
nextPutAll: 'function(){';
|
63
|
+
nextPutAll: aNode source;
|
64
|
+
nextPutAll: '})()'
|
65
|
+
!
|
66
|
+
|
67
|
+
visitDynamicArrayNode: aNode
|
68
|
+
self visitNode: aNode
|
69
|
+
!
|
70
|
+
|
71
|
+
visitDynamicDictionaryNode: aNode
|
72
|
+
self visitNode: aNode
|
41
73
|
! !
|
42
74
|
|
75
|
+
Object subclass: #DoIt
|
76
|
+
instanceVariableNames: ''
|
77
|
+
category: 'Compiler'!
|
78
|
+
|
43
79
|
Object subclass: #Importer
|
44
80
|
instanceVariableNames: ''
|
45
81
|
category: 'Compiler'!
|
@@ -75,7 +111,8 @@ exportPackage: packageName
|
|
75
111
|
^String streamContents: [:stream |
|
76
112
|
package := Smalltalk current packageAt: packageName.
|
77
113
|
self exportPackageDefinitionOf: package on: stream.
|
78
|
-
|
114
|
+
"Export classes in dependency order"
|
115
|
+
package sortedClasses do: [:each |
|
79
116
|
stream nextPutAll: (self exportClass: each)].
|
80
117
|
self exportPackageExtensionsOf: package on: stream]
|
81
118
|
!
|
@@ -185,140 +222,45 @@ exportPackageDefinitionOf: package on: aStream
|
|
185
222
|
aStream lf
|
186
223
|
! !
|
187
224
|
|
188
|
-
|
189
|
-
instanceVariableNames: ''
|
225
|
+
Object subclass: #ChunkParser
|
226
|
+
instanceVariableNames: 'stream'
|
190
227
|
category: 'Compiler'!
|
191
228
|
|
192
|
-
!
|
193
|
-
|
194
|
-
exportDefinitionOf: aClass on: aStream
|
195
|
-
"Chunk format."
|
196
|
-
|
197
|
-
aStream
|
198
|
-
nextPutAll: (self classNameFor: aClass superclass);
|
199
|
-
nextPutAll: ' subclass: #', (self classNameFor: aClass); lf;
|
200
|
-
nextPutAll: ' instanceVariableNames: '''.
|
201
|
-
aClass instanceVariableNames
|
202
|
-
do: [:each | aStream nextPutAll: each]
|
203
|
-
separatedBy: [aStream nextPutAll: ' '].
|
204
|
-
aStream
|
205
|
-
nextPutAll: ''''; lf;
|
206
|
-
nextPutAll: ' category: ''', aClass category, '''!!'; lf.
|
207
|
-
aClass comment notEmpty ifTrue: [
|
208
|
-
aStream
|
209
|
-
nextPutAll: '!!', (self classNameFor: aClass), ' commentStamp!!';lf;
|
210
|
-
nextPutAll: (self chunkEscape: aClass comment), '!!';lf].
|
211
|
-
aStream lf
|
212
|
-
!
|
213
|
-
|
214
|
-
exportMethod: aMethod of: aClass on: aStream
|
215
|
-
aStream
|
216
|
-
lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;
|
217
|
-
nextPutAll: '!!'
|
218
|
-
!
|
219
|
-
|
220
|
-
exportMethodsOf: aClass on: aStream
|
221
|
-
|
222
|
-
aClass protocolsDo: [:category :methods |
|
223
|
-
(category match: '^\*') ifFalse: [
|
224
|
-
self
|
225
|
-
exportMethods: methods
|
226
|
-
category: category
|
227
|
-
of: aClass
|
228
|
-
on: aStream]]
|
229
|
-
!
|
230
|
-
|
231
|
-
exportMetaDefinitionOf: aClass on: aStream
|
232
|
-
|
233
|
-
aClass class instanceVariableNames isEmpty ifFalse: [
|
234
|
-
aStream
|
235
|
-
nextPutAll: (self classNameFor: aClass class);
|
236
|
-
nextPutAll: ' instanceVariableNames: '''.
|
237
|
-
aClass class instanceVariableNames
|
238
|
-
do: [:each | aStream nextPutAll: each]
|
239
|
-
separatedBy: [aStream nextPutAll: ' '].
|
240
|
-
aStream
|
241
|
-
nextPutAll: '''!!'; lf; lf]
|
242
|
-
!
|
243
|
-
|
244
|
-
classNameFor: aClass
|
245
|
-
^aClass isMetaclass
|
246
|
-
ifTrue: [aClass instanceClass name, ' class']
|
247
|
-
ifFalse: [
|
248
|
-
aClass isNil
|
249
|
-
ifTrue: ['nil']
|
250
|
-
ifFalse: [aClass name]]
|
251
|
-
!
|
252
|
-
|
253
|
-
chunkEscape: aString
|
254
|
-
"Replace all occurrences of !! with !!!! and trim at both ends."
|
255
|
-
|
256
|
-
^(aString replace: '!!' with: '!!!!') trimBoth
|
257
|
-
!
|
258
|
-
|
259
|
-
exportMethods: methods category: category of: aClass on: aStream
|
229
|
+
!ChunkParser methodsFor: 'accessing'!
|
260
230
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
methods do: [:each |
|
265
|
-
self exportMethod: each of: aClass on: aStream].
|
266
|
-
aStream nextPutAll: ' !!'; lf; lf
|
267
|
-
!
|
231
|
+
stream: aStream
|
232
|
+
stream := aStream
|
233
|
+
! !
|
268
234
|
|
269
|
-
|
270
|
-
"We need to override this one too since we need to group
|
271
|
-
all methods in a given protocol under a leading methodsFor: chunk
|
272
|
-
for that class."
|
235
|
+
!ChunkParser methodsFor: 'reading'!
|
273
236
|
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
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.
|
281
245
|
|
282
|
-
|
283
|
-
"Chunk format."
|
246
|
+
This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
|
284
247
|
|
285
|
-
|
286
|
-
|
287
|
-
|
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 !!"
|
288
258
|
! !
|
289
259
|
|
290
|
-
|
291
|
-
instanceVariableNames: ''
|
292
|
-
category: 'Compiler'!
|
293
|
-
|
294
|
-
!StrippedExporter methodsFor: 'private'!
|
295
|
-
|
296
|
-
exportDefinitionOf: aClass on: aStream
|
297
|
-
aStream
|
298
|
-
nextPutAll: 'smalltalk.addClass(';
|
299
|
-
nextPutAll: '''', (self classNameFor: aClass), ''', ';
|
300
|
-
nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
|
301
|
-
nextPutAll: ', ['.
|
302
|
-
aClass instanceVariableNames
|
303
|
-
do: [:each | aStream nextPutAll: '''', each, '''']
|
304
|
-
separatedBy: [aStream nextPutAll: ', '].
|
305
|
-
aStream
|
306
|
-
nextPutAll: '], ''';
|
307
|
-
nextPutAll: aClass category, '''';
|
308
|
-
nextPutAll: ');'.
|
309
|
-
aStream lf
|
310
|
-
!
|
260
|
+
!ChunkParser class methodsFor: 'not yet classified'!
|
311
261
|
|
312
|
-
|
313
|
-
aStream
|
314
|
-
nextPutAll: 'smalltalk.addMethod(';lf;
|
315
|
-
nextPutAll: 'unescape(''', aMethod selector asSelector escaped, '''),';lf;
|
316
|
-
nextPutAll: 'smalltalk.method({';lf;
|
317
|
-
nextPutAll: 'selector: unescape(''', aMethod selector escaped, '''),';lf;
|
318
|
-
nextPutAll: 'fn: ', aMethod fn compiledSource;lf;
|
319
|
-
nextPutAll: '}),';lf;
|
320
|
-
nextPutAll: 'smalltalk.', (self classNameFor: aClass);
|
321
|
-
nextPutAll: ');';lf;lf
|
262
|
+
on: aStream
|
263
|
+
^self new stream: aStream
|
322
264
|
! !
|
323
265
|
|
324
266
|
Object subclass: #Node
|
@@ -361,292 +303,269 @@ accept: aVisitor
|
|
361
303
|
aVisitor visitNode: self
|
362
304
|
! !
|
363
305
|
|
364
|
-
Node subclass: #
|
365
|
-
instanceVariableNames: '
|
306
|
+
Node subclass: #SequenceNode
|
307
|
+
instanceVariableNames: 'temps'
|
366
308
|
category: 'Compiler'!
|
367
309
|
|
368
|
-
!
|
310
|
+
!SequenceNode methodsFor: 'accessing'!
|
369
311
|
|
370
|
-
|
371
|
-
^
|
372
|
-
!
|
373
|
-
|
374
|
-
selector: aString
|
375
|
-
selector := aString
|
376
|
-
!
|
377
|
-
|
378
|
-
arguments
|
379
|
-
^arguments ifNil: [#()]
|
312
|
+
temps
|
313
|
+
^temps ifNil: [#()]
|
380
314
|
!
|
381
315
|
|
382
|
-
|
383
|
-
|
384
|
-
!
|
316
|
+
temps: aCollection
|
317
|
+
temps := aCollection
|
318
|
+
! !
|
385
319
|
|
386
|
-
|
387
|
-
^source
|
388
|
-
!
|
320
|
+
!SequenceNode methodsFor: 'testing'!
|
389
321
|
|
390
|
-
|
391
|
-
|
322
|
+
asBlockSequenceNode
|
323
|
+
^BlockSequenceNode new
|
324
|
+
nodes: self nodes;
|
325
|
+
temps: self temps;
|
326
|
+
yourself
|
392
327
|
! !
|
393
328
|
|
394
|
-
!
|
329
|
+
!SequenceNode methodsFor: 'visiting'!
|
395
330
|
|
396
331
|
accept: aVisitor
|
397
|
-
aVisitor
|
332
|
+
aVisitor visitSequenceNode: self
|
398
333
|
! !
|
399
334
|
|
400
|
-
Node subclass: #
|
401
|
-
instanceVariableNames: '
|
335
|
+
Node subclass: #DynamicDictionaryNode
|
336
|
+
instanceVariableNames: ''
|
402
337
|
category: 'Compiler'!
|
403
338
|
|
404
|
-
!
|
405
|
-
|
406
|
-
selector
|
407
|
-
^selector
|
408
|
-
!
|
409
|
-
|
410
|
-
selector: aString
|
411
|
-
selector := aString
|
412
|
-
!
|
413
|
-
|
414
|
-
arguments
|
415
|
-
^arguments ifNil: [arguments := #()]
|
416
|
-
!
|
417
|
-
|
418
|
-
arguments: aCollection
|
419
|
-
arguments := aCollection
|
420
|
-
!
|
421
|
-
|
422
|
-
receiver
|
423
|
-
^receiver
|
424
|
-
!
|
425
|
-
|
426
|
-
receiver: aNode
|
427
|
-
receiver := aNode
|
428
|
-
!
|
429
|
-
|
430
|
-
valueForReceiver: anObject
|
431
|
-
^SendNode new
|
432
|
-
receiver: (self receiver
|
433
|
-
ifNil: [anObject]
|
434
|
-
ifNotNil: [self receiver valueForReceiver: anObject]);
|
435
|
-
selector: self selector;
|
436
|
-
arguments: self arguments;
|
437
|
-
yourself
|
438
|
-
!
|
339
|
+
!DynamicDictionaryNode methodsFor: 'visiting'!
|
439
340
|
|
440
|
-
|
441
|
-
|
442
|
-
first := SendNode new
|
443
|
-
selector: self selector;
|
444
|
-
arguments: self arguments;
|
445
|
-
yourself.
|
446
|
-
^CascadeNode new
|
447
|
-
receiver: self receiver;
|
448
|
-
nodes: (Array with: first), aCollection;
|
449
|
-
yourself
|
341
|
+
accept: aVisitor
|
342
|
+
aVisitor visitDynamicDictionaryNode: self
|
450
343
|
! !
|
451
344
|
|
452
|
-
|
345
|
+
Node subclass: #ReturnNode
|
346
|
+
instanceVariableNames: ''
|
347
|
+
category: 'Compiler'!
|
348
|
+
|
349
|
+
!ReturnNode methodsFor: 'visiting'!
|
453
350
|
|
454
351
|
accept: aVisitor
|
455
|
-
aVisitor
|
352
|
+
aVisitor visitReturnNode: self
|
456
353
|
! !
|
457
354
|
|
458
|
-
Node subclass: #
|
459
|
-
instanceVariableNames: '
|
355
|
+
Node subclass: #ValueNode
|
356
|
+
instanceVariableNames: 'value'
|
460
357
|
category: 'Compiler'!
|
461
358
|
|
462
|
-
!
|
359
|
+
!ValueNode methodsFor: 'accessing'!
|
463
360
|
|
464
|
-
|
465
|
-
^
|
361
|
+
value
|
362
|
+
^value
|
466
363
|
!
|
467
364
|
|
468
|
-
|
469
|
-
|
365
|
+
value: anObject
|
366
|
+
value := anObject
|
470
367
|
! !
|
471
368
|
|
472
|
-
!
|
369
|
+
!ValueNode methodsFor: 'testing'!
|
473
370
|
|
474
|
-
|
475
|
-
|
371
|
+
isValueNode
|
372
|
+
^true
|
476
373
|
! !
|
477
374
|
|
478
|
-
|
479
|
-
instanceVariableNames: 'left right'
|
480
|
-
category: 'Compiler'!
|
375
|
+
!ValueNode methodsFor: 'visiting'!
|
481
376
|
|
482
|
-
|
377
|
+
accept: aVisitor
|
378
|
+
aVisitor visitValueNode: self
|
379
|
+
! !
|
483
380
|
|
484
|
-
|
485
|
-
|
486
|
-
!
|
381
|
+
ValueNode subclass: #VariableNode
|
382
|
+
instanceVariableNames: 'assigned'
|
383
|
+
category: 'Compiler'!
|
487
384
|
|
488
|
-
|
489
|
-
left := aNode.
|
490
|
-
left assigned: true
|
491
|
-
!
|
385
|
+
!VariableNode methodsFor: 'accessing'!
|
492
386
|
|
493
|
-
|
494
|
-
^
|
387
|
+
assigned
|
388
|
+
^assigned ifNil: [false]
|
495
389
|
!
|
496
390
|
|
497
|
-
|
498
|
-
|
391
|
+
assigned: aBoolean
|
392
|
+
assigned := aBoolean
|
499
393
|
! !
|
500
394
|
|
501
|
-
!
|
395
|
+
!VariableNode methodsFor: 'visiting'!
|
502
396
|
|
503
397
|
accept: aVisitor
|
504
|
-
aVisitor
|
398
|
+
aVisitor visitVariableNode: self
|
505
399
|
! !
|
506
400
|
|
507
|
-
|
508
|
-
instanceVariableNames: '
|
401
|
+
Exporter subclass: #ChunkExporter
|
402
|
+
instanceVariableNames: ''
|
509
403
|
category: 'Compiler'!
|
510
404
|
|
511
|
-
!
|
405
|
+
!ChunkExporter methodsFor: 'not yet classified'!
|
512
406
|
|
513
|
-
|
514
|
-
|
515
|
-
!
|
407
|
+
exportDefinitionOf: aClass on: aStream
|
408
|
+
"Chunk format."
|
516
409
|
|
517
|
-
|
518
|
-
|
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
|
519
425
|
!
|
520
426
|
|
521
|
-
|
522
|
-
|
427
|
+
exportMethod: aMethod of: aClass on: aStream
|
428
|
+
aStream
|
429
|
+
lf; lf; nextPutAll: (self chunkEscape: aMethod source); lf;
|
430
|
+
nextPutAll: '!!'
|
523
431
|
!
|
524
432
|
|
525
|
-
|
526
|
-
inlined := aBoolean
|
527
|
-
! !
|
528
|
-
|
529
|
-
!BlockNode methodsFor: 'testing'!
|
530
|
-
|
531
|
-
isBlockNode
|
532
|
-
^true
|
533
|
-
! !
|
534
|
-
|
535
|
-
!BlockNode methodsFor: 'visiting'!
|
536
|
-
|
537
|
-
accept: aVisitor
|
538
|
-
aVisitor visitBlockNode: self
|
539
|
-
! !
|
433
|
+
exportMethodsOf: aClass on: aStream
|
540
434
|
|
541
|
-
|
542
|
-
|
543
|
-
|
435
|
+
aClass protocolsDo: [:category :methods |
|
436
|
+
(category match: '^\*') ifFalse: [
|
437
|
+
self
|
438
|
+
exportMethods: methods
|
439
|
+
category: category
|
440
|
+
of: aClass
|
441
|
+
on: aStream]]
|
442
|
+
!
|
544
443
|
|
545
|
-
|
444
|
+
exportMetaDefinitionOf: aClass on: aStream
|
546
445
|
|
547
|
-
|
548
|
-
|
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]
|
549
455
|
!
|
550
456
|
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
457
|
+
classNameFor: aClass
|
458
|
+
^aClass isMetaclass
|
459
|
+
ifTrue: [aClass instanceClass name, ' class']
|
460
|
+
ifFalse: [
|
461
|
+
aClass isNil
|
462
|
+
ifTrue: ['nil']
|
463
|
+
ifFalse: [aClass name]]
|
464
|
+
!
|
556
465
|
|
557
|
-
|
558
|
-
|
559
|
-
nodes: self nodes;
|
560
|
-
temps: self temps;
|
561
|
-
yourself
|
562
|
-
! !
|
466
|
+
chunkEscape: aString
|
467
|
+
"Replace all occurrences of !! with !!!! and trim at both ends."
|
563
468
|
|
564
|
-
|
469
|
+
^(aString replace: '!!' with: '!!!!') trimBoth
|
470
|
+
!
|
565
471
|
|
566
|
-
|
567
|
-
aVisitor visitSequenceNode: self
|
568
|
-
! !
|
472
|
+
exportMethods: methods category: category of: aClass on: aStream
|
569
473
|
|
570
|
-
|
571
|
-
|
572
|
-
|
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
|
480
|
+
!
|
573
481
|
|
574
|
-
|
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."
|
575
486
|
|
576
|
-
|
577
|
-
|
578
|
-
|
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
|
+
!
|
579
494
|
|
580
|
-
|
495
|
+
exportPackageDefinitionOf: package on: aStream
|
496
|
+
"Chunk format."
|
581
497
|
|
582
|
-
|
583
|
-
|
498
|
+
aStream
|
499
|
+
nextPutAll: 'Smalltalk current createPackage: ''', package name,
|
500
|
+
''' properties: ', package properties storeString, '!!'; lf.
|
584
501
|
! !
|
585
502
|
|
586
|
-
|
503
|
+
VariableNode subclass: #ClassReferenceNode
|
587
504
|
instanceVariableNames: ''
|
588
505
|
category: 'Compiler'!
|
589
506
|
|
590
|
-
!
|
507
|
+
!ClassReferenceNode methodsFor: 'visiting'!
|
591
508
|
|
592
509
|
accept: aVisitor
|
593
|
-
aVisitor
|
510
|
+
aVisitor visitClassReferenceNode: self
|
594
511
|
! !
|
595
512
|
|
596
|
-
Node subclass: #
|
597
|
-
instanceVariableNames: '
|
513
|
+
Node subclass: #SendNode
|
514
|
+
instanceVariableNames: 'selector arguments receiver'
|
598
515
|
category: 'Compiler'!
|
599
516
|
|
600
|
-
!
|
517
|
+
!SendNode methodsFor: 'accessing'!
|
601
518
|
|
602
|
-
|
603
|
-
^
|
519
|
+
selector
|
520
|
+
^selector
|
604
521
|
!
|
605
522
|
|
606
|
-
|
607
|
-
|
608
|
-
!
|
609
|
-
|
610
|
-
!ValueNode methodsFor: 'testing'!
|
611
|
-
|
612
|
-
isValueNode
|
613
|
-
^true
|
614
|
-
! !
|
615
|
-
|
616
|
-
!ValueNode methodsFor: 'visiting'!
|
617
|
-
|
618
|
-
accept: aVisitor
|
619
|
-
aVisitor visitValueNode: self
|
620
|
-
! !
|
523
|
+
selector: aString
|
524
|
+
selector := aString
|
525
|
+
!
|
621
526
|
|
622
|
-
|
623
|
-
|
624
|
-
|
527
|
+
arguments
|
528
|
+
^arguments ifNil: [arguments := #()]
|
529
|
+
!
|
625
530
|
|
626
|
-
|
531
|
+
arguments: aCollection
|
532
|
+
arguments := aCollection
|
533
|
+
!
|
627
534
|
|
628
|
-
|
629
|
-
^
|
535
|
+
receiver
|
536
|
+
^receiver
|
630
537
|
!
|
631
538
|
|
632
|
-
|
633
|
-
|
634
|
-
!
|
539
|
+
receiver: aNode
|
540
|
+
receiver := aNode
|
541
|
+
!
|
635
542
|
|
636
|
-
|
543
|
+
valueForReceiver: anObject
|
544
|
+
^SendNode new
|
545
|
+
receiver: (self receiver
|
546
|
+
ifNil: [anObject]
|
547
|
+
ifNotNil: [self receiver valueForReceiver: anObject]);
|
548
|
+
selector: self selector;
|
549
|
+
arguments: self arguments;
|
550
|
+
yourself
|
551
|
+
!
|
637
552
|
|
638
|
-
|
639
|
-
|
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
|
640
563
|
! !
|
641
564
|
|
642
|
-
|
643
|
-
instanceVariableNames: ''
|
644
|
-
category: 'Compiler'!
|
645
|
-
|
646
|
-
!ClassReferenceNode methodsFor: 'visiting'!
|
565
|
+
!SendNode methodsFor: 'visiting'!
|
647
566
|
|
648
567
|
accept: aVisitor
|
649
|
-
aVisitor
|
568
|
+
aVisitor visitSendNode: self
|
650
569
|
! !
|
651
570
|
|
652
571
|
Node subclass: #JSStatementNode
|
@@ -669,77 +588,43 @@ accept: aVisitor
|
|
669
588
|
aVisitor visitJSStatementNode: self
|
670
589
|
! !
|
671
590
|
|
672
|
-
|
673
|
-
instanceVariableNames: ''
|
591
|
+
Node subclass: #AssignmentNode
|
592
|
+
instanceVariableNames: 'left right'
|
674
593
|
category: 'Compiler'!
|
675
594
|
|
676
|
-
!
|
677
|
-
|
678
|
-
visit: aNode
|
679
|
-
aNode accept: self
|
680
|
-
!
|
681
|
-
|
682
|
-
visitNode: aNode
|
683
|
-
!
|
684
|
-
|
685
|
-
visitMethodNode: aNode
|
686
|
-
self visitNode: aNode
|
687
|
-
!
|
688
|
-
|
689
|
-
visitSequenceNode: aNode
|
690
|
-
self visitNode: aNode
|
691
|
-
!
|
692
|
-
|
693
|
-
visitBlockSequenceNode: aNode
|
694
|
-
self visitSequenceNode: aNode
|
695
|
-
!
|
696
|
-
|
697
|
-
visitBlockNode: aNode
|
698
|
-
self visitNode: aNode
|
699
|
-
!
|
700
|
-
|
701
|
-
visitReturnNode: aNode
|
702
|
-
self visitNode: aNode
|
703
|
-
!
|
595
|
+
!AssignmentNode methodsFor: 'accessing'!
|
704
596
|
|
705
|
-
|
706
|
-
|
597
|
+
left
|
598
|
+
^left
|
707
599
|
!
|
708
600
|
|
709
|
-
|
710
|
-
|
601
|
+
left: aNode
|
602
|
+
left := aNode.
|
603
|
+
left assigned: true
|
711
604
|
!
|
712
605
|
|
713
|
-
|
714
|
-
|
606
|
+
right
|
607
|
+
^right
|
715
608
|
!
|
716
609
|
|
717
|
-
|
718
|
-
|
610
|
+
right: aNode
|
611
|
+
right := aNode
|
612
|
+
! !
|
719
613
|
|
720
|
-
|
721
|
-
self visitNode: aNode
|
722
|
-
!
|
614
|
+
!AssignmentNode methodsFor: 'visiting'!
|
723
615
|
|
724
|
-
|
725
|
-
self
|
726
|
-
|
727
|
-
nextPutAll: aNode value
|
728
|
-
!
|
616
|
+
accept: aVisitor
|
617
|
+
aVisitor visitAssignmentNode: self
|
618
|
+
! !
|
729
619
|
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
nextPutAll: aNode source;
|
734
|
-
nextPutAll: '})()'
|
735
|
-
!
|
620
|
+
Node subclass: #DynamicArrayNode
|
621
|
+
instanceVariableNames: ''
|
622
|
+
category: 'Compiler'!
|
736
623
|
|
737
|
-
|
738
|
-
self visitNode: aNode
|
739
|
-
!
|
624
|
+
!DynamicArrayNode methodsFor: 'visiting'!
|
740
625
|
|
741
|
-
|
742
|
-
|
626
|
+
accept: aVisitor
|
627
|
+
aVisitor visitDynamicArrayNode: self
|
743
628
|
! !
|
744
629
|
|
745
630
|
NodeVisitor subclass: #Compiler
|
@@ -1399,27 +1284,143 @@ recompileAll
|
|
1399
1284
|
self recompile: each]
|
1400
1285
|
! !
|
1401
1286
|
|
1402
|
-
|
1287
|
+
SequenceNode subclass: #BlockSequenceNode
|
1403
1288
|
instanceVariableNames: ''
|
1404
1289
|
category: 'Compiler'!
|
1405
1290
|
|
1406
|
-
|
1407
|
-
|
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'
|
1408
1305
|
category: 'Compiler'!
|
1409
1306
|
|
1410
|
-
!
|
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'!
|
1411
1332
|
|
1412
1333
|
accept: aVisitor
|
1413
|
-
aVisitor
|
1334
|
+
aVisitor visitBlockNode: self
|
1414
1335
|
! !
|
1415
1336
|
|
1416
|
-
Node subclass: #
|
1417
|
-
instanceVariableNames: ''
|
1337
|
+
Node subclass: #CascadeNode
|
1338
|
+
instanceVariableNames: 'receiver'
|
1418
1339
|
category: 'Compiler'!
|
1419
1340
|
|
1420
|
-
!
|
1341
|
+
!CascadeNode methodsFor: 'accessing'!
|
1342
|
+
|
1343
|
+
receiver
|
1344
|
+
^receiver
|
1345
|
+
!
|
1346
|
+
|
1347
|
+
receiver: aNode
|
1348
|
+
receiver := aNode
|
1349
|
+
! !
|
1350
|
+
|
1351
|
+
!CascadeNode methodsFor: 'visiting'!
|
1421
1352
|
|
1422
1353
|
accept: aVisitor
|
1423
|
-
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
|
1424
1425
|
! !
|
1425
1426
|
|