resin 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. data/amber/css/amber-normalize.css +73 -73
  2. data/amber/css/amber-normalize.less +1 -1
  3. data/amber/css/amber.css +106 -106
  4. data/amber/css/helios.css +242 -0
  5. data/amber/images/hsplitter.png +0 -0
  6. data/amber/images/vsplitter.png +0 -0
  7. data/amber/js/Benchfib.deploy.js +116 -38
  8. data/amber/js/Benchfib.js +120 -42
  9. data/amber/js/Canvas.deploy.js +674 -403
  10. data/amber/js/Canvas.js +682 -411
  11. data/amber/js/Compiler-AST.deploy.js +1150 -0
  12. data/amber/js/Compiler-AST.js +1591 -0
  13. data/amber/js/Compiler-Core.deploy.js +1562 -0
  14. data/amber/js/Compiler-Core.js +1972 -0
  15. data/amber/js/Compiler-Exceptions.deploy.js +114 -0
  16. data/amber/js/Compiler-Exceptions.js +161 -0
  17. data/amber/js/Compiler-IR.deploy.js +2326 -0
  18. data/amber/js/Compiler-IR.js +3146 -0
  19. data/amber/js/Compiler-Inlining.deploy.js +1147 -0
  20. data/amber/js/Compiler-Inlining.js +1514 -0
  21. data/amber/js/Compiler-Semantic.deploy.js +1207 -0
  22. data/amber/js/Compiler-Semantic.js +1628 -0
  23. data/amber/js/Compiler-Tests.deploy.js +646 -60
  24. data/amber/js/Compiler-Tests.js +843 -82
  25. data/amber/js/Compiler.deploy.js +1097 -159
  26. data/amber/js/Compiler.js +1414 -161
  27. data/amber/js/Examples.deploy.js +31 -15
  28. data/amber/js/Examples.js +33 -17
  29. data/amber/js/Helios-Announcements.deploy.js +127 -0
  30. data/amber/js/Helios-Announcements.js +157 -0
  31. data/amber/js/Helios-Browser.deploy.js +1473 -0
  32. data/amber/js/Helios-Browser.js +1953 -0
  33. data/amber/js/Helios-Commands.deploy.js +403 -0
  34. data/amber/js/Helios-Commands.js +563 -0
  35. data/amber/js/Helios-Core.deploy.js +1070 -0
  36. data/amber/js/Helios-Core.js +1445 -0
  37. data/amber/js/Helios-Environments.deploy.js +132 -0
  38. data/amber/js/Helios-Environments.js +179 -0
  39. data/amber/js/Helios-Inspector.deploy.js +855 -0
  40. data/amber/js/Helios-Inspector.js +1155 -0
  41. data/amber/js/Helios-KeyBindings.deploy.js +753 -0
  42. data/amber/js/Helios-KeyBindings.js +1023 -0
  43. data/amber/js/Helios-Layout.deploy.js +383 -0
  44. data/amber/js/Helios-Layout.js +523 -0
  45. data/amber/js/Helios-Workspace.deploy.js +799 -0
  46. data/amber/js/Helios-Workspace.js +1074 -0
  47. data/amber/js/IDE.deploy.js +2541 -1490
  48. data/amber/js/IDE.js +2721 -1660
  49. data/amber/js/Importer-Exporter.deploy.js +671 -0
  50. data/amber/js/Importer-Exporter.js +816 -0
  51. data/amber/js/Kernel-Announcements.deploy.js +137 -20
  52. data/amber/js/Kernel-Announcements.js +176 -22
  53. data/amber/js/Kernel-Classes.deploy.js +555 -168
  54. data/amber/js/Kernel-Classes.js +662 -205
  55. data/amber/js/Kernel-Collections.deploy.js +1403 -618
  56. data/amber/js/Kernel-Collections.js +1545 -690
  57. data/amber/js/Kernel-Exceptions.deploy.js +109 -45
  58. data/amber/js/Kernel-Exceptions.js +123 -49
  59. data/amber/js/Kernel-Methods.deploy.js +196 -81
  60. data/amber/js/Kernel-Methods.js +214 -89
  61. data/amber/js/Kernel-Objects.deploy.js +1542 -1117
  62. data/amber/js/Kernel-Objects.js +1593 -1148
  63. data/amber/js/Kernel-Tests.deploy.js +1725 -772
  64. data/amber/js/Kernel-Tests.js +2301 -1123
  65. data/amber/js/Kernel-Transcript.deploy.js +23 -25
  66. data/amber/js/Kernel-Transcript.js +24 -26
  67. data/amber/js/SUnit.deploy.js +204 -131
  68. data/amber/js/SUnit.js +222 -139
  69. data/amber/js/Spaces.deploy.js +240 -0
  70. data/amber/js/Spaces.js +326 -0
  71. data/amber/js/amber.js +26 -7
  72. data/amber/js/boot.js +65 -47
  73. data/amber/js/init.js +1 -1
  74. data/amber/js/lib/CodeMirror/amber.css +21 -21
  75. data/amber/js/lib/CodeMirror/codemirror.css +119 -13
  76. data/amber/js/lib/CodeMirror/codemirror.js +2219 -1220
  77. data/amber/js/lib/CodeMirror/smalltalk.js +134 -129
  78. data/amber/js/lib/bootstrap/css/bootstrap.css +5837 -0
  79. data/amber/js/lib/bootstrap/css/bootstrap.min.css +841 -0
  80. data/amber/js/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
  81. data/amber/js/lib/bootstrap/img/glyphicons-halflings.png +0 -0
  82. data/amber/js/lib/bootstrap/js/bootstrap.js +2038 -0
  83. data/amber/js/lib/bootstrap/js/bootstrap.min.js +7 -0
  84. data/amber/js/lib/jQuery/jquery-1.8.2.min.js +2 -0
  85. data/amber/js/lib/jQuery/jquery-ui-1.8.24.custom.min.js +125 -0
  86. data/amber/st/Compiler-AST.st +505 -0
  87. data/amber/st/Compiler-Core.st +835 -0
  88. data/amber/st/Compiler-Exceptions.st +87 -0
  89. data/amber/st/Compiler-IR.st +1097 -0
  90. data/amber/st/Compiler-Inlining.st +650 -0
  91. data/amber/st/Compiler-Semantic.st +558 -0
  92. data/amber/st/Compiler-Tests.st +285 -381
  93. data/amber/st/Compiler.st +725 -2
  94. data/amber/st/Helios-Announcements.st +104 -0
  95. data/amber/st/Helios-Browser.st +708 -0
  96. data/amber/st/Helios-Commands.st +223 -0
  97. data/amber/st/Helios-Core.st +532 -0
  98. data/amber/st/Helios-Environments.st +98 -0
  99. data/amber/st/Helios-Inspector.st +367 -0
  100. data/amber/st/Helios-KeyBindings.st +337 -0
  101. data/amber/st/Helios-Layout.st +199 -0
  102. data/amber/st/Helios-Workspace.st +367 -0
  103. data/amber/st/IDE.st +75 -53
  104. data/amber/st/Importer-Exporter.st +386 -0
  105. data/amber/st/Kernel-Announcements.st +92 -0
  106. data/amber/st/Kernel-Classes.st +137 -15
  107. data/amber/st/Kernel-Collections.st +137 -47
  108. data/amber/st/Kernel-Exceptions.st +14 -0
  109. data/amber/st/Kernel-Methods.st +9 -1
  110. data/amber/st/Kernel-Objects.st +29 -5
  111. data/amber/st/Kernel-Tests.st +545 -199
  112. data/amber/st/SUnit.st +10 -0
  113. data/amber/st/Spaces.st +142 -0
  114. data/lib/resin/app.rb +1 -1
  115. metadata +86 -31
  116. data/amber/js/lib/jQuery/jquery-1.4.4.min.js +0 -167
  117. data/amber/js/lib/jQuery/jquery-1.6.4.min.js +0 -4
data/amber/st/Compiler.st CHANGED
@@ -41,13 +41,17 @@ on: aStream
41
41
  ! !
42
42
 
43
43
  Object subclass: #Compiler
44
- instanceVariableNames: 'currentClass source unknownVariables'
44
+ instanceVariableNames: 'currentClass source unknownVariables codeGeneratorClass'
45
45
  package: 'Compiler'!
46
46
 
47
47
  !Compiler methodsFor: 'accessing'!
48
48
 
49
49
  codeGeneratorClass
50
- ^FunCodeGenerator
50
+ ^codeGeneratorClass ifNil: [FunCodeGenerator]
51
+ !
52
+
53
+ codeGeneratorClass: aClass
54
+ codeGeneratorClass := aClass
51
55
  !
52
56
 
53
57
  currentClass
@@ -833,6 +837,26 @@ accept: aVisitor
833
837
  aVisitor visitClassReferenceNode: self
834
838
  ! !
835
839
 
840
+ Node subclass: #VerbatimNode
841
+ instanceVariableNames: 'value'
842
+ package: 'Compiler'!
843
+
844
+ !VerbatimNode methodsFor: 'accessing'!
845
+
846
+ value
847
+ ^value
848
+ !
849
+
850
+ value: anObject
851
+ value := anObject
852
+ ! !
853
+
854
+ !VerbatimNode methodsFor: 'visiting'!
855
+
856
+ accept: aVisitor
857
+ aVisitor visitVerbatimNode: self
858
+ ! !
859
+
836
860
  Object subclass: #NodeVisitor
837
861
  instanceVariableNames: ''
838
862
  package: 'Compiler'!
@@ -900,6 +924,10 @@ visitValueNode: aNode
900
924
 
901
925
  visitVariableNode: aNode
902
926
  self visitNode: aNode
927
+ !
928
+
929
+ visitVerbatimNode: aNode
930
+ self visitNode: aNode
903
931
  ! !
904
932
 
905
933
  NodeVisitor subclass: #AbstractCodeGenerator
@@ -1488,3 +1516,698 @@ performOptimizations: aBoolean
1488
1516
  performOptimizations := aBoolean
1489
1517
  ! !
1490
1518
 
1519
+ AbstractCodeGenerator subclass: #ImpCodeGenerator
1520
+ instanceVariableNames: 'stream nestedBlocks earlyReturn currentSelector unknownVariables tempVariables messageSends referencedClasses classReferenced argVariables mutables target lazyVars realVarNames'
1521
+ package: 'Compiler'!
1522
+
1523
+ !ImpCodeGenerator methodsFor: 'accessing'!
1524
+
1525
+ argVariables
1526
+ ^argVariables copy
1527
+ !
1528
+
1529
+ knownVariables
1530
+ ^self pseudoVariables
1531
+ addAll: self tempVariables;
1532
+ addAll: self argVariables;
1533
+ yourself
1534
+ !
1535
+
1536
+ tempVariables
1537
+ ^tempVariables copy
1538
+ !
1539
+
1540
+ unknownVariables
1541
+ ^unknownVariables copy
1542
+ ! !
1543
+
1544
+ !ImpCodeGenerator methodsFor: 'compilation DSL'!
1545
+
1546
+ aboutToModifyState
1547
+ | list old |
1548
+ list := mutables.
1549
+ mutables := Set new.
1550
+ old := self switchTarget: nil.
1551
+ list do: [ :each | | value |
1552
+ self switchTarget: each.
1553
+ self realAssign: (lazyVars at: each)
1554
+ ].
1555
+ self switchTarget: old
1556
+ !
1557
+
1558
+ ifValueWanted: aBlock
1559
+ target ifNotNil: aBlock
1560
+ !
1561
+
1562
+ isolated: node
1563
+ ^ self visit: node targetBeing: self nextLazyvarName
1564
+ !
1565
+
1566
+ isolatedUse: node
1567
+ | old |
1568
+ old := self switchTarget: self nextLazyvarName.
1569
+ self visit: node.
1570
+ ^self useValueNamed: (self switchTarget: old)
1571
+ !
1572
+
1573
+ lazyAssign: aString dependsOnState: aBoolean
1574
+ (lazyVars includesKey: target)
1575
+ ifTrue: [ lazyVars at: target put: aString. aBoolean ifTrue: [ mutables add: target ] ]
1576
+ ifFalse: [ self realAssign: aString ]
1577
+ !
1578
+
1579
+ lazyAssignExpression: aString
1580
+ self lazyAssign: aString dependsOnState: true
1581
+ !
1582
+
1583
+ lazyAssignValue: aString
1584
+ self lazyAssign: aString dependsOnState: false
1585
+ !
1586
+
1587
+ makeTargetRealVariable
1588
+ (lazyVars includesKey: target) ifTrue: [
1589
+ lazyVars removeKey: target.
1590
+ lazyVars at: 'assigned ',target put: nil. "<-- only to retain size, it is used in nextLazyvarName"
1591
+ realVarNames add: target ].
1592
+ !
1593
+
1594
+ nextLazyvarName
1595
+ | name |
1596
+ name := '$', lazyVars size asString.
1597
+ lazyVars at: name put: name.
1598
+ ^name
1599
+ !
1600
+
1601
+ nilIfValueWanted
1602
+ target ifNotNil: [ self lazyAssignValue: 'nil' ]
1603
+ !
1604
+
1605
+ realAssign: aString
1606
+ | closer |
1607
+ aString ifNotEmpty: [
1608
+ self aboutToModifyState.
1609
+ closer := ''.
1610
+ self ifValueWanted: [ stream nextPutAll:
1611
+ (target = '^' ifTrue: ['return '] ifFalse: [
1612
+ target = '!!' ifTrue: [ closer := ']'. 'throw $early=['] ifFalse: [
1613
+ target, '=']]) ].
1614
+ self makeTargetRealVariable.
1615
+ stream nextPutAll: aString, closer, ';', self mylf ]
1616
+ !
1617
+
1618
+ switchTarget: aString
1619
+ | old |
1620
+ old := target.
1621
+ target := aString.
1622
+ ^old
1623
+ !
1624
+
1625
+ useValueNamed: key
1626
+ | val |
1627
+ (realVarNames includes: key) ifTrue: [ ^key ].
1628
+ mutables remove: key.
1629
+ ^lazyVars at: key
1630
+ !
1631
+
1632
+ visit: aNode targetBeing: aString
1633
+ | old |
1634
+ old := self switchTarget: aString.
1635
+ self visit: aNode.
1636
+ ^ self switchTarget: old.
1637
+ ! !
1638
+
1639
+ !ImpCodeGenerator methodsFor: 'compiling'!
1640
+
1641
+ compileNode: aNode
1642
+ stream := '' writeStream.
1643
+ self visit: aNode.
1644
+ ^stream contents
1645
+ ! !
1646
+
1647
+ !ImpCodeGenerator methodsFor: 'initialization'!
1648
+
1649
+ initialize
1650
+ super initialize.
1651
+ stream := '' writeStream.
1652
+ unknownVariables := #().
1653
+ tempVariables := #().
1654
+ argVariables := #().
1655
+ messageSends := #().
1656
+ classReferenced := #().
1657
+ mutables := Set new.
1658
+ realVarNames := Set new.
1659
+ lazyVars := HashedCollection new.
1660
+ target := nil
1661
+ ! !
1662
+
1663
+ !ImpCodeGenerator methodsFor: 'optimizations'!
1664
+
1665
+ checkClass: aClassName for: receiver
1666
+ self prvCheckClass: aClassName for: receiver.
1667
+ stream nextPutAll: '{'
1668
+ !
1669
+
1670
+ checkClass: aClassName for: receiver includeIf: aBoolean
1671
+ self prvCheckClass: aClassName for: receiver.
1672
+ stream nextPutAll: (aBoolean ifTrue: ['if(('] ifFalse: ['if(!!(']), (self useValueNamed: receiver), ')) {'
1673
+ !
1674
+
1675
+ inline: aSelector receiver: receiver argumentNodes: aCollection
1676
+
1677
+ "-- Booleans --"
1678
+
1679
+ (aSelector = 'ifFalse:') ifTrue: [
1680
+ aCollection first isBlockNode ifTrue: [
1681
+ self checkClass: 'Boolean' for: receiver includeIf: false.
1682
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1683
+ self prvPutAndElse: [ self nilIfValueWanted ].
1684
+ ^true]].
1685
+
1686
+ (aSelector = 'ifTrue:') ifTrue: [
1687
+ aCollection first isBlockNode ifTrue: [
1688
+ self checkClass: 'Boolean' for: receiver includeIf: true.
1689
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1690
+ self prvPutAndElse: [ self nilIfValueWanted ].
1691
+ ^true]].
1692
+
1693
+ (aSelector = 'ifTrue:ifFalse:') ifTrue: [
1694
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
1695
+ self checkClass: 'Boolean' for: receiver includeIf: true.
1696
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1697
+ self prvPutAndElse: [ self visit: aCollection second nodes first ].
1698
+ ^true]].
1699
+
1700
+ (aSelector = 'ifFalse:ifTrue:') ifTrue: [
1701
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [
1702
+ self checkClass: 'Boolean' for: receiver includeIf: false.
1703
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1704
+ self prvPutAndElse: [ self visit: aCollection second nodes first ].
1705
+ ^true]].
1706
+
1707
+ "-- Numbers --"
1708
+
1709
+ (aSelector = '<') ifTrue: [ | operand |
1710
+ operand := self isolatedUse: aCollection first.
1711
+ self checkClass: 'Number' for: receiver.
1712
+ self prvPutAndElse: [
1713
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '<', operand, ')' ].
1714
+ ^{ VerbatimNode new value: operand }].
1715
+
1716
+ (aSelector = '<=') ifTrue: [ | operand |
1717
+ operand := self isolatedUse: aCollection first.
1718
+ self checkClass: 'Number' for: receiver.
1719
+ self prvPutAndElse: [
1720
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '<=', operand, ')' ].
1721
+ ^{ VerbatimNode new value: operand }].
1722
+
1723
+ (aSelector = '>') ifTrue: [ | operand |
1724
+ operand := self isolatedUse: aCollection first.
1725
+ self checkClass: 'Number' for: receiver.
1726
+ self prvPutAndElse: [
1727
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '>', operand, ')' ].
1728
+ ^{ VerbatimNode new value: operand }].
1729
+
1730
+ (aSelector = '>=') ifTrue: [ | operand |
1731
+ operand := self isolatedUse: aCollection first.
1732
+ self checkClass: 'Number' for: receiver.
1733
+ self prvPutAndElse: [
1734
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '>=', operand, ')' ].
1735
+ ^{ VerbatimNode new value: operand }].
1736
+
1737
+ (aSelector = '+') ifTrue: [ | operand |
1738
+ operand := self isolatedUse: aCollection first.
1739
+ self checkClass: 'Number' for: receiver.
1740
+ self prvPutAndElse: [
1741
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '+', operand, ')' ].
1742
+ ^{ VerbatimNode new value: operand }].
1743
+
1744
+ (aSelector = '-') ifTrue: [ | operand |
1745
+ operand := self isolatedUse: aCollection first.
1746
+ self checkClass: 'Number' for: receiver.
1747
+ self prvPutAndElse: [
1748
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '-', operand, ')' ].
1749
+ ^{ VerbatimNode new value: operand }].
1750
+
1751
+ (aSelector = '*') ifTrue: [ | operand |
1752
+ operand := self isolatedUse: aCollection first.
1753
+ self checkClass: 'Number' for: receiver.
1754
+ self prvPutAndElse: [
1755
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '*', operand, ')' ].
1756
+ ^{ VerbatimNode new value: operand }].
1757
+
1758
+ (aSelector = '/') ifTrue: [ | operand |
1759
+ operand := self isolatedUse: aCollection first.
1760
+ self checkClass: 'Number' for: receiver.
1761
+ self prvPutAndElse: [
1762
+ self lazyAssignExpression: '(', (self useValueNamed: receiver), '/', operand, ')' ].
1763
+ ^{ VerbatimNode new value: operand }].
1764
+
1765
+ ^nil
1766
+ !
1767
+
1768
+ inlineLiteral: aSelector receiverNode: anObject argumentNodes: aCollection
1769
+ | inlined |
1770
+ inlined := false.
1771
+
1772
+ "-- BlockClosures --"
1773
+
1774
+ (aSelector = 'whileTrue:') ifTrue: [
1775
+ (anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
1776
+ self prvWhileConditionStatement: 'for(;;){' pre: 'if (!!(' condition: anObject post: ')) {'.
1777
+ stream nextPutAll: 'break}', self mylf.
1778
+ self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
1779
+ inlined := true]].
1780
+
1781
+ (aSelector = 'whileFalse:') ifTrue: [
1782
+ (anObject isBlockNode and: [aCollection first isBlockNode]) ifTrue: [ | old |
1783
+ self prvWhileConditionStatement: 'for(;;){' pre: 'if ((' condition: anObject post: ')) {'.
1784
+ stream nextPutAll: 'break}', self mylf.
1785
+ self prvPutAndClose: [ self visit: aCollection first nodes first targetBeing: nil ].
1786
+ inlined := true]].
1787
+
1788
+ (aSelector = 'whileTrue') ifTrue: [
1789
+ anObject isBlockNode ifTrue: [
1790
+ self prvWhileConditionStatement: 'do{' pre: '}while((' condition: anObject post: '));', self mylf.
1791
+ inlined := true]].
1792
+
1793
+ (aSelector = 'whileFalse') ifTrue: [
1794
+ anObject isBlockNode ifTrue: [
1795
+ self prvWhileConditionStatement: 'do{' pre: '}while(!!(' condition: anObject post: '));', self mylf.
1796
+ inlined := true]].
1797
+
1798
+ "-- Numbers --"
1799
+
1800
+ (#('+' '-' '*' '/' '<' '<=' '>=' '>') includes: aSelector) ifTrue: [
1801
+ (self prvInlineNumberOperator: aSelector on: anObject and: aCollection first) ifTrue: [
1802
+ inlined := true]].
1803
+
1804
+ "-- UndefinedObject --"
1805
+
1806
+ (aSelector = 'ifNil:') ifTrue: [
1807
+ aCollection first isBlockNode ifTrue: [ | rcv |
1808
+ self aboutToModifyState.
1809
+ rcv := self isolatedUse: anObject.
1810
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1811
+ self makeTargetRealVariable.
1812
+ stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
1813
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1814
+ self prvPutAndClose: [ self lazyAssignValue: rcv ].
1815
+ inlined := true]].
1816
+
1817
+ (aSelector = 'ifNotNil:') ifTrue: [
1818
+ aCollection first isBlockNode ifTrue: [ | rcv |
1819
+ self aboutToModifyState.
1820
+ rcv := self isolatedUse: anObject.
1821
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1822
+ self makeTargetRealVariable.
1823
+ stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
1824
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1825
+ self prvPutAndClose: [ self lazyAssignValue: rcv ].
1826
+ inlined := true]].
1827
+
1828
+ (aSelector = 'ifNil:ifNotNil:') ifTrue: [
1829
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
1830
+ self aboutToModifyState.
1831
+ rcv := self isolatedUse: anObject.
1832
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1833
+ self makeTargetRealVariable.
1834
+ stream nextPutAll: 'if((', rcv, ') === nil || (', rcv, ') == null) {'.
1835
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1836
+ self prvPutAndClose: [ self visit: aCollection second nodes first ].
1837
+ inlined := true]].
1838
+
1839
+ (aSelector = 'ifNotNil:ifNil:') ifTrue: [
1840
+ (aCollection first isBlockNode and: [aCollection second isBlockNode]) ifTrue: [ | rcv |
1841
+ self aboutToModifyState.
1842
+ rcv := self isolatedUse: anObject.
1843
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1844
+ self makeTargetRealVariable.
1845
+ stream nextPutAll: 'if((', rcv, ') !!== nil && (', rcv, ') !!= null) {'.
1846
+ self prvPutAndElse: [ self visit: aCollection first nodes first ].
1847
+ self prvPutAndClose: [ self visit: aCollection second nodes first ].
1848
+ inlined := true]].
1849
+
1850
+ (aSelector = 'isNil') ifTrue: [ | rcv |
1851
+ rcv := self isolatedUse: anObject.
1852
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1853
+ self lazyAssignValue: '((', rcv, ') === nil || (', rcv, ') == null)'.
1854
+ inlined := true].
1855
+
1856
+ (aSelector = 'notNil') ifTrue: [ | rcv |
1857
+ rcv := self isolatedUse: anObject.
1858
+ rcv = 'super' ifTrue: [ rcv := 'self' ].
1859
+ self lazyAssignValue: '((', rcv, ') !!== nil && (', rcv, ') !!= null)'.
1860
+ inlined := true].
1861
+
1862
+ ^inlined
1863
+ !
1864
+
1865
+ isNode: aNode ofClass: aClass
1866
+ ^aNode isValueNode and: [
1867
+ aNode value class = aClass or: [
1868
+ aNode value = 'self' and: [self currentClass = aClass]]]
1869
+ !
1870
+
1871
+ prvCheckClass: aClassName for: receiver
1872
+ self makeTargetRealVariable.
1873
+ self aboutToModifyState.
1874
+ stream nextPutAll: 'if((', (self useValueNamed: receiver), ').klass === smalltalk.', aClassName, ') '
1875
+ !
1876
+
1877
+ prvInlineNumberOperator: aSelector on: receiverNode and: operandNode
1878
+ (aSelector = aSelector) ifTrue: [
1879
+ (self isNode: receiverNode ofClass: Number) ifTrue: [
1880
+ | rcv operand |
1881
+ rcv := self isolated: receiverNode.
1882
+ operand := self isolated: operandNode.
1883
+ self lazyAssignValue: ((self useValueNamed: rcv), aSelector, (self useValueNamed: operand)).
1884
+ ^true]].
1885
+ ^false
1886
+ !
1887
+
1888
+ prvWhileConditionStatement: stmtString pre: preString condition: anObject post: postString
1889
+ | x |
1890
+ stream nextPutAll: stmtString.
1891
+ x := self isolatedUse: anObject nodes first.
1892
+ x ifEmpty: [ x := '"should not reach - receiver includes ^"' ].
1893
+ stream nextPutAll: preString, x, postString.
1894
+ self nilIfValueWanted
1895
+ ! !
1896
+
1897
+ !ImpCodeGenerator methodsFor: 'output'!
1898
+
1899
+ mylf
1900
+ ^String lf, ((Array new: nestedBlocks+2) join: String tab)
1901
+ !
1902
+
1903
+ prvPutAndClose: aBlock
1904
+
1905
+ aBlock value.
1906
+ stream nextPutAll: '}', self mylf
1907
+ !
1908
+
1909
+ prvPutAndElse: aBlock
1910
+
1911
+ aBlock value.
1912
+ stream nextPutAll: '} else {'
1913
+ !
1914
+
1915
+ putTemps: temps
1916
+ temps ifNotEmpty: [
1917
+ stream nextPutAll: 'var '.
1918
+ temps do: [:each | | temp |
1919
+ temp := self safeVariableNameFor: each.
1920
+ tempVariables add: temp.
1921
+ stream nextPutAll: temp, '=nil'] separatedBy: [ stream nextPutAll: ',' ].
1922
+ stream nextPutAll: ';', self mylf
1923
+ ]
1924
+ ! !
1925
+
1926
+ !ImpCodeGenerator methodsFor: 'testing'!
1927
+
1928
+ assert: aBoolean
1929
+ aBoolean ifFalse: [ self error: 'assertion failed' ]
1930
+ !
1931
+
1932
+ performOptimizations
1933
+ ^self class performOptimizations
1934
+ ! !
1935
+
1936
+ !ImpCodeGenerator methodsFor: 'visiting'!
1937
+
1938
+ send: aSelector to: aReceiver arguments: aCollection superSend: aBoolean
1939
+ | args |
1940
+ args := self isolated: (DynamicArrayNode new nodes: aCollection; yourself).
1941
+ self lazyAssignExpression: (String streamContents: [ :str |
1942
+ str nextPutAll: 'smalltalk.send('.
1943
+ str nextPutAll: (self useValueNamed: aReceiver).
1944
+ str nextPutAll: ', "', aSelector asSelector, '", '.
1945
+ str nextPutAll: (self useValueNamed: args).
1946
+ aBoolean ifTrue: [
1947
+ str nextPutAll: ', smalltalk.', (self classNameFor: self currentClass superclass)].
1948
+ str nextPutAll: ')'
1949
+ ])
1950
+ !
1951
+
1952
+ sequenceOfNodes: nodes temps: temps
1953
+ nodes isEmpty
1954
+ ifFalse: [ | old index |
1955
+ self putTemps: temps.
1956
+ old :=self switchTarget: nil.
1957
+ index := 0.
1958
+ nodes do: [:each |
1959
+ index := index + 1.
1960
+ index = nodes size ifTrue: [ self switchTarget: old ].
1961
+ self visit: each ]]
1962
+ ifTrue: [ self nilIfValueWanted ]
1963
+ !
1964
+
1965
+ visit: aNode
1966
+ aNode accept: self
1967
+ !
1968
+
1969
+ visitAssignmentNode: aNode
1970
+ | olds oldt |
1971
+ olds := stream.
1972
+ stream := '' writeStream.
1973
+ oldt := self switchTarget: self nextLazyvarName.
1974
+ self visit: aNode left.
1975
+ self assert: (lazyVars at: target) ~= target.
1976
+ self switchTarget: (self useValueNamed: (self switchTarget: nil)).
1977
+ self assert: (lazyVars includesKey: target) not.
1978
+ stream := olds.
1979
+ self visit: aNode right.
1980
+ olds := self switchTarget: oldt.
1981
+ self ifValueWanted: [ self lazyAssignExpression: olds ]
1982
+ !
1983
+
1984
+ visitBlockNode: aNode
1985
+ | oldt olds oldm |
1986
+ self assert: aNode nodes size = 1.
1987
+ oldt := self switchTarget: '^'.
1988
+ olds := stream.
1989
+ stream := '' writeStream.
1990
+ stream nextPutAll: '(function('.
1991
+ aNode parameters
1992
+ do: [:each |
1993
+ tempVariables add: each.
1994
+ stream nextPutAll: each]
1995
+ separatedBy: [stream nextPutAll: ', '].
1996
+ stream nextPutAll: '){'.
1997
+ nestedBlocks := nestedBlocks + 1.
1998
+ oldm := mutables.
1999
+ mutables := Set new.
2000
+ self visit: aNode nodes first.
2001
+ self assert: mutables isEmpty.
2002
+ mutables := oldm.
2003
+ nestedBlocks := nestedBlocks - 1.
2004
+ stream nextPutAll: '})'.
2005
+ self switchTarget: oldt.
2006
+ oldt := stream contents.
2007
+ stream := olds.
2008
+ self lazyAssignExpression: oldt
2009
+ !
2010
+
2011
+ visitBlockSequenceNode: aNode
2012
+ self sequenceOfNodes: aNode nodes temps: aNode temps
2013
+ !
2014
+
2015
+ visitCascadeNode: aNode
2016
+ | rcv |
2017
+ rcv := self isolated: aNode receiver.
2018
+ self aboutToModifyState.
2019
+ rcv := self useValueNamed: rcv.
2020
+ aNode nodes do: [:each |
2021
+ each receiver: (VerbatimNode new value: rcv) ].
2022
+ self sequenceOfNodes: aNode nodes temps: #()
2023
+ !
2024
+
2025
+ visitClassReferenceNode: aNode
2026
+ (referencedClasses includes: aNode value) ifFalse: [
2027
+ referencedClasses add: aNode value].
2028
+ self lazyAssignExpression: '(smalltalk.', aNode value, ' || ', aNode value, ')'
2029
+ !
2030
+
2031
+ visitDynamicArrayNode: aNode
2032
+ | args |
2033
+ args :=aNode nodes collect: [ :node | self isolated: node ].
2034
+ self lazyAssignValue: (String streamContents: [ :str |
2035
+ str nextPutAll: '['.
2036
+ args
2037
+ do: [:each | str nextPutAll: (self useValueNamed: each) ]
2038
+ separatedBy: [str nextPutAll: ', '].
2039
+ str nextPutAll: ']'
2040
+ ])
2041
+ !
2042
+
2043
+ visitDynamicDictionaryNode: aNode
2044
+ | elements |
2045
+ elements := self isolated: (DynamicArrayNode new nodes: aNode nodes; yourself).
2046
+ self lazyAssignValue: 'smalltalk.HashedCollection._fromPairs_(', (self useValueNamed: elements), ')'
2047
+ !
2048
+
2049
+ visitFailure: aFailure
2050
+ self error: aFailure asString
2051
+ !
2052
+
2053
+ visitJSStatementNode: aNode
2054
+ self aboutToModifyState.
2055
+ stream nextPutAll: ';', (aNode source replace: '>>' with: '>'), ';', self mylf
2056
+ !
2057
+
2058
+ visitMethodNode: aNode
2059
+ | str currentSelector |
2060
+ currentSelector := aNode selector asSelector.
2061
+ nestedBlocks := 0.
2062
+ earlyReturn := false.
2063
+ messageSends := #().
2064
+ referencedClasses := #().
2065
+ unknownVariables := #().
2066
+ tempVariables := #().
2067
+ argVariables := #().
2068
+ lazyVars := HashedCollection new.
2069
+ mutables := Set new.
2070
+ realVarNames := Set new.
2071
+ stream
2072
+ nextPutAll: 'smalltalk.method({'; lf;
2073
+ nextPutAll: 'selector: "', aNode selector, '",'; lf.
2074
+ stream nextPutAll: 'source: ', self source asJavascript, ',';lf.
2075
+ stream nextPutAll: 'fn: function('.
2076
+ aNode arguments
2077
+ do: [:each |
2078
+ argVariables add: each.
2079
+ stream nextPutAll: each]
2080
+ separatedBy: [stream nextPutAll: ', '].
2081
+ stream
2082
+ nextPutAll: '){var self=this;', self mylf.
2083
+ str := stream.
2084
+ stream := '' writeStream.
2085
+ self switchTarget: nil.
2086
+ self assert: aNode nodes size = 1.
2087
+ self visit: aNode nodes first.
2088
+ realVarNames ifNotEmpty: [ str nextPutAll: 'var ', (realVarNames asArray join: ','), ';', self mylf ].
2089
+ earlyReturn ifTrue: [
2090
+ str nextPutAll: 'var $early={}; try{', self mylf].
2091
+ str nextPutAll: stream contents.
2092
+ stream := str.
2093
+ (aNode nodes first nodes notEmpty and: [ |checker|
2094
+ checker := ReturnNodeChecker new.
2095
+ checker visit: aNode nodes first nodes last.
2096
+ checker wasReturnNode]) ifFalse: [ self switchTarget: '^'. self lazyAssignValue: 'self'. self switchTarget: nil ].
2097
+ earlyReturn ifTrue: [
2098
+ stream nextPutAll: '} catch(e) {if(e===$early) return e[0]; throw e}'].
2099
+ stream nextPutAll: '}'.
2100
+ stream
2101
+ nextPutAll: ',', String lf, 'messageSends: ';
2102
+ nextPutAll: messageSends asJavascript, ','; lf;
2103
+ nextPutAll: 'args: ', argVariables asJavascript, ','; lf;
2104
+ nextPutAll: 'referencedClasses: ['.
2105
+ referencedClasses
2106
+ do: [:each | stream nextPutAll: each printString]
2107
+ separatedBy: [stream nextPutAll: ','].
2108
+ stream nextPutAll: ']'.
2109
+ stream nextPutAll: '})'.
2110
+ self assert: mutables isEmpty
2111
+ !
2112
+
2113
+ visitReturnNode: aNode
2114
+ self assert: aNode nodes size = 1.
2115
+ nestedBlocks > 0 ifTrue: [
2116
+ earlyReturn := true].
2117
+ self
2118
+ visit: aNode nodes first
2119
+ targetBeing: (nestedBlocks > 0 ifTrue: ['!!'] ifFalse: ['^']).
2120
+ self lazyAssignValue: ''
2121
+ !
2122
+
2123
+ visitSendNode: aNode
2124
+ | receiver superSend rcv |
2125
+ (messageSends includes: aNode selector) ifFalse: [
2126
+ messageSends add: aNode selector].
2127
+
2128
+ self performOptimizations
2129
+ ifTrue: [
2130
+ (self inlineLiteral: aNode selector receiverNode: aNode receiver argumentNodes: aNode arguments) ifTrue: [ ^self ].
2131
+ ].
2132
+
2133
+ rcv := self isolated: aNode receiver.
2134
+ superSend := (lazyVars at: rcv ifAbsent: []) = 'super'.
2135
+ superSend ifTrue: [ mutables remove: rcv. lazyVars at: rcv put: 'self' ].
2136
+
2137
+ self performOptimizations
2138
+ ifTrue: [ | inline |
2139
+ inline := self inline: aNode selector receiver: rcv argumentNodes: aNode arguments.
2140
+ inline ifNotNil: [ | args |
2141
+ args := inline = true ifTrue: [ aNode arguments ] ifFalse: [ inline ].
2142
+ self prvPutAndClose: [ self send: aNode selector to: rcv arguments: args superSend: superSend ].
2143
+ ^self ]].
2144
+ self send: aNode selector to: rcv arguments: aNode arguments superSend: superSend
2145
+ !
2146
+
2147
+ visitSequenceNode: aNode
2148
+ aNode nodes isEmpty ifFalse: [
2149
+ self sequenceOfNodes: aNode nodes temps: aNode temps ]
2150
+ !
2151
+
2152
+ visitValueNode: aNode
2153
+ self lazyAssignValue: aNode value asJavascript
2154
+ !
2155
+
2156
+ visitVariableNode: aNode
2157
+ | varName |
2158
+ (self currentClass allInstanceVariableNames includes: aNode value)
2159
+ ifTrue: [self lazyAssignExpression: 'self[''@', aNode value, ''']']
2160
+ ifFalse: [
2161
+ varName := self safeVariableNameFor: aNode value.
2162
+ (self knownVariables includes: varName)
2163
+ ifFalse: [
2164
+ unknownVariables add: aNode value.
2165
+ aNode assigned
2166
+ ifTrue: [self lazyAssignExpression: varName]
2167
+ ifFalse: [self lazyAssignExpression: '(typeof ', varName, ' == ''undefined'' ? nil : ', varName, ')']]
2168
+ ifTrue: [
2169
+ aNode value = 'thisContext'
2170
+ ifTrue: [self lazyAssignExpression: '(smalltalk.getThisContext())']
2171
+ ifFalse: [(self pseudoVariables includes: varName)
2172
+ ifTrue: [ self lazyAssignValue: varName ]
2173
+ ifFalse: [ self lazyAssignExpression: varName]]]]
2174
+ !
2175
+
2176
+ visitVerbatimNode: aNode
2177
+ self lazyAssignValue: aNode value
2178
+ ! !
2179
+
2180
+ ImpCodeGenerator class instanceVariableNames: 'performOptimizations'!
2181
+
2182
+ !ImpCodeGenerator class methodsFor: 'accessing'!
2183
+
2184
+ performOptimizations
2185
+ ^performOptimizations ifNil: [true]
2186
+ !
2187
+
2188
+ performOptimizations: aBoolean
2189
+ performOptimizations := aBoolean
2190
+ ! !
2191
+
2192
+ NodeVisitor subclass: #ReturnNodeChecker
2193
+ instanceVariableNames: 'wasReturnNode'
2194
+ package: 'Compiler'!
2195
+
2196
+ !ReturnNodeChecker methodsFor: 'accessing'!
2197
+
2198
+ wasReturnNode
2199
+ ^wasReturnNode
2200
+ ! !
2201
+
2202
+ !ReturnNodeChecker methodsFor: 'initializing'!
2203
+
2204
+ initialize
2205
+ wasReturnNode := false
2206
+ ! !
2207
+
2208
+ !ReturnNodeChecker methodsFor: 'visiting'!
2209
+
2210
+ visitReturnNode: aNode
2211
+ wasReturnNode := true
2212
+ ! !
2213
+