home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 116.lha / SmallTalk / Sources / BASIC.ST next >
Encoding:
Text File  |  1986-11-20  |  24.1 KB  |  1,187 lines

  1. *
  2. * Little Smalltalk, version 2
  3. * Written by Tim Budd, Oregon State University, July 1987
  4. *
  5. * basic classes common to all images
  6. *
  7. Declare Object
  8. Declare Block Object context argumentCounter argumentLocation bytecodeCounter creatingInterpreter
  9. Declare Boolean Object
  10. Declare   True Boolean
  11. Declare   False Boolean
  12. Declare Class Object name instanceSize methods superClass variables icon
  13. Declare Context Object method methodClass arguments temporaries
  14. Declare Link Object key value nextLink
  15. Declare Magnitude Object
  16. Declare    Char Magnitude value
  17. Declare    Collection Magnitude
  18. Declare       IndexedCollection Collection
  19. Declare          Array IndexedCollection
  20. Declare             ByteArray Array
  21. Declare                String ByteArray
  22. Declare          Dictionary IndexedCollection hashTable
  23. Declare       Interval Collection lower upper step
  24. Declare       List Collection links
  25. Declare          Set List
  26. Declare    Number Magnitude
  27. Declare       Integer Number
  28. Declare       Float Number
  29. Declare Method Object text message bytecodes literals stackSize temporarySize
  30. Declare Random Object
  31. Declare Switch Object const notdone
  32. Declare Smalltalk Object
  33. Declare Symbol Object
  34. Declare UndefinedObject Object
  35. *
  36. Instance Smalltalk smalltalk
  37. Instance True true
  38. Instance False false
  39. *
  40. Class Object
  41.     == aValue
  42.         ^ <21 self aValue>
  43. |
  44.     = aValue
  45.         ^ self == aValue
  46. |
  47.     basicAt: index
  48.         ^ <25 self index>
  49. |
  50.     basicAt: index put: value
  51.         ^ <31 self index value>
  52. |
  53.     basicSize
  54.         ^ <12 self>
  55. |
  56.     class
  57.         ^ <11 self>
  58. |
  59.     display
  60.         ('(Class ', self class, ') ' , self printString ) print
  61. |
  62.     hash
  63.         ^ <13 self>
  64. |
  65.     isMemberOf: aClass
  66.         ^ self class == aClass
  67. |
  68.     isNil
  69.         ^ false
  70. |
  71.     isKindOf: aClass
  72.         self class upSuperclassChain:
  73.             [:x | (x == aClass) ifTrue: [ ^ true ] ].
  74.         ^ false
  75. |
  76.     new
  77.             " default initialization protocol"
  78.         ^ self
  79. |
  80.     notNil
  81.         ^ true
  82. |
  83.     print
  84.         ^ self printString print
  85. |
  86.     printString
  87.         ^ self class printString
  88. ]
  89. Class Array
  90.     < coll
  91.         (coll isKindOf: Array)
  92.             ifTrue: [ self with: coll 
  93.                    do: [:x :y | (x < y) ifTrue: [ ^ true ]].
  94.                   ^ self size < coll size ]
  95.             ifFalse: [ ^ super < coll ]
  96. |
  97.     = coll
  98.         (coll isKindOf: Array)
  99.             ifTrue: [ (self size = coll size)
  100.                     ifFalse: [ ^ false ].
  101.                   self with: coll
  102.                     do: [:x :y | (x = y) 
  103.                         ifFalse: [ ^ false ] ]. 
  104.                  ^ true ]
  105.             ifFalse: [ ^ super = coll ]
  106. |
  107.     at: index put: value
  108.         (self includesKey: index)
  109.             ifTrue: [ self basicAt: index put: value ]
  110.             ifFalse: [ smalltalk error: 
  111.                 'illegal index to at:put: for array' ]
  112. |
  113.     binaryDo: aBlock
  114.         (1 to: self size) do:
  115.             [:i | aBlock value: i value: (self at: i) ]
  116. |
  117.     copyFrom: low to: high    | newArray newlow newhigh |
  118.         newlow <- low max: 1.
  119.         newhigh <- high min: self size.
  120.         newArray <- self class new: (0 max: newhigh - newlow + 1).
  121.         (newlow to: newhigh)
  122.             do: [:i |  newArray at: ((i - newlow) + 1)
  123.                     put: (self at: i) ].
  124.         ^ newArray
  125. |
  126.     do: aBlock
  127.         (1 to: self size) do:
  128.             [:i | aBlock value: (self at: i) ]
  129. |
  130.     exchange: a and: b    | temp |
  131.         temp <- self at: a.
  132.         self at: a put: (self at: b).
  133.         self at: b put: temp
  134. |
  135.     includesKey: index
  136.         ^ index between: 1 and: self size
  137. |
  138.     size
  139.         ^ self basicSize
  140. |
  141.     with: coll do: aBlock
  142.         (1 to: (self size min: coll size))
  143.             do: [:i | aBlock value: (self at: i) 
  144.                     value: (coll at: i) ]
  145. ]
  146. Class Block
  147.     checkArgumentCount: count
  148.         ^ (argumentCounter = count)
  149.             ifTrue: [ true ]
  150.             ifFalse: [ smalltalk error:
  151.                 'wrong number of arguments passed to block'.
  152.                 false ]
  153. |
  154.     value
  155.         ^ (self checkArgumentCount: 0)
  156.             ifTrue: [ context executeFrom: bytecodeCounter 
  157.                     creator: creatingInterpreter ]
  158. |
  159.     value: x
  160.         ^ (self checkArgumentCount:  1)
  161.             ifTrue: [ context temporaries at: argumentLocation 
  162.                     put: x.
  163.                   context executeFrom: bytecodeCounter 
  164.                     creator: creatingInterpreter ]
  165. |
  166.     value: x value: y    | temps |
  167.         ^ (self checkArgumentCount: 2)
  168.             ifTrue: [ temps <- context temporaries.
  169.                   temps at: argumentLocation put: x.
  170.                   temps at: argumentLocation + 1 put: y.
  171.                   context executeFrom: bytecodeCounter 
  172.                       creator: creatingInterpreter ]
  173. |
  174.     value: x value: y value: z    | temps |
  175.         ^ (self checkArgumentCount:  3)
  176.             ifTrue: [ temps <- context temporaries.
  177.                   temps at: argumentLocation put: x.
  178.                   temps at: argumentLocation + 1 put: y.
  179.                   temps at: argumentLocation + 2 put: z.
  180.                   context executeFrom: bytecodeCounter 
  181.                     creator: creatingInterpreter ]
  182. |
  183.     whileTrue: aBlock
  184.         ( self value ) ifTrue:
  185.             [ aBlock value. 
  186.                 self whileTrue: aBlock ]
  187. |
  188.     whileTrue
  189.         self whileTrue: []
  190. ]
  191. Class Boolean
  192.     ifTrue: trueBlock
  193.         ^ self ifTrue: trueBlock ifFalse: []
  194. |
  195.     ifFalse: falseBlock
  196.         ^ self ifTrue: [] ifFalse: falseBlock
  197. |
  198.     ifFalse: falseBlock ifTrue: trueBlock
  199.         ^ self ifTrue: trueBlock
  200.             ifFalse: falseBlock
  201. |
  202.     and: aBlock
  203.         ^ self ifTrue: aBlock ifFalse: [ false ]
  204. |
  205.     or: aBlock
  206.         ^ self ifTrue: [ true ] ifFalse: aBlock
  207. ]
  208. Class ByteArray
  209.     asString
  210.         <22 self String>
  211. |
  212.     basicAt: index put: value
  213.         ^ <32 self index value >
  214. |
  215.     basicAt: index
  216.         ^ <26 self index>
  217. |
  218.     size: value
  219.         ^ <22 <59 value> ByteArray>
  220. |
  221.     size
  222.         ^ self basicSize * 2
  223. ]
  224. Class Char
  225.     < aValue
  226.         ^ (aValue isMemberOf: Char)
  227.             ifTrue: [ value < aValue asInteger ]
  228.             ifFalse: [ smalltalk error: 'char compared to nonchar']
  229. |
  230.     == aValue
  231.         ^ (aValue isMemberOf: Char)
  232.             ifTrue: [ value = aValue asInteger ]
  233.             ifFalse: [ false ]
  234. |
  235.     = aValue
  236.         ^ self == aValue
  237. |
  238.     asInteger
  239.         ^ value
  240. |
  241.     asString
  242.         ^ ' ' copy; at: 1 put: self
  243. |
  244.     digitValue
  245.         self isDigit ifTrue: [ ^ value - $0 asInteger ].
  246.         self isUppercase ifTrue: [ ^ value - $A asInteger + 10 ].
  247.         ^ smalltalk error: 'illegal conversion, char to digit'
  248. |
  249.     isAlphabetic
  250.         ^ (self isLowercase) or: [ self isUppercase ]
  251. |
  252.     isAlphaNumeric
  253.         ^ (self isAlphabetic) or: [ self isDigit ]
  254. |
  255.     isBlank
  256.         ^ value = $   " blank char "
  257. |
  258.     isDigit
  259.         ^ value between: $0 asInteger and: $9 asInteger
  260. |
  261.     isLowercase
  262.         ^ value between: $a asInteger and: $z asInteger
  263. |
  264.     isUppercase
  265.         ^ value between: $A asInteger and: $Z asInteger
  266. |
  267.     value: aValue        " private - used for initialization "
  268.         value <- aValue
  269. |
  270.     printString
  271.         ^ '$', self asString
  272. ]
  273. Class Class
  274.     new        | newObject |
  275.         newObject <- self new: instanceSize.
  276.         ^ (self == Class)
  277.             ifTrue: [ newObject initialize ]
  278.             ifFalse: [ newObject new ]
  279. |
  280.     new: size    " hack out block the right size and class "
  281.         ^ < 22 < 58 size > self >
  282. |
  283.     initialize
  284.         superClass <- Object.
  285.         instanceSize <- 0.
  286.         methods <- Dictionary new
  287. |
  288.     name
  289.         ^ name
  290. |
  291.     name: aString
  292.         name <- aString
  293. |
  294.     methods
  295.         ^ methods
  296. |
  297.     instanceSize
  298.         ^ instanceSize
  299. |
  300.     printString
  301.         ^ name asString
  302. |
  303.     respondsTo    | theSet |
  304.         theSet <- Set new.
  305.         self upSuperclassChain: 
  306.             [:x | theSet addAll: x methods keys ].
  307.         ^ theSet
  308. |
  309.     respondsTo: message
  310.         ^ methods includesKey: message
  311. |
  312.     subClasses
  313.         ^ globalNames inject: List new
  314.             into: [:x :y | ((y class = Class) and:
  315.                     [ y superClass = self])
  316.                         ifTrue: [ x add: y]. x ]
  317. |
  318.     superClass
  319.         ^ superClass
  320. |
  321.     superClass: aClass
  322.         superClass <- aClass
  323. |
  324.     upSuperclassChain: aBlock
  325.         aBlock value: self.
  326.         (superClass notNil)
  327.             ifTrue: [ superClass upSuperclassChain: aBlock ]
  328. |
  329.     variables
  330.         ^ variables
  331. |
  332.     variables: nameArray
  333.         variables <- nameArray.
  334.         instanceSize <- superClass instanceSize + nameArray size
  335. ]
  336. Class Collection
  337.     < coll
  338.         self do: [:x | (coll includes: x) ifFalse: [ ^ false ]].
  339.         ^ true
  340. |
  341.     = coll
  342.         self do: [:x | (self occurrencesOf: x) = 
  343.                 (coll occurrencesOf: x) ifFalse: [ ^ false ] ].
  344.         ^ true
  345. |
  346.     asArray        | newArray i |
  347.         newArray <- Array new: self size.
  348.         i <- 0.
  349.         self do: [:x | i <- i + 1. newArray at: i put: x].
  350.         ^ newArray
  351. |
  352.     asByteArray    | newArray i |
  353.         newArray <- ByteArray new size: self size.
  354.         i <- 0.
  355.         self do: [:x | i <- i + 1. newArray at: i put: x].
  356.         ^ newArray
  357. |
  358.     asSet
  359.         ^ Set new addAll: self
  360. |
  361.     asString
  362.         ^ self asByteArray asString
  363. |
  364.     display
  365.         self do: [:x | x print ]
  366. |
  367.     includes: value
  368.         self do: [:x | (x = value) ifTrue: [ ^ true ] ].
  369.         ^ false
  370. |
  371.     inject: thisValue into: binaryBlock     | last |
  372.         last <- thisValue.
  373.         self do: [:x | last <- binaryBlock value: last value: x].
  374.         ^ last
  375. |
  376.     isEmpty 
  377.         ^ self size == 0
  378. |
  379.     occurrencesOf: anObject
  380.         ^ self inject: 0
  381.                into: [:x :y | (y = anObject) 
  382.                      ifTrue: [x + 1]
  383.                      ifFalse: [x] ]
  384. |
  385.     printString
  386.         ^ ( self inject: self class printString , ' ('
  387.              into: [:x :y | x , ' ' , y printString]), ' )'
  388. |
  389.     size
  390.         ^ self inject: 0 into: [:x :y | x + 1]
  391. |
  392.     sort: aBlock
  393.         ^ self inject: List new
  394.             into: [:x :y | x add: y ordered: aBlock. x]
  395. |
  396.     sort
  397.         ^ self sort: [:x :y | x < y ]
  398. ]
  399. Class Context
  400.     executeFrom: value creator: interp
  401.         ^ <38 self value interp>
  402. |
  403.     method: value
  404.         method <- value
  405. |
  406.     arguments: value
  407.         arguments <- value
  408. |
  409.     temporaries
  410.         ^ temporaries
  411. |
  412.     temporaries: value
  413.         temporaries <- value
  414. ]
  415. Class Dictionary
  416.     new
  417.         hashTable <- Array new: 39
  418. |
  419.     hash: aKey
  420.         ^ 3 * ((aKey hash) rem: ((hashTable size) quo: 3))
  421. |
  422.     at: aKey ifAbsent: exceptionBlock    | hashPosition  link |
  423.  
  424.         hashPosition <- self hash: aKey.
  425.         ((hashTable at: hashPosition + 1) == aKey)
  426.             ifTrue: [ ^ hashTable at: hashPosition + 2].
  427.         link <- hashTable at: hashPosition + 3.
  428.         ^ (link notNil)
  429.             ifTrue: [ link at: aKey ifAbsent: exceptionBlock ]
  430.             ifFalse: exceptionBlock
  431. |
  432.     at: aKey put: aValue            | hashPosition link |
  433.  
  434.         hashPosition <- self hash: aKey.
  435.         ((hashTable at: hashPosition + 1) isNil)
  436.            ifTrue: [ hashTable at: hashPosition + 1 put: aKey ].
  437.         ((hashTable at: hashPosition + 1) == aKey)
  438.            ifTrue: [ hashTable at: hashPosition + 2 put: aValue ]
  439.            ifFalse: [ link <- hashTable at: hashPosition + 3.
  440.             (link notNil)
  441.                 ifTrue: [ link at: aKey put: aValue ]
  442.                 ifFalse: [ hashTable at: hashPosition + 3
  443.                     put: (Link new; key: aKey; value: aValue)]]
  444. |
  445.     binaryDo: aBlock
  446.         (1 to: hashTable size by: 3) do:
  447.             [:i | (hashTable at: i) notNil
  448.                 ifTrue: [ aBlock value: (hashTable at: i)
  449.                         value: (hashTable at: i+1) ].
  450.                   (hashTable at: i+2) notNil
  451.                 ifTrue: [ (hashTable at: i+2) 
  452.                         binaryDo: aBlock ] ]
  453. |
  454.     display
  455.         self binaryDo: [:x :y | (x printString , ' -> ', 
  456.                     y printString ) print ]
  457. |
  458.     includesKey: aKey
  459.         " look up, but throw away result "
  460.         self at: aKey ifAbsent: [ ^ false ].
  461.         ^ true
  462. |
  463.     removeKey: aKey
  464.         ^ self removeKey: aKey
  465.             ifAbsent: [ smalltalk error: 'remove key not found']
  466. |
  467.     removeKey: aKey ifAbsent: exceptionBlock
  468.         ^ (self includesKey: aKey)
  469.             ifTrue: [ self basicRemoveKey: aKey ]
  470.             ifFalse: exceptionBlock
  471. |
  472.     basicRemoveKey: aKey        | hashPosition link |
  473.         hashPosition <- self hash: aKey.
  474.         ((hashTable at: hashPosition + 1) == aKey)
  475.             ifTrue: [ hashTable at: hashPosition + 1 put: nil.
  476.                   hashTable at: hashPosition + 2 put: nil]
  477.             ifFalse: [ link <- hashTable at: hashPosition + 3.
  478.                 (link notNil)
  479.                     ifTrue: [ hashTable at: hashPosition + 3
  480.                             put: (link removeKey: aKey) ]]
  481. ]
  482. Class False
  483.     ifTrue: trueBlock ifFalse: falseBlock
  484.         ^ falseBlock value
  485. |
  486.     not
  487.         ^ true
  488. ]
  489. Class Float
  490.     + value
  491.         ^ (value isMemberOf: Float)
  492.             ifTrue: [ <110 self value> ]
  493.             ifFalse: [ super + value ]
  494. |
  495.     - value
  496.         ^ (value isMemberOf: Float)
  497.             ifTrue: [ <111 self value> ]
  498.             ifFalse: [ super - value ]
  499. |
  500.     < value
  501.         ^ (value isMemberOf: Float)
  502.             ifTrue: [ <112 self value> ]
  503.             ifFalse: [ super < value ]
  504. |
  505.     = value
  506.         ^ (value isMemberOf: Float)
  507.             ifTrue: [ <116 self value> ]
  508.             ifFalse: [ super = value ]
  509. |
  510.     * value
  511.         ^ (value isMemberOf: Float)
  512.             ifTrue: [ <118 self value> ]
  513.             ifFalse: [ super * value ]
  514. |
  515.     / value    
  516.         ^ (value isMemberOf: Float)
  517.             ifTrue: [ (value = 0.0)
  518.                     ifTrue: [ smalltalk error:
  519.                         'float division by zero' ]
  520.                     ifFalse: [ <119 self value> ]]
  521.             ifFalse: [ super / value ]
  522. |
  523.     ceiling        | i |
  524.         i <- self integerPart.
  525.         ^ ((self positive) and: [ self ~= i ])
  526.             ifTrue: [ i + 1 ]
  527.             ifFalse: [ i ]
  528. |
  529.     coerce: value
  530.         ^ value asFloat
  531. |
  532.     exp
  533.         ^ <103 self>
  534. |
  535.     floor        | i |
  536.         i <- self integerPart.
  537.         ^ ((self negative) and: [ self ~= i ])
  538.             ifTrue: [ i - 1 ]
  539.             ifFalse: [ i ]
  540. |
  541.     fractionalPart
  542.         ^ self - self integerPart
  543. |
  544.     generality
  545.         ^ 7
  546. |
  547.     integerPart
  548.         ^ <106 self>
  549. |
  550.     ln
  551.         ^ <102 self>
  552. |
  553.     printString
  554.         ^ <101 self>
  555. |
  556.     rounded
  557.         ^ (self + 0.5 ) floor
  558. |
  559.     sqrt
  560.         ^ (self negative)
  561.             ifTrue: [ smalltalk error: 'sqrt of negative']
  562.             ifFalse: [ <104 self> ]
  563. |
  564.     truncated
  565.         ^ (self negative) 
  566.             ifTrue: [ self ceiling ]
  567.             ifFalse: [ self floor ]
  568. ]
  569. Class IndexedCollection
  570.     addAll: aCollection
  571.         aCollection binaryDo: [:i :x | self at: i put: x ]
  572. |
  573.     asArray    
  574.         ^ Array new: self size ; addAll: self
  575. |
  576.     asDictionary
  577.         ^ Dictionary new ; addAll: self
  578. |
  579.     at: aKey
  580.         ^ self at: aKey 
  581.             ifAbsent: [ smalltalk error: 'index to at: illegal' ]
  582. |
  583.     at: index ifAbsent: exceptionBlock
  584.          ^ (self includesKey: index)
  585.             ifTrue: [ self basicAt: index ]
  586.             ifFalse: exceptionBlock
  587. |
  588.     binaryInject: thisValue into: aBlock     | last |
  589.         last <- thisValue.
  590.         self binaryDo: [:i :x | last <- aBlock value: last 
  591.                         value: i value: x].
  592.         ^ last
  593. |
  594.     collect: aBlock
  595.         ^ self binaryInject: Dictionary new
  596.             into: [:s :i :x | s at: i put: (aBlock value: x).  s]
  597. |
  598.     do: aBlock
  599.         self binaryDo: [:i :x | aBlock value: x ]
  600. |
  601.     keys
  602.         ^ self binaryInject: Set new 
  603.             into: [:s :i :x | s add: i ]
  604. |
  605.     indexOf: aBlock
  606.         ^ self indexOf: aBlock
  607.             ifAbsent: [ smalltalk error: 'index not found']
  608. |
  609.     indexOf: aBlock ifAbsent: exceptionBlock
  610.         self binaryDo: [:i :x | (aBlock value: x)
  611.                 ifTrue: [ ^ i ] ].
  612.         ^ exceptionBlock value
  613. |
  614.     select: aBlock
  615.         ^ self binaryInject: Dictionary new
  616.             into: [:s :i :x | (aBlock value: x)
  617.                     ifTrue: [ s at: i put: x ]. s ]
  618. |
  619.     values
  620.         ^ self binaryInject: List new
  621.             into: [:s :i :x | s add: x ]
  622. ]
  623. Class Integer
  624.     + value        | r |
  625.         ^ (value isMemberOf: Integer)
  626.             ifTrue: [ r <- <60 self value>.
  627.                   r notNil ifTrue: [ r ]
  628.                 ifFalse: [ self asFloat + value asFloat ]]
  629.             ifFalse: [ super + value ]
  630. |
  631.     - value        | r |
  632.         ^ (value isMemberOf: Integer)
  633.             ifTrue: [ r <- <61 self value>.
  634.                 r notNil ifTrue: [ r ]
  635.                 ifFalse: [ self asFloat - value asFloat ]]
  636.             ifFalse: [ super - value ]
  637. |
  638.     < value
  639.         ^ (value isMemberOf: Integer)
  640.             ifTrue: [ <62 self value> ]
  641.             ifFalse: [ super < value ]
  642. |
  643.     = value
  644.         ^ (value isMemberOf: Integer)
  645.             ifTrue: [ <66 self value> ]
  646.             ifFalse: [ super = value ]
  647. |
  648.     * value        | r |
  649.         ^ (value isMemberOf: Integer)
  650.             ifTrue: [ r <- <68 self value>.
  651.                   r notNil ifTrue: [ r ]
  652.                   ifFalse: [ self asFloat * value asFloat ]]
  653.             ifFalse: [ super * value ]
  654. |
  655.     / value        " do it as float "
  656.         ^ self asFloat / value
  657. |
  658.     // value    | i |
  659.         i <- self quo: value.
  660.         ( (i < 0) and: [ (self rem: value) ~= 0] )
  661.             ifTrue: [ i <- i - 1 ].
  662.         ^ i
  663. |
  664.     \\ value
  665.         ^ self * self sign rem: value
  666. |
  667.     allMask: value
  668.         ^ value = (self bitAnd: value)
  669. |
  670.     anyMask: value
  671.         ^ 0 ~= (self bitAnd: value)
  672. |
  673.     asCharacter
  674.         ^ Char new; value: self
  675. |
  676.     asDigit
  677.         (self >= 0)
  678.             ifTrue: [ (self <= 9) ifTrue: 
  679.                     [ ^ (self + $0 asInteger) asCharacter ].
  680.                   (self <= 36) ifTrue:
  681.                     [ ^ (self + $A asInteger - 10) asCharacter ] ].
  682.         ^ smalltalk error: 'illegal conversion, integer to digit'
  683. |
  684.     asFloat
  685.         ^ <51 self>
  686. |
  687.     asString
  688.         ^ self radix: 10
  689. |
  690.     bitAnd: value
  691.         ^ (value isMemberOf: Integer)
  692.             ifTrue: [ <71 self value > ]
  693.             ifFalse: [ smalltalk error: 
  694.                 'argument to bit operation must be integer']
  695. |
  696.     bitAt: value
  697.         ^ (self bitShift: 1 - value) bitAnd: 1
  698. |
  699.     bitInvert
  700.         ^ self bitXor: -1
  701. |
  702.     bitOr: value
  703.         ^ (self bitXor: value) bitXor: (self bitAnd: value)
  704. |
  705.     bitXor: value
  706.         ^ (value isMemberOf: Integer)
  707.             ifTrue: [ <72 self value > ]
  708.             ifFalse: [ smalltalk error: 
  709.                 'argument to bit operation must be integer']
  710. |
  711.     bitShift: value
  712.         ^ (value isMemberOf: Integer)
  713.             ifTrue: [ <79 self value > ]
  714.             ifFalse: [ smalltalk error: 
  715.                 'argument to bit operation must be integer']
  716. |
  717.     even
  718.         ^ (self rem: 2) = 0
  719. |
  720.     factorial
  721.         ^ (2 to: self) inject: 1 into: [:x :y | x * y ]
  722. |
  723.     gcd: value
  724.         (value = 0) ifTrue: [ ^ self ].
  725.         (self negative) ifTrue: [ ^ self negated gcd: value ].
  726.         (value negative) ifTrue: [ ^ self gcd: value negated ].
  727.         (value > self) ifTrue: [ ^ value gcd: self ].
  728.         ^ value gcd: (self rem: value)
  729. |
  730.     generality
  731.         ^ 2
  732. |
  733.     lcm: value
  734.         ^ (self quo: (self gcd: value)) * value
  735. |
  736.     odd
  737.         ^ (self rem: 2) ~= 0
  738. |
  739.     quo: value    | r |
  740.         ^ (value isMemberOf: Integer)
  741.             ifTrue: [ r <- <69 self value>.
  742.                 (r isNil)
  743.                     ifTrue: [ smalltalk error:
  744.                         'quo: or rem: with argument 0']
  745.                     ifFalse: [ r ]]
  746.             ifFalse: [ smalltalk error: 
  747.                 'argument to quo: or rem: must be integer']
  748. |
  749.     radix: base     | text |
  750.         text <- (self \\ base) asDigit asString.
  751.         ^ (self abs < base)
  752.             ifTrue: [ (self negative)
  753.                     ifTrue: [ '-' , text ]
  754.                     ifFalse: [ text ]]
  755.             ifFalse: [ ((self quo: base) radix: base), text ]
  756. |
  757.     rem: value
  758.         ^ self - ((self quo: value) * value)
  759. |
  760.     printString
  761.         ^ self asString
  762. |
  763.     timesRepeat: aBlock    | i |
  764.         " use while, which is optimized, not to:, which is not"
  765.         i <- 0.
  766.         [ i < self ] whileTrue:
  767.             [ aBlock value. i <- i + 1]
  768. ]
  769. Class Interval
  770.     do: aBlock        | current |
  771.         current <- lower.
  772.         (step > 0) 
  773.             ifTrue: [ [ current <= upper ] whileTrue:
  774.                     [ aBlock value: current.
  775.                       current <- current + step ] ]
  776.             ifFalse: [ [ current >= upper ] whileTrue:
  777.                     [ aBlock value: current.
  778.                     current <- current + step ] ]
  779. |
  780.     lower: aValue
  781.         lower <- aValue
  782. |
  783.     upper: aValue
  784.         upper <- aValue
  785. |
  786.     step: aValue
  787.         step <- aValue
  788. ]
  789. Class Link
  790.     add: newValue whenFalse: aBlock
  791.         (aBlock value: value value: newValue)
  792.             ifTrue: [ (nextLink notNil)
  793.                 ifTrue: [ nextLink <- nextLink add: newValue 
  794.                     whenFalse: aBlock ]
  795.             ifFalse: [ nextLink <- Link new; value: newValue] ]
  796.             ifFalse: [ ^ Link new; value: newValue; link: self ]
  797. |
  798.     at: aKey ifAbsent: exceptionBlock
  799.         (aKey == key)
  800.             ifTrue: [ ^value ]
  801.             ifFalse: [ ^ (nextLink notNil)
  802.                     ifTrue: [ nextLink at: aKey
  803.                             ifAbsent: exceptionBlock ]
  804.                     ifFalse: exceptionBlock ]
  805. |
  806.     at: aKey put: aValue
  807.         (aKey == key)
  808.             ifTrue: [ value <- aValue ]
  809.             ifFalse: [ (nextLink notNil)
  810.                 ifTrue: [ nextLink at: aKey put: aValue]
  811.                 ifFalse: [ nextLink <- Link new;
  812.                         key: aKey; value: aValue] ]
  813. |
  814.     binaryDo: aBlock
  815.         aBlock value: key value: value.
  816.         (nextLink notNil)
  817.             ifTrue: [ nextLink binaryDo: aBlock ]
  818. |
  819.     key: aKey
  820.         key <- aKey
  821. |
  822.     includesKey: aKey
  823.         (key == aKey)
  824.             ifTrue: [ ^ true ].
  825.         (nextLink notNil)
  826.             ifTrue: [ ^ nextLink includesKey: aKey ]
  827.             ifFalse: [ ^ false ]
  828. |
  829.     link: aLink
  830.         nextLink <- aLink
  831. |
  832.     removeKey: aKey
  833.         (aKey == key)
  834.             ifTrue: [ ^ nextLink ]
  835.             ifFalse: [ (nextLink notNil)
  836.                 ifTrue: [ nextLink <- nextLink removeKey: aKey]]
  837. |
  838.     removeValue: aValue
  839.         (aValue == value)
  840.             ifTrue: [ ^ nextLink ]
  841.             ifFalse: [ (nextLink notNil)
  842.                 ifTrue: [ nextLink <- nextLink removeValue: aValue]]
  843. |
  844.     size
  845.         (nextLink notNil)
  846.             ifTrue: [ ^ 1 + nextLink size]
  847.             ifFalse: [ ^ 1 ]
  848. |
  849.     value: aValue
  850.         value <- aValue
  851. |
  852.     value
  853.         ^ value
  854. ]
  855. Class List
  856.     add: aValue
  857.         ^ self addFirst: aValue
  858. |
  859.     add: aValue ordered: aBlock
  860.         (links isNil)
  861.             ifTrue: [ self addFirst: aValue]
  862.             ifFalse: [ links <- links add: aValue 
  863.                     whenFalse: aBlock ]
  864. |
  865.     addAll: aValue
  866.         aValue do: [:x | self add: x ]
  867. |
  868.     addFirst: aValue
  869.         links <- Link new; value: aValue; link: links
  870. |
  871.     addLast: aValue
  872.         (links isNil)
  873.             ifTrue: [ self addFirst: aValue ]
  874.             ifFalse: [ links add: aValue whenFalse: [ :x :y | true ] ]
  875. |
  876.     collect: aBlock
  877.         ^ self inject: self class new
  878.                into: [:x :y | x add: (aBlock value: y). x ]
  879. |
  880.     reject: aBlock          
  881.         ^ self select: [:x | (aBlock value: x) not ]
  882. |
  883.     select: aBlock          
  884.         ^ self inject: self class new
  885.                into: [:x :y | (aBlock value: y) 
  886.                     ifTrue: [x add: y]. x]
  887. |
  888.     do: aBlock
  889.         (links notNil)
  890.             ifTrue: [ links binaryDo: [:x :y | aBlock value: y]]
  891. |
  892.     first
  893.         ^ (links notNil)
  894.             ifTrue: links
  895.             ifFalse: [ smalltalk error: 'first on empty list']
  896. |
  897.     removeFirst
  898.         self remove: self first
  899. |
  900.     remove: value
  901.         (links notNil)
  902.             ifTrue: [ links <- links removeValue: value ]
  903. |
  904.     size
  905.         (links isNil)
  906.             ifTrue: [ ^ 0 ]
  907.             ifFalse: [ ^ links size ]
  908. ]
  909. Class Magnitude
  910.     <= value
  911.         ^ (self < value) or: [ self = value ]
  912. |
  913.     < value
  914.         ^ (value > self)
  915. |
  916.     >= value
  917.         ^ (self > value) or: [ self = value ]
  918. |
  919.     > value
  920.         ^ (value < self)
  921. |
  922.     = value
  923.         ^ (self == value)
  924. |
  925.     ~= value
  926.         ^ (self = value) not
  927. |
  928.     between: low and: high
  929.         ^ (low <= self) and: [ self <= high ]
  930. |
  931.     max: value
  932.         ^ (self < value)
  933.             ifTrue: [ value ]
  934.             ifFalse: [ self ]
  935. |
  936.     min: value
  937.         ^ (self < value)
  938.             ifTrue: [ self ]
  939.             ifFalse: [ value ]
  940. ]
  941. Class Method
  942.     compileWithClass: aClass
  943.         ^ <39 aClass text self>
  944. |
  945.     name
  946.         ^ message
  947. |
  948.     message: aSymbol
  949.         message <- aSymbol
  950. |
  951.     printString
  952.         ^ message asString
  953. |
  954.     text
  955.         ^ text
  956. |
  957.     text: aString
  958.         text <- aString
  959. |
  960.     display
  961.         ('Method ', message) print.
  962.         'text' print.
  963.         text print.
  964.         'literals' print.
  965.         literals print.
  966.         'bytecodes' print.
  967.         bytecodes do: [:x |
  968.             (x printString, ' ', (x quo: 16), ' ', (x rem: 16))
  969.                 print ]
  970. ]
  971. Class Number
  972.     maxgen: value
  973.         ^ (self generality > value generality)
  974.             ifTrue: [ self ]
  975.             ifFalse: [ value coerce: self ]
  976. |
  977.     + value
  978.         ^ (self maxgen: value) + (value maxgen: self)
  979. |
  980.     - value
  981.         ^ (self maxgen: value) - (value maxgen: self)
  982. |
  983.     < value
  984.         ^ (self maxgen: value) < (value maxgen: self)
  985. |
  986.     = value
  987.         ^ (self maxgen: value) = (value maxgen: self)
  988. |
  989.     * value
  990.         ^ (self maxgen: value) * (value maxgen: self)
  991. |
  992.     / value
  993.         ^ (self maxgen: value) / (value maxgen: self)
  994. |
  995.     abs
  996.         ^ (self < 0)
  997.             ifTrue: [ 0 - self ]
  998.             ifFalse: [ self ]
  999. |
  1000.     exp
  1001.         ^ self asFloat exp
  1002. |
  1003.     ln
  1004.         ^ self asFloat ln
  1005. |
  1006.     log: value
  1007.         ^ self ln / value ln
  1008. |
  1009.     negated
  1010.         ^ 0 - self
  1011. |
  1012.     negative
  1013.         ^ self < 0
  1014. |
  1015.     positive
  1016.         ^ self >= 0
  1017. |
  1018.     raisedTo: value
  1019.         ^ ( value * self ln ) exp
  1020. |
  1021.     reciprocal
  1022.         ^ 1.00 / self
  1023. |
  1024.     roundTo: value
  1025.         ^ (self / value ) rounded * value
  1026. |
  1027.     sign
  1028.         ^ self negative ifTrue: [ -1 ]
  1029.             ifFalse: [ self strictlyPositive 
  1030.                     ifTrue: [ 1 ] ifFalse: [ 0 ] ]
  1031. |
  1032.     sqrt
  1033.         ^ self asFloat sqrt
  1034. |
  1035.     squared
  1036.         ^ self * self
  1037. |
  1038.     strictlyPositive
  1039.         ^ self > 0
  1040. |
  1041.     to: value
  1042.         ^ Interval new; lower: self; upper: value; step: 1
  1043. |
  1044.     to: value by: step
  1045.         ^ Interval new; lower: self; upper: value; step: step
  1046. |
  1047.     trucateTo: value
  1048.         ^ (self / value) trucated * value
  1049. ]
  1050. Class Random
  1051.     between: low and: high
  1052.         ^ (self next * (high - low)) + low
  1053. |
  1054.     next
  1055.         ^ (<3> rem: 1000) / 1000
  1056. |
  1057.     next: value    | list |
  1058.         list <- List new.
  1059.         value timesRepeat: [ list add: self next ].
  1060.         ^ list
  1061. |
  1062.     randInteger: value
  1063.         ^ 1 + (<3> rem: value)
  1064. |
  1065.     set: value
  1066.         <55 value>
  1067. ]
  1068. Class Set
  1069.     add: value
  1070.         (self includes: value)
  1071.             ifFalse: [ self addFirst: value ]
  1072. ]
  1073. Class String
  1074.     , value
  1075.         ^ (value isMemberOf: String)
  1076.             ifTrue: [ (self size + value size) > 512
  1077.                     ifTrue: [ 'string too large' print.  self ]
  1078.                     ifFalse: [ <24 self value> ] ]
  1079.             ifFalse: [ self , value printString ]
  1080. |
  1081.     = value
  1082.         (value isKindOf: String)
  1083.             ifTrue: [ ^ super = value ]
  1084.             ifFalse: [ ^ false ]
  1085. |
  1086.     < value
  1087.         (value isKindOf: String)
  1088.             ifTrue: [ ^ super < value ]
  1089.             ifFalse: [ ^ false ]
  1090. |
  1091.     asInteger
  1092.         ^ self inject: 0 into: [:x :y | x * 10 + y digitValue ]
  1093. |
  1094.     basicAt: index
  1095.         ^  (super basicAt: index) asCharacter
  1096. |
  1097.     basicAt: index put: aValue
  1098.         (aValue isMemberOf: Char)
  1099.             ifTrue: [ super basicAt: index put: aValue asInteger ]
  1100.             ifFalse: [ smalltalk error:
  1101.                 'cannot put non Char into string' ]
  1102. |
  1103.     asSymbol
  1104.         ^ <83 self>
  1105. |
  1106.     copy
  1107.         " catenation makes copy automatically "
  1108.         ^ '',self
  1109. |
  1110.     copyFrom: position1 to: position2
  1111.         ^ <33 self position1 position2>
  1112. |
  1113.     printString
  1114.         ^ '''' , self, ''''
  1115. |
  1116.     size
  1117.         ^ <81 self>
  1118. |
  1119.     words: aBlock    | text index list |
  1120.         list <- List new.
  1121.         text <- self.
  1122.         [ text <- text copyFrom: 
  1123.             (text indexOf: aBlock ifAbsent: [ text size + 1])
  1124.                 to: text size.
  1125.           text size > 0 ] whileTrue:
  1126.             [ index <- text 
  1127.                 indexOf: [:x | (aBlock value: x) not ]
  1128.                 ifAbsent: [ text size + 1].
  1129.               list addLast: (text copyFrom: 1 to: index - 1).
  1130.               text <- text copyFrom: index to: text size ].
  1131.         ^ list asArray
  1132. ]
  1133. Class Smalltalk
  1134.     class: aClass doesNotRespond: aMessage
  1135.         ^ self error: aClass printString ,
  1136.             ' does not respond to ' , aMessage
  1137. |
  1138.     cantFindGlobal: name
  1139.         ^ self error: 'cannot find global symbol ' , name
  1140. |
  1141.     flushMessageCache
  1142.         <2>
  1143. ]
  1144. Class Switch
  1145.     key: value
  1146.         const <- value.
  1147.         notdone <- true.
  1148. |
  1149.     ifMatch: key do: block
  1150.         (notdone and: [ const = key ])
  1151.             ifTrue: [ notdone <- false. block value ]
  1152. |
  1153.     else: block
  1154.         notdone ifTrue: [ notdone <- false. block value ]
  1155. ]
  1156. Class Symbol
  1157.     asString
  1158.         " catenation makes copy automatically "
  1159.         ^ <24 self ''>
  1160. |
  1161.     printString
  1162.         ^ '#' , self asString
  1163. |
  1164.     respondsTo
  1165.         ^ globalNames inject: Set new
  1166.             into: [:x :y | ((y class = Class) and:
  1167.                     [ y respondsTo: self])
  1168.                         ifTrue: [ x add: y]. x]
  1169. ]
  1170. Class True
  1171.     ifTrue: trueBlock ifFalse: falseBlock
  1172.         ^ trueBlock value
  1173. |
  1174.     not
  1175.         ^ false
  1176. ]
  1177. Class UndefinedObject
  1178.     isNil
  1179.         ^ true
  1180. |
  1181.     notNil
  1182.         ^ false
  1183. |
  1184.     printString
  1185.         ^ 'nil'
  1186. ]
  1187.