resin 0.2.2 → 0.2.3

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