resin 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|