Axxord.st 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. Smalltalk createPackage: 'Axxord'!
  2. (Smalltalk packageAt: 'Axxord') imports: {'axxord/Axxord-Axon'}!
  3. Object subclass: #Axes
  4. instanceVariableNames: ''
  5. package: 'Axxord'!
  6. !Axes class methodsFor: 'delegated'!
  7. on: anObject at: aCollection consume: aBlock
  8. | value |
  9. value := anObject atAxes: aCollection ifAbsent: [ ^ anObject ].
  10. ^ aBlock value: value
  11. !
  12. on: anObject at: aCollection ifAbsent: aBlock
  13. ^ aCollection inject: anObject into: [ :soFar :segment |
  14. segment asAxisIn: soFar ifAbsent: [ ^ aBlock value ]]
  15. !
  16. on: anObject at: aCollection ifAbsent: aBlock put: value
  17. | penultimate |
  18. penultimate := anObject atAxes: aCollection allButLast ifAbsent: aBlock.
  19. ^ aCollection last asAxisIn: penultimate ifAbsent: aBlock put: value
  20. !
  21. on: anObject at: aCollection transform: aBlock
  22. | value newValue |
  23. value := anObject atAxes: aCollection ifAbsent: [ ^ anObject ].
  24. newValue := aBlock value: value.
  25. value == newValue ifFalse: [ anObject atAxes: aCollection ifAbsent: [ ^ anObject ] put: newValue ].
  26. anObject axxord ifNotNil: [:axon | axon changed: aCollection]
  27. ! !
  28. !Axes class methodsFor: 'factory'!
  29. newInterestThru: anAspect doing: aBlock
  30. ^ PluggableInterest new
  31. accept: [ :aspect | aspect size <= anAspect size
  32. ifTrue: [ aspect = (anAspect copyFrom: 1 to: aspect size) ]
  33. ifFalse: [ anAspect = (aspect copyFrom: 1 to: anAspect size) ] ]
  34. enact: aBlock
  35. !
  36. newInterestUpTo: anAspect doing: aBlock
  37. ^ PluggableInterest new
  38. accept: [ :changedAspect | changedAspect size <= anAspect size and:
  39. [changedAspect = (anAspect copyFrom: 1 to: changedAspect size)] ]
  40. enact: aBlock
  41. ! !
  42. !Axes class methodsFor: 'parsing'!
  43. parse: message
  44. | result stack anArray |
  45. anArray := message tokenize: ' '.
  46. result := #().
  47. stack := { result }.
  48. anArray do: [ :each |
  49. | asNum inner close |
  50. close := 0.
  51. inner := each.
  52. [ inner notEmpty and: [ inner first = '(' ]] whileTrue: [ inner := inner allButFirst. stack add: (stack last add: #()) ].
  53. [ inner notEmpty and: [ inner last = ')' ]] whileTrue: [ inner := inner allButLast. close := close + 1 ].
  54. (inner notEmpty and: [ inner first = '~' ]) ifTrue: [ inner := { inner allButFirst } ].
  55. asNum := inner isString ifTrue: [ (inner ifEmpty: [ 'NaN' ]) asNumber ] ifFalse: [ inner ].
  56. asNum = asNum ifTrue: [ stack last add: asNum ] ifFalse: [
  57. inner ifNotEmpty: [ stack last add: inner ] ].
  58. close timesRepeat: [ stack removeLast ] ].
  59. ^ result
  60. ! !
  61. Object subclass: #Axolator
  62. instanceVariableNames: 'root'
  63. package: 'Axxord'!
  64. !Axolator methodsFor: 'accessing'!
  65. root
  66. ^root
  67. !
  68. root: anObject
  69. root := anObject
  70. ! !
  71. !Axolator methodsFor: 'action'!
  72. atAxes: aCollection ifAbsent: aBlock
  73. ^ root atAxes: aCollection ifAbsent: aBlock
  74. !
  75. atAxes: aCollection ifAbsent: aBlock put: value
  76. ^ root atAxes: aCollection ifAbsent: aBlock put: value
  77. !
  78. axes: aCollection consume: aBlock
  79. super axes: aCollection consume: [:value | aBlock value: value deepCopy]
  80. !
  81. axes: aCollection transform: aBlock
  82. aCollection
  83. ifEmpty: [ self root: (aBlock value: self root) deepCopy. self axxord ifNotNil: [ :axxord | axxord changed: aCollection ] ]
  84. ifNotEmpty: [ super axes: aCollection transform: [:value | (aBlock value: value) deepCopy] ]
  85. ! !
  86. !Axolator class methodsFor: 'instance creation'!
  87. on: anObject
  88. ^self new root: anObject
  89. ! !
  90. !Array methodsFor: '*Axxord'!
  91. asAxisIn: anObject ifAbsent: aBlock
  92. | receiver selector result |
  93. selector := self first.
  94. receiver := anObject yourself. "JSObjectProxy hack"
  95. [ result := receiver perform: selector ]
  96. on: MessageNotUnderstood do: [ :mnu |
  97. ((mnu message selector = selector
  98. and: [ mnu receiver == receiver ])
  99. and: [ mnu message arguments isEmpty ])
  100. ifFalse: [ mnu resignal ].
  101. ^ aBlock value ].
  102. ^ result
  103. !
  104. asAxisIn: anObject ifAbsent: aBlock put: anotherObject
  105. | receiver selector arguments result |
  106. selector := self first asMutator.
  107. receiver := anObject yourself. "JSObjectProxy hack"
  108. arguments := { anotherObject }.
  109. [ result := receiver perform: selector withArguments: arguments ]
  110. on: MessageNotUnderstood do: [ :mnu |
  111. ((mnu message selector = selector
  112. and: [ mnu receiver == receiver ])
  113. and: [ mnu message arguments = arguments ])
  114. ifFalse: [ mnu resignal ].
  115. ^ aBlock value ].
  116. ^ result
  117. ! !
  118. !JSObjectProxy methodsFor: '*Axxord'!
  119. asAxisIn: anObject ifAbsent: aBlock
  120. ^ aBlock value
  121. !
  122. asAxisIn: anObject ifAbsent: aBlock put: anotherObject
  123. ^ aBlock value
  124. !
  125. atAxes: aCollection ifAbsent: aBlock
  126. ^ Axes on: self at: aCollection ifAbsent: aBlock
  127. !
  128. atAxes: aCollection ifAbsent: aBlock put: value
  129. ^ Axes on: self at: aCollection ifAbsent: aBlock put: value
  130. !
  131. axes: aCollection consume: aBlock
  132. ^ Axes on: self at: aCollection consume: aBlock
  133. !
  134. axes: aCollection transform: aBlock
  135. ^ Axes on: self at: aCollection transform: aBlock
  136. !
  137. axxord
  138. <inlineJS: 'return $self["@jsObject"].$axxord$'>
  139. !
  140. axxord: anAxon
  141. <inlineJS: '$self["@jsObject"].$axxord$ = anAxon'>
  142. ! !
  143. !Number methodsFor: '*Axxord'!
  144. asAxisIn: anObject ifAbsent: aBlock
  145. (anObject respondsTo: #at:ifAbsent:)
  146. ifTrue: [ ^ anObject at: self ifAbsent: aBlock ]
  147. ifFalse: aBlock
  148. !
  149. asAxisIn: anObject ifAbsent: aBlock put: anotherObject
  150. (anObject respondsTo: #at:put:)
  151. ifTrue: [ ^ anObject at: self put: anotherObject ]
  152. ifFalse: aBlock
  153. ! !
  154. !Object methodsFor: '*Axxord'!
  155. asAxisIn: anObject ifAbsent: aBlock
  156. ^ aBlock value
  157. !
  158. asAxisIn: anObject ifAbsent: aBlock put: anotherObject
  159. ^ aBlock value
  160. !
  161. atAxes: aCollection ifAbsent: aBlock
  162. ^ Axes on: self at: aCollection ifAbsent: aBlock
  163. !
  164. atAxes: aCollection ifAbsent: aBlock put: value
  165. ^ Axes on: self at: aCollection ifAbsent: aBlock put: value
  166. !
  167. axes: aCollection consume: aBlock
  168. ^ Axes on: self at: aCollection consume: aBlock
  169. !
  170. axes: aCollection transform: aBlock
  171. ^ Axes on: self at: aCollection transform: aBlock
  172. !
  173. axxord
  174. <inlineJS: 'return self.$axxord$'>
  175. !
  176. axxord: anAxon
  177. <inlineJS: 'self.$axxord$ = anAxon'>
  178. ! !
  179. !String methodsFor: '*Axxord'!
  180. asAxisIn: anObject ifAbsent: aBlock
  181. (anObject respondsTo: #at:ifAbsent:)
  182. ifTrue: [ ^ anObject at: self ifAbsent: aBlock ]
  183. ifFalse: aBlock
  184. !
  185. asAxisIn: anObject ifAbsent: aBlock put: anotherObject
  186. (anObject respondsTo: #at:put:)
  187. ifTrue: [ ^ anObject at: self put: anotherObject ]
  188. ifFalse: aBlock
  189. ! !