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.
@@ -1,45 +1,81 @@
1
1
  Smalltalk current createPackage: 'Compiler' properties: #{}!
2
- Object subclass: #ChunkParser
3
- instanceVariableNames: 'stream'
2
+ Object subclass: #NodeVisitor
3
+ instanceVariableNames: ''
4
4
  category: 'Compiler'!
5
5
 
6
- !ChunkParser methodsFor: 'accessing'!
6
+ !NodeVisitor methodsFor: 'visiting'!
7
7
 
8
- stream: aStream
9
- stream := aStream
10
- ! !
8
+ visit: aNode
9
+ aNode accept: self
10
+ !
11
11
 
12
- !ChunkParser methodsFor: 'reading'!
12
+ visitNode: aNode
13
+ !
13
14
 
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.
15
+ visitMethodNode: aNode
16
+ self visitNode: aNode
17
+ !
22
18
 
23
- This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
19
+ visitSequenceNode: aNode
20
+ self visitNode: aNode
21
+ !
24
22
 
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
- ! !
23
+ visitBlockSequenceNode: aNode
24
+ self visitSequenceNode: aNode
25
+ !
36
26
 
37
- !ChunkParser class methodsFor: 'not yet classified'!
27
+ visitBlockNode: aNode
28
+ self visitNode: aNode
29
+ !
38
30
 
39
- on: aStream
40
- ^self new stream: aStream
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
- package classes do: [:each |
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
- Exporter subclass: #ChunkExporter
189
- instanceVariableNames: ''
225
+ Object subclass: #ChunkParser
226
+ instanceVariableNames: 'stream'
190
227
  category: 'Compiler'!
191
228
 
192
- !ChunkExporter methodsFor: 'not yet classified'!
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
- aStream
262
- nextPutAll: '!!', (self classNameFor: aClass);
263
- nextPutAll: ' methodsFor: ''', category, '''!!'.
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
- exportPackageExtensionsOf: package on: aStream
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
- | name |
275
- name := package name.
276
- Smalltalk current classes, (Smalltalk current classes collect: [:each | each class]) do: [:each |
277
- each protocolsDo: [:category :methods |
278
- category = ('*', name) ifTrue: [
279
- self exportMethods: methods category: category of: each on: aStream]]]
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
- exportPackageDefinitionOf: package on: aStream
283
- "Chunk format."
246
+ This metod returns next chunk as a String (trimmed), empty String (all whitespace) or nil."
284
247
 
285
- aStream
286
- nextPutAll: 'Smalltalk current createPackage: ''', package name,
287
- ''' properties: ', package properties storeString, '!!'; lf.
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
- Exporter subclass: #StrippedExporter
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
- exportMethod: aMethod of: aClass on: aStream
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: #MethodNode
365
- instanceVariableNames: 'selector arguments source'
306
+ Node subclass: #SequenceNode
307
+ instanceVariableNames: 'temps'
366
308
  category: 'Compiler'!
367
309
 
368
- !MethodNode methodsFor: 'accessing'!
310
+ !SequenceNode methodsFor: 'accessing'!
369
311
 
370
- selector
371
- ^selector
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
- arguments: aCollection
383
- arguments := aCollection
384
- !
316
+ temps: aCollection
317
+ temps := aCollection
318
+ ! !
385
319
 
386
- source
387
- ^source
388
- !
320
+ !SequenceNode methodsFor: 'testing'!
389
321
 
390
- source: aString
391
- source := aString
322
+ asBlockSequenceNode
323
+ ^BlockSequenceNode new
324
+ nodes: self nodes;
325
+ temps: self temps;
326
+ yourself
392
327
  ! !
393
328
 
394
- !MethodNode methodsFor: 'visiting'!
329
+ !SequenceNode methodsFor: 'visiting'!
395
330
 
396
331
  accept: aVisitor
397
- aVisitor visitMethodNode: self
332
+ aVisitor visitSequenceNode: self
398
333
  ! !
399
334
 
400
- Node subclass: #SendNode
401
- instanceVariableNames: 'selector arguments receiver'
335
+ Node subclass: #DynamicDictionaryNode
336
+ instanceVariableNames: ''
402
337
  category: 'Compiler'!
403
338
 
404
- !SendNode methodsFor: 'accessing'!
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
- cascadeNodeWithMessages: aCollection
441
- | first |
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
- !SendNode methodsFor: 'visiting'!
345
+ Node subclass: #ReturnNode
346
+ instanceVariableNames: ''
347
+ category: 'Compiler'!
348
+
349
+ !ReturnNode methodsFor: 'visiting'!
453
350
 
454
351
  accept: aVisitor
455
- aVisitor visitSendNode: self
352
+ aVisitor visitReturnNode: self
456
353
  ! !
457
354
 
458
- Node subclass: #CascadeNode
459
- instanceVariableNames: 'receiver'
355
+ Node subclass: #ValueNode
356
+ instanceVariableNames: 'value'
460
357
  category: 'Compiler'!
461
358
 
462
- !CascadeNode methodsFor: 'accessing'!
359
+ !ValueNode methodsFor: 'accessing'!
463
360
 
464
- receiver
465
- ^receiver
361
+ value
362
+ ^value
466
363
  !
467
364
 
468
- receiver: aNode
469
- receiver := aNode
365
+ value: anObject
366
+ value := anObject
470
367
  ! !
471
368
 
472
- !CascadeNode methodsFor: 'visiting'!
369
+ !ValueNode methodsFor: 'testing'!
473
370
 
474
- accept: aVisitor
475
- aVisitor visitCascadeNode: self
371
+ isValueNode
372
+ ^true
476
373
  ! !
477
374
 
478
- Node subclass: #AssignmentNode
479
- instanceVariableNames: 'left right'
480
- category: 'Compiler'!
375
+ !ValueNode methodsFor: 'visiting'!
481
376
 
482
- !AssignmentNode methodsFor: 'accessing'!
377
+ accept: aVisitor
378
+ aVisitor visitValueNode: self
379
+ ! !
483
380
 
484
- left
485
- ^left
486
- !
381
+ ValueNode subclass: #VariableNode
382
+ instanceVariableNames: 'assigned'
383
+ category: 'Compiler'!
487
384
 
488
- left: aNode
489
- left := aNode.
490
- left assigned: true
491
- !
385
+ !VariableNode methodsFor: 'accessing'!
492
386
 
493
- right
494
- ^right
387
+ assigned
388
+ ^assigned ifNil: [false]
495
389
  !
496
390
 
497
- right: aNode
498
- right := aNode
391
+ assigned: aBoolean
392
+ assigned := aBoolean
499
393
  ! !
500
394
 
501
- !AssignmentNode methodsFor: 'visiting'!
395
+ !VariableNode methodsFor: 'visiting'!
502
396
 
503
397
  accept: aVisitor
504
- aVisitor visitAssignmentNode: self
398
+ aVisitor visitVariableNode: self
505
399
  ! !
506
400
 
507
- Node subclass: #BlockNode
508
- instanceVariableNames: 'parameters inlined'
401
+ Exporter subclass: #ChunkExporter
402
+ instanceVariableNames: ''
509
403
  category: 'Compiler'!
510
404
 
511
- !BlockNode methodsFor: 'accessing'!
405
+ !ChunkExporter methodsFor: 'not yet classified'!
512
406
 
513
- parameters
514
- ^parameters ifNil: [parameters := Array new]
515
- !
407
+ exportDefinitionOf: aClass on: aStream
408
+ "Chunk format."
516
409
 
517
- parameters: aCollection
518
- parameters := aCollection
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
- inlined
522
- ^inlined ifNil: [false]
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
- inlined: aBoolean
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
- Node subclass: #SequenceNode
542
- instanceVariableNames: 'temps'
543
- category: 'Compiler'!
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
- !SequenceNode methodsFor: 'accessing'!
444
+ exportMetaDefinitionOf: aClass on: aStream
546
445
 
547
- temps
548
- ^temps ifNil: [#()]
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
- temps: aCollection
552
- temps := aCollection
553
- ! !
554
-
555
- !SequenceNode methodsFor: 'testing'!
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
- asBlockSequenceNode
558
- ^BlockSequenceNode new
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
- !SequenceNode methodsFor: 'visiting'!
469
+ ^(aString replace: '!!' with: '!!!!') trimBoth
470
+ !
565
471
 
566
- accept: aVisitor
567
- aVisitor visitSequenceNode: self
568
- ! !
472
+ exportMethods: methods category: category of: aClass on: aStream
569
473
 
570
- SequenceNode subclass: #BlockSequenceNode
571
- instanceVariableNames: ''
572
- category: 'Compiler'!
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
- !BlockSequenceNode methodsFor: 'testing'!
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
- isBlockSequenceNode
577
- ^true
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
- !BlockSequenceNode methodsFor: 'visiting'!
495
+ exportPackageDefinitionOf: package on: aStream
496
+ "Chunk format."
581
497
 
582
- accept: aVisitor
583
- aVisitor visitBlockSequenceNode: self
498
+ aStream
499
+ nextPutAll: 'Smalltalk current createPackage: ''', package name,
500
+ ''' properties: ', package properties storeString, '!!'; lf.
584
501
  ! !
585
502
 
586
- Node subclass: #ReturnNode
503
+ VariableNode subclass: #ClassReferenceNode
587
504
  instanceVariableNames: ''
588
505
  category: 'Compiler'!
589
506
 
590
- !ReturnNode methodsFor: 'visiting'!
507
+ !ClassReferenceNode methodsFor: 'visiting'!
591
508
 
592
509
  accept: aVisitor
593
- aVisitor visitReturnNode: self
510
+ aVisitor visitClassReferenceNode: self
594
511
  ! !
595
512
 
596
- Node subclass: #ValueNode
597
- instanceVariableNames: 'value'
513
+ Node subclass: #SendNode
514
+ instanceVariableNames: 'selector arguments receiver'
598
515
  category: 'Compiler'!
599
516
 
600
- !ValueNode methodsFor: 'accessing'!
517
+ !SendNode methodsFor: 'accessing'!
601
518
 
602
- value
603
- ^value
519
+ selector
520
+ ^selector
604
521
  !
605
522
 
606
- value: anObject
607
- value := anObject
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
- ValueNode subclass: #VariableNode
623
- instanceVariableNames: 'assigned'
624
- category: 'Compiler'!
527
+ arguments
528
+ ^arguments ifNil: [arguments := #()]
529
+ !
625
530
 
626
- !VariableNode methodsFor: 'accessing'!
531
+ arguments: aCollection
532
+ arguments := aCollection
533
+ !
627
534
 
628
- assigned
629
- ^assigned ifNil: [false]
535
+ receiver
536
+ ^receiver
630
537
  !
631
538
 
632
- assigned: aBoolean
633
- assigned := aBoolean
634
- ! !
539
+ receiver: aNode
540
+ receiver := aNode
541
+ !
635
542
 
636
- !VariableNode methodsFor: 'visiting'!
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
- accept: aVisitor
639
- aVisitor visitVariableNode: self
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
- VariableNode subclass: #ClassReferenceNode
643
- instanceVariableNames: ''
644
- category: 'Compiler'!
645
-
646
- !ClassReferenceNode methodsFor: 'visiting'!
565
+ !SendNode methodsFor: 'visiting'!
647
566
 
648
567
  accept: aVisitor
649
- aVisitor visitClassReferenceNode: self
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
- Object subclass: #NodeVisitor
673
- instanceVariableNames: ''
591
+ Node subclass: #AssignmentNode
592
+ instanceVariableNames: 'left right'
674
593
  category: 'Compiler'!
675
594
 
676
- !NodeVisitor methodsFor: 'visiting'!
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
- visitSendNode: aNode
706
- self visitNode: aNode
597
+ left
598
+ ^left
707
599
  !
708
600
 
709
- visitCascadeNode: aNode
710
- self visitNode: aNode
601
+ left: aNode
602
+ left := aNode.
603
+ left assigned: true
711
604
  !
712
605
 
713
- visitValueNode: aNode
714
- self visitNode: aNode
606
+ right
607
+ ^right
715
608
  !
716
609
 
717
- visitVariableNode: aNode
718
- !
610
+ right: aNode
611
+ right := aNode
612
+ ! !
719
613
 
720
- visitAssignmentNode: aNode
721
- self visitNode: aNode
722
- !
614
+ !AssignmentNode methodsFor: 'visiting'!
723
615
 
724
- visitClassReferenceNode: aNode
725
- self
726
- nextPutAll: 'smalltalk.';
727
- nextPutAll: aNode value
728
- !
616
+ accept: aVisitor
617
+ aVisitor visitAssignmentNode: self
618
+ ! !
729
619
 
730
- visitJSStatementNode: aNode
731
- self
732
- nextPutAll: 'function(){';
733
- nextPutAll: aNode source;
734
- nextPutAll: '})()'
735
- !
620
+ Node subclass: #DynamicArrayNode
621
+ instanceVariableNames: ''
622
+ category: 'Compiler'!
736
623
 
737
- visitDynamicArrayNode: aNode
738
- self visitNode: aNode
739
- !
624
+ !DynamicArrayNode methodsFor: 'visiting'!
740
625
 
741
- visitDynamicDictionaryNode: aNode
742
- self visitNode: aNode
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
- Object subclass: #DoIt
1287
+ SequenceNode subclass: #BlockSequenceNode
1403
1288
  instanceVariableNames: ''
1404
1289
  category: 'Compiler'!
1405
1290
 
1406
- Node subclass: #DynamicArrayNode
1407
- instanceVariableNames: ''
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
- !DynamicArrayNode methodsFor: 'visiting'!
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 visitDynamicArrayNode: self
1334
+ aVisitor visitBlockNode: self
1414
1335
  ! !
1415
1336
 
1416
- Node subclass: #DynamicDictionaryNode
1417
- instanceVariableNames: ''
1337
+ Node subclass: #CascadeNode
1338
+ instanceVariableNames: 'receiver'
1418
1339
  category: 'Compiler'!
1419
1340
 
1420
- !DynamicDictionaryNode methodsFor: 'visiting'!
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 visitDynamicDictionaryNode: self
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