resin 0.0.1 → 0.0.2

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