home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / little-st / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-10-03  |  29.4 KB

  1. Subject:  v11i088:  Little Smalltal    k interpreter, Part03/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: Tim Budd <budd@cs.orst.edu>
  7. Posting-number: Volume 11, Issue 88
  8. Archive-name: little-st/part03
  9.  
  10. The following is version two of the Little Smalltalk system, distributed
  11. in three parts.  Little Smalltalk is an interpreter for the language
  12. Smalltalk.
  13.  
  14. Questions or comments should be sent to Tim Budd,
  15.     budd@oregon-state.csnet
  16.     budd@cs.orst.edu    (128.193.32.1)
  17.     {tektronix, hp-pcd}!orstcs!budd
  18.  
  19. -----------cut here--------------------------------------------
  20. : To unbundle, sh this file
  21. echo unbundling basicclasses 1>&2
  22. cat >basicclasses <<'End'
  23. *
  24. * Little Smalltalk, version 2
  25. * Written by Tim Budd, Oregon State University, July 1987
  26. *
  27. * basic classes common to all images
  28. *
  29. Declare Object
  30. Declare Block Object context argumentCounter argumentLocation bytecodeCounter creatingInterpreter
  31. Declare Boolean Object
  32. Declare   True Boolean
  33. Declare   False Boolean
  34. Declare Class Object name size methods superClass variables icon
  35. Declare Context Object method methodClass arguments temporaries
  36. Declare Link Object key value nextLink
  37. Declare Magnitude Object
  38. Declare    Char Magnitude value
  39. Declare    Collection Magnitude
  40. Declare       IndexedCollection Collection
  41. Declare          Array IndexedCollection
  42. Declare             ByteArray Array
  43. Declare                String ByteArray
  44. Declare          Dictionary IndexedCollection
  45. Declare       Interval Collection lower upper step
  46. Declare       List Collection links
  47. Declare          Set List
  48. Declare    Number Magnitude
  49. Declare       Integer Number
  50. Declare       Float Number
  51. Declare Method Object text message bytecodes literals stackSize temporarySize
  52. Declare Process Object interpreter nextProcess state
  53. Declare Random Object
  54. Declare Smalltalk Object
  55. Declare Symbol Object
  56. Declare UndefinedObject Object
  57. *
  58. Instance Smalltalk smalltalk
  59. Instance True true
  60. Instance False false
  61. *
  62. Class Object
  63.     == aValue
  64.         ^ <21 self aValue>
  65. |
  66.     = aValue
  67.         ^ self == aValue
  68. |
  69.     basicAt: index
  70.         ^ <25 self index>
  71. |
  72.     basicAt: index put: value
  73.         ^ <31 self index value>
  74. |
  75.     basicSize
  76.         ^ <12 self>
  77. |
  78.     class
  79.         ^ <11 self>
  80. |
  81.     hash
  82.         ^ <13 self>
  83. |
  84.     isMemberOf: aClass
  85.         ^ self class == aClass
  86. |
  87.     isNil
  88.         ^ false
  89. |
  90.     isKindOf: aClass    | myClass |
  91.         myClass <- self class.
  92.         [ myClass notNil ] whileTrue:
  93.             [ (myClass == aClass) ifTrue: [ ^ true ].
  94.                myClass <- myClass superClass ].
  95. |
  96.     notNil
  97.         ^ true
  98. |
  99.     print
  100.         ^ self printString print
  101. |
  102.     printString
  103.         ^ self class printString
  104. ]
  105. Class Array
  106.     < coll
  107.         (coll isKindOf: Array)
  108.             ifTrue: [ self with: coll 
  109.                    do: [:x :y | (x < y) ifTrue: [ ^ true ]].
  110.                   ^ self size < coll size ]
  111.             ifFalse: [ ^ super < coll ]
  112. |
  113.     = coll
  114.         (coll isKindOf: Array)
  115.             ifTrue: [ (self size = coll size)
  116.                     ifFalse: [ ^ false ].
  117.                   self with: coll
  118.                     do: [:x :y | (x = y) 
  119.                         ifFalse: [ ^ false ] ]. 
  120.                  ^ true ]
  121.             ifFalse: [ ^ super < coll ]
  122. |
  123.     at: index put: value
  124.         (self includesKey: index)
  125.             ifTrue: [ self basicAt: index put: value ]
  126.             ifFalse: [ smalltalk error: 
  127.                 'illegal index to at:put: for array' ]
  128. |
  129.     binaryDo: aBlock
  130.         (1 to: self size) do:
  131.             [:i | aBlock value: i value: (self at: i) ]
  132. |
  133.     do: aBlock
  134.         (1 to: self size) do:
  135.             [:i | aBlock value: (self at: i) ]
  136. |
  137.     exchange: a and: b    | temp |
  138.         temp <- self at: a.
  139.         self at: a put: (self at: b).
  140.         self at: b put: temp
  141. |
  142.     includesKey: index
  143.         ^ index between: 1 and: self size
  144. |
  145.     size
  146.         ^ self basicSize
  147. |
  148.     sort
  149.         ^ self sort: [:a :b | a < b ]
  150. |
  151.     sort: sortBlock
  152.         (self size to: 2 by: -1 ) do:
  153.           [:high | (1 to: high - 1) do:
  154.              [:index | (sortBlock value: (self at: index)
  155.                 value: (self at: high))
  156.                 ifFalse: [ self exchange: index and: high ] ] ]
  157. |
  158.     with: coll do: aBlock
  159.         (1 to: (self size min: coll size))
  160.             do: [:i | aBlock value: (self at: i) 
  161.                     value: (coll at: i) ]
  162. ]
  163. Class Block
  164.     value
  165.         ^ context executeFrom: bytecodeCounter
  166. |
  167.     value: x
  168.         context temporaries at: argumentLocation put: x.
  169.         ^ context executeFrom: bytecodeCounter
  170. |
  171.     value: x value: y    | temps |
  172.         temps <- context temporaries.
  173.         temps at: argumentLocation put: x.
  174.         temps at: argumentLocation + 1 put: y.
  175.         ^ context executeFrom: bytecodeCounter
  176. |
  177.     value: x value: y value: z    | temps |
  178.         temps <- context temporaries.
  179.         temps at: argumentLocation put: x.
  180.         temps at: argumentLocation + 1 put: y.
  181.         temps at: argumentLocation + 2 put: z.
  182.         ^ context executeFrom: bytecodeCounter
  183. |
  184.     whileTrue: aBlock
  185.         ( self value ) ifTrue:
  186.             [ aBlock value. 
  187.                 [ self value ] whileTrue: [ aBlock value ] ]
  188. ]
  189. Class Boolean
  190.     ifTrue: trueBlock
  191.         ^ self ifTrue: [ trueBlock value ] ifFalse: [ nil ]
  192. |
  193.     ifFalse: falseBlock
  194.         ^ self ifTrue: [ nil ] ifFalse: [ falseBlock value ]
  195. |
  196.     ifFalse: falseBlock ifTrue: trueBlock
  197.         ^ self ifTrue: [ trueBlock value ]
  198.             ifFalse: [ falseBlock value ]
  199. |
  200.     and: aBlock
  201.         self ifTrue: [ ^ aBlock value ].
  202.         ^ false
  203. |
  204.     or: aBlock
  205.         self ifFalse: [ ^ aBlock value ].
  206.         ^ true
  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 asciiValue ]
  228.             ifFalse: [ smalltalk error: 'char compared to nonchar']
  229. |
  230.     == aValue
  231.         ^ (aValue isMemberOf: Char)
  232.             ifTrue: [ value = aValue asciiValue ]
  233.             ifFalse: [ false ]
  234. |
  235.     = aValue
  236.         ^ self == aValue
  237. |
  238.     asciiValue
  239.         ^ value
  240. |
  241.     asString
  242.         ^ ' ' copy; at: 1 put: self
  243. |
  244.     digitValue
  245.         ^ value - 48
  246. |
  247.     isAlphabetic
  248.         ^ (self isLowercase) or: [ self isUppercase ]
  249. |
  250.     isAlphaNumeric
  251.         ^ (self isAlphabetic) or: [ self isDigit ]
  252. |
  253.     isBlank
  254.         ^ value = 32
  255. |
  256.     isDigit
  257.         ^ value between: 48 and: 57
  258. |
  259.     isLowercase
  260.         ^ value between: 97 and: 122
  261. |
  262.     isUppercase
  263.         ^ value between: 65 and: 90
  264. |
  265.     value: aValue        " private - used for initializatin "
  266.         value <- aValue
  267. |
  268.     printString
  269.         ^ '$', value asCharacter
  270. ]
  271. Class Class
  272.     new        | newObject |
  273.         newObject <- self new: size.
  274.         (self == Class)
  275.             ifTrue: [ newObject initialize ]
  276.             ifFalse: [(methods includesKey: #new )
  277.                     ifTrue: [ ^ newObject new ]].
  278.         ^ newObject
  279. |
  280.     new: size    " hack out block the right size and class "
  281.         ^ < 22 < 58 size > self >
  282. |
  283.     initialize
  284.         superClass <- Object.
  285.         size <- 0.
  286.         methods <- Dictionary new
  287. |
  288.     name: aString
  289.         name <- aString
  290. |
  291.     methods
  292.         ^ methods
  293. |
  294.     objectSize
  295.         ^ size
  296. |
  297.     printString
  298.         ^ name asString
  299. |
  300.     respondsTo: message
  301.         ^ methods includesKey: message
  302. |
  303.     superClass
  304.         ^ superClass
  305. |
  306.     superClass: aClass
  307.         superClass <- aClass
  308. |
  309.     variables
  310.         ^ variables
  311. |
  312.     variables: nameArray
  313.         variables <- nameArray.
  314.         size <- superClass objectSize + nameArray size
  315. ]
  316. Class Collection
  317.     < coll
  318.         self do: [:x | (coll includes: x) ifFalse: [ ^ false ]].
  319.         ^ true
  320. |
  321.     = coll
  322.         self do: [:x | (self occurrencesOf: x) = 
  323.                 (coll occurrencesOf: x) ifFalse: [ ^ false ] ].
  324.         ^ true
  325. |
  326.     asArray        | newArray i |
  327.         newArray <- Array new: self size.
  328.         i <- 0.
  329.         self do: [:x | i <- i + 1. newArray at: i put: x].
  330.         ^ newArray
  331. |
  332.     asByteArray    | newArray i |
  333.         newArray <- ByteArray new size: self size.
  334.         i <- 0.
  335.         self do: [:x | i <- i + 1. newArray at: i put: x].
  336.         ^ newArray
  337. |
  338.     asSet
  339.         ^ Set new addAll: self
  340. |
  341.     asString
  342.         ^ self asByteArray asString
  343. |
  344.     detect: aBlock
  345.         ^ self detect: aBlock
  346.         ifAbsent: [ smalltalk  error: 'no object found matching detect']
  347.  
  348. |
  349.         detect: aBlock ifAbsent: exceptionBlock   
  350.                 self do: [:x | 
  351.                           (aBlock value: x) ifTrue: [^ x ] ].
  352.                 ^ exceptionBlock value
  353. |
  354.     includes: value
  355.         self do: [:x | (x = value) ifTrue: [ ^ true ] ].
  356.         ^ false
  357. |
  358.         inject: thisValue into: binaryBlock     | last |
  359.                 last <- thisValue.
  360.                 self do: [:x | last <- binaryBlock value: last value: x].
  361.                 ^ last
  362. |
  363.     isEmpty 
  364.         ^ self size == 0
  365. |
  366.     occurrencesOf: anObject
  367.         ^ self inject: 0
  368.                        into: [:x :y | (y = anObject) 
  369.                                          ifTrue: [x + 1]
  370.                                          ifFalse: [x] ]
  371. |
  372.     printString
  373.         ^ ( self inject: self class printString , ' ('
  374.              into: [:x :y | x , ' ' , y printString]), ' )'
  375. |
  376.     size
  377.         ^ self inject: 0 into: [:x :y | x + 1]
  378. ]
  379. Class Context
  380.     executeFrom: value
  381.         ^ <28 self value>
  382. |
  383.     method: value
  384.         method <- value
  385. |
  386.     arguments: value
  387.         arguments <- value
  388. |
  389.     temporaries
  390.         ^ temporaries
  391. |
  392.     temporaries: value
  393.         temporaries <- value
  394. ]
  395. Class Dictionary
  396.     new
  397.         ^ Dictionary new: 39
  398. |
  399.     hash: aKey
  400.         ^ 3 * ((aKey hash) rem: ((self basicSize) quo: 3))
  401. |
  402.     at: aKey ifAbsent: exceptionBlock    | hashPosition  link |
  403.  
  404.         hashPosition <- self hash: aKey.
  405.         ((self basicAt: hashPosition + 1) == aKey)
  406.             ifTrue: [ ^ self basicAt: hashPosition + 2].
  407.         link <- self basicAt: hashPosition + 3.
  408.         (link notNil)
  409.             ifTrue: [ ^ link at: aKey ifAbsent: exceptionBlock ]
  410.             ifFalse: [ ^ exceptionBlock value ]
  411. |
  412.     at: aKey put: aValue            | hashPosition link |
  413.  
  414.         hashPosition <- self hash: aKey.
  415.         ((self basicAt: hashPosition + 1) isNil)
  416.            ifTrue: [ self basicAt: hashPosition + 1 put: aKey ].
  417.         ((self basicAt: hashPosition + 1) == aKey)
  418.            ifTrue: [ self basicAt: hashPosition + 2 put: aValue ]
  419.            ifFalse: [ link <- self basicAt: hashPosition + 3.
  420.             (link notNil)
  421.                 ifTrue: [ link at: aKey put: aValue ]
  422.                 ifFalse: [ self basicAt: hashPosition + 3
  423.                     put: (Link new; key: aKey; value: aValue)]]
  424. |
  425.     binaryDo: aBlock
  426.         (1 to: self basicSize by: 3) do:
  427.             [:i | (self basicAt: i) notNil
  428.                 ifTrue: [ aBlock value: (self basicAt: i)
  429.                         value: (self basicAt: i+1) ].
  430.                   (self basicAt: i+2) notNil
  431.                 ifTrue: [ (self basicAt: i+2) 
  432.                         binaryDo: aBlock ] ]
  433. |
  434.     includesKey: aKey    | hashPosition link |
  435.         hashPosition <- self hash: aKey.
  436.         ((self basicAt: hashPosition + 1) == aKey)
  437.             ifTrue: [ ^ true ].
  438.         link <- self basicAt: hashPosition + 3.
  439.         (link notNil)
  440.             ifTrue: [ ^ link includesKey: aKey ].
  441.         ^ false
  442. |
  443.     removeKey: aKey
  444.         ^ self removeKey: aKey
  445.             ifAbsent: [ smalltalk error: 'remove key not found']
  446. |
  447.     removeKey: aKey ifAbsent: exceptionBlock
  448.         ^ (self includesKey: aKey)
  449.             ifTrue: [ self basicRemoveKey: aKey ]
  450.             ifFalse [ exceptionBlock value ]
  451. |
  452.     basicRemoveKey: aKey        | hashPosition link |
  453.         hashPosition <- self hash: aKey.
  454.         ((self basicAt: hashPosition + 1) == aKey)
  455.             ifTrue: [ self basicAt: hashPosition + 1 put: nil.
  456.                   self basicAt: hashPosition + 2 put: nil]
  457.             ifFalse: [ link <- self basicAt: hashPosition + 3.
  458.                 (link notNil)
  459.                     ifTrue: [ self basicAt: hashPosition + 3
  460.                             put: (link removeKey: aKey) ]]
  461. ]
  462. Class Float
  463.     + value
  464.         ^ (value isMemberOf: Float)
  465.             ifTrue: [ <110 self value> ]
  466.             ifFalse: [ super + value ]
  467. |
  468.     - value
  469.         ^ (value isMemberOf: Float)
  470.             ifTrue: [ <111 self value> ]
  471.             ifFalse: [ super - value ]
  472. |
  473.     < value
  474.         ^ (value isMemberOf: Float)
  475.             ifTrue: [ <112 self value> ]
  476.             ifFalse: [ super < value ]
  477. |
  478.     = value
  479.         ^ (value isMemberOf: Float)
  480.             ifTrue: [ <116 self value> ]
  481.             ifFalse: [ super = value ]
  482. |
  483.     * value
  484.         ^ (value isMemberOf: Float)
  485.             ifTrue: [ <118 self value> ]
  486.             ifFalse: [ super * value ]
  487. |
  488.     / value
  489.         ^ (value isMemberOf: Float)
  490.             ifTrue: [ <119 self value> ]
  491.             ifFalse: [ super / value ]
  492. |
  493.     ceiling        | i |
  494.         i <- self integerPart.
  495.         ^ ((self positive) and: [ self ~= i ])
  496.             ifTrue: [ i + 1 ]
  497.             ifFalse: [ i ]
  498. |
  499.     coerce: value
  500.         ^ value asFloat
  501. |
  502.     exp
  503.         ^ <103 self>
  504. |
  505.     floor        | i |
  506.         i <- self integerPart.
  507.         ^ ((self negative) and: [ self ~= i ])
  508.             ifTrue: [ i - 1 ]
  509.             ifFalse: [ i ]
  510. |
  511.     fractionalPart
  512.         ^ self - self integerPart
  513. |
  514.     logGamma
  515.         ^ <105 self>
  516. |
  517.     generality
  518.         ^ 7
  519. |
  520.     integerPart
  521.         ^ <106 self>
  522. |
  523.     ln
  524.         ^ <102 self>
  525. |
  526.     printString
  527.         ^ <101 self>
  528. |
  529.     rounded
  530.         ^ (self + 0.5 ) floor
  531. |
  532.     sqrt
  533.         ^ <104 self>
  534. |
  535.     truncated
  536.         ^ (self < 0.0 ) 
  537.             ifTrue: [ self ceiling ]
  538.             ifFalse: [ self floor ]
  539. ]
  540. Class IndexedCollection
  541.     addAll: aCollection
  542.         aCollection binaryDo: [:i :x | self at: i put: x ]
  543. |
  544.     asArray    
  545.         ^ Array new: self size ; addAll: self
  546. |
  547.     asDictionary
  548.         ^ Dictionary new ; addAll: self
  549. |
  550.     at: aKey
  551.         ^ self at: aKey 
  552.             ifAbsent: [ smalltalk error: 'index to at: illegal' ]
  553. |
  554.     at: index ifAbsent: exceptionBlock
  555.          ^ (self includesKey: index)
  556.             ifTrue: [ self basicAt: index ]
  557.             ifFalse: [ exceptionBlock value ]
  558. |
  559.         binaryInject: thisValue into: aBlock     | last |
  560.                 last <- thisValue.
  561.                 self binaryDo: [:i :x | last <- aBlock value: last 
  562.                         value: i value: x].
  563.                 ^ last
  564. |
  565.     collect: aBlock
  566.         ^ self binaryInject: Dictionary new
  567.             into: [:s :i :x | s at: i put: (aBlock value: x).  s]
  568. |
  569.     do: aBlock
  570.         self binaryDo: [:i :x | aBlock value: x ]
  571. |
  572.     keys
  573.         ^ self binaryInject: Set new 
  574.             into: [:s :i :x | s add: i ]
  575. |
  576.     indexOf: value
  577.         ^ self indexOf: value
  578.             ifAbsent: [ smalltalk error: 'index not found']
  579. |
  580.     indexOf: value ifAbsent: exceptionBlock
  581.         self binaryDo: [:i :x | (x == value)
  582.                 ifTrue: [ ^ i ] ].
  583.         ^ exceptionBlock value
  584. |
  585.     select: aBlock
  586.         ^ self binaryInject: Dictionary new
  587.             into: [:s :i :x | (aBlock value: x)
  588.                     ifTrue: [ s at: i put: x ]. s ]
  589. |
  590.     values
  591.         ^ self binaryInject: List new
  592.             into: [:s :i :x | s add: x ]
  593. ]
  594. Class Integer
  595.     + value
  596.         ^ (value isMemberOf: Integer)
  597.             ifTrue: [ <60 self value> ]
  598.             ifFalse: [ super + value ]
  599. |
  600.     - value
  601.         ^ (value isMemberOf: Integer)
  602.             ifTrue: [ <61 self value> ]
  603.             ifFalse: [ super - value ]
  604. |
  605.     < value
  606.         ^ (value isMemberOf: Integer)
  607.             ifTrue: [ <62 self value> ]
  608.             ifFalse: [ super < value ]
  609. |
  610.     = value
  611.         ^ (value isMemberOf: Integer)
  612.             ifTrue: [ <66 self value> ]
  613.             ifFalse: [ super = value ]
  614. |
  615.     * value
  616.         ^ (value isMemberOf: Integer)
  617.             ifTrue: [ <68 self value> ]
  618.             ifFalse: [ super * value ]
  619. |
  620.     / value        " do it as float "
  621.         ^ self asFloat / value
  622. |
  623.     // value    | i |
  624.         i <- self quo: value.
  625.         ( (i < 0) and: [ (self rem: value) ~= 0] )
  626.             ifTrue: [ i <- i - 1 ].
  627.         ^ i
  628. |
  629.     \\ value
  630.         ^ self * self sign rem: value
  631. |
  632.     allMask: value
  633.         ^ value = (self bitAnd: value)
  634. |
  635.     anyMask: value
  636.         ^ 0 ~= (self bitAnd: value)
  637. |
  638.     asCharacter
  639.         ^ <56 self>
  640. |
  641.     asFloat
  642.         ^ <51 self>
  643. |
  644.     bitAnd: value
  645.         ^ (value isMemberOf: Integer)
  646.             ifTrue: [ <71 self value > ]
  647.             ifFalse: [ smalltalk error: 
  648.                 'argument to bit operation must be integer']
  649. |
  650.     bitAt: value
  651.         ^ (self bitShift: 1 - value) bitAnd: 1
  652. |
  653.     bitInvert
  654.         ^ self bitXor: -1
  655. |
  656.     bitOr: value
  657.         ^ (self bitXor: value) bitXor: (self bitAnd: value)
  658. |
  659.     bitXor: value
  660.         ^ (value isMemberOf: Integer)
  661.             ifTrue: [ <72 self value > ]
  662.             ifFalse: [ smalltalk error: 
  663.                 'argument to bit operation must be integer']
  664. |
  665.     bitShift: value
  666.         ^ (value isMemberOf: Integer)
  667.             ifTrue: [ <79 self value > ]
  668.             ifFalse: [ smalltalk error: 
  669.                 'argument to bit operation must be integer']
  670. |
  671.     even
  672.         ^ (self rem: 2) = 0
  673. |
  674.     factorial    | i |
  675.         ^ (self < 8) 
  676.             ifTrue: [ i <- 1.
  677.                   (2 to: self) do: [:x | i <- i * x].
  678.                   i ]
  679.             ifFalse: [ (self + 1) asFloat logGamma exp ]
  680. |
  681.     gcd: value
  682.         (value = 0) ifTrue: [ ^ self ].
  683.         (self negative) ifTrue: [ ^ self negated gcd: value ].
  684.         (value negative) ifTrue: [ ^ self gcd: value negated ].
  685.         (value > self) ifTrue: [ ^ value gcd: self ].
  686.         ^ value gcd: (self rem: value)
  687. |
  688.     generality
  689.         ^ 2
  690. |
  691.     lcm: value
  692.         ^ (self quo: (self gcd: value)) * value
  693. |
  694.     odd
  695.         ^ (self rem: 2) ~= 0
  696. |
  697.     quo: value
  698.         ^ (value isMemberOf: Integer)
  699.             ifTrue: [ <69 self value> ]
  700.             ifFalse: [ smalltalk error: 
  701.                 'argument to quo: must be integer']
  702. |
  703.     rem: aValue
  704.         ^ (value isMemberOf: Integer)
  705.             ifTrue: [ <70 self value> ]
  706.             ifFalse: [ smalltalk error: 
  707.                 'argument to rem: must be integer']
  708. |
  709.     printString
  710.         ^ <57 self>
  711. |
  712.     timesRepeat: aBlock    | i |
  713.         " use while, which is optimized, not to:, which is not"
  714.         i <- 0.
  715.         [ i < self ] whileTrue:
  716.             [ aBlock value. i <- i + 1]
  717. ]
  718. Class Interval
  719.     do: aBlock        | current |
  720.         current <- lower.
  721.         (step > 0) 
  722.             ifTrue: [ [ current <= upper ] whileTrue:
  723.                     [ aBlock value: current.
  724.                       current <- current + step ] ]
  725.             ifFalse: [ [ current >= upper ] whileTrue:
  726.                     [ aBlock value: current.
  727.                     current <- current + step ] ]
  728. |
  729.     lower: aValue
  730.         lower <- aValue
  731. |
  732.     upper: aValue
  733.         upper <- aValue
  734. |
  735.     step: aValue
  736.         step <- aValue
  737. ]
  738. Class Link
  739.     addLast: aValue
  740.         (nextLink notNil)
  741.             ifTrue: [ nextLink addLast: aValue]
  742.             ifFalse: [ nextLink <- Link new; value: aValue]
  743. |
  744.     at: aKey ifAbsent: exceptionBlock
  745.         (aKey == key)
  746.             ifTrue: [ ^value ]
  747.             ifFalse: [ (nextLink notNil)
  748.                     ifTrue: [ ^ nextLink at: aKey
  749.                             ifAbsent: exceptionBlock ]
  750.                     ifFalse: [ ^ exceptionBlock value ] ]
  751. |
  752.     at: aKey put: aValue
  753.         (aKey == key)
  754.             ifTrue: [ value <- aValue ]
  755.             ifFalse: [ (nextLink notNil)
  756.                 ifTrue: [ nextLink at: aKey put: aValue]
  757.                 ifFalse: [ nextLink <- Link new;
  758.                         key: aKey; value: aValue] ]
  759. |
  760.     binaryDo: aBlock
  761.         aBlock value: key value: value.
  762.         (nextLink notNil)
  763.             ifTrue: [ nextLink binaryDo: aBlock ]
  764. |
  765.     do: aBlock
  766.         aBlock value: value.
  767.         (nextLink notNil)
  768.             ifTrue: [ nextLink do: aBlock ]
  769. |
  770.     key: aKey
  771.         key <- aKey
  772. |
  773.     includesKey: aKey
  774.         (key == aKey)
  775.             ifTrue: [ ^ true ].
  776.         (nextLink notNil)
  777.             ifTrue: [ ^ nextLink includesKey: aKey ]
  778.             ifFalse: [ ^ false ]
  779. |
  780.     link: aLink
  781.         nextLink <- aLink
  782. |
  783.     removeKey: aKey
  784.         (aKey == key)
  785.             ifTrue: [ ^ nextLink ]
  786.             ifFalse: [ (nextLink notNil)
  787.                 ifTrue: [ nextLink <- nextLink removeKey: aKey]]
  788. |
  789.     removeValue: aValue
  790.         (aValue == value)
  791.             ifTrue: [ ^ nextLink ]
  792.             ifFalse: [ (nextLink notNil)
  793.                 ifTrue: [ nextLink <- nextLink removeValue: aValue]]
  794. |
  795.     size
  796.         (nextLink notNil)
  797.             ifTrue: [ ^ 1 + nextLink size]
  798.             ifFalse: [ ^ 1 ]
  799. |
  800.     value: aValue
  801.         value <- aValue
  802. |
  803.     value
  804.         ^ value
  805. ]
  806. Class List
  807.     add: aValue
  808.         ^ self addFirst: aValue
  809. |
  810.     addAll: aValue
  811.         aValue do: [:x | self add: x ]
  812. |
  813.     addFirst: aValue
  814.         links <- Link new; value: aValue; link: links
  815. |
  816.     addLast: aValue
  817.         (links isNil)
  818.             ifTrue: [ self addFirst: aValue ]
  819.             ifFalse: [ links addLast: aValue ]
  820. |
  821.     collect: aBlock
  822.         ^ self inject: self class new
  823.                into: [:x :y | x add: (aBlock value: y). x ]
  824. |
  825.     reject: aBlock          
  826.         ^ self select: [:x | (aBlock value: x) not ]
  827. |
  828.     select: aBlock          
  829.         ^ self inject: self class new
  830.                into: [:x :y | (aBlock value: y) 
  831.                                         ifTrue: [x add: y]. x]
  832. |
  833.     do: aBlock
  834.         (links notNil)
  835.             ifTrue: [ links do: aBlock ]
  836. |
  837.     first
  838.         (links notNil)
  839.             ifTrue: [ ^ links value ]
  840.             ifFalse: [ ^ smalltalk error: 'first on empty list']
  841. |
  842.     removeFirst
  843.         self remove: self first
  844. |
  845.     remove: value
  846.         (links notNil)
  847.             ifTrue: [ links <- links removeValue: value ]
  848. |
  849.     size
  850.         (links isNil)
  851.             ifTrue: [ ^ 0 ]
  852.             ifFalse: [ ^ links size ]
  853. ]
  854. Class Magnitude
  855.     <= value
  856.         ^ (self < value) or: [ self = value ]
  857. |
  858.     < value
  859.         ^ (value > self)
  860. |
  861.     >= value
  862.         ^ (self > value) or: [ self = value ]
  863. |
  864.     > value
  865.         ^ (value < self)
  866. |
  867.     = value
  868.         ^ (self == value)
  869. |
  870.     ~= value
  871.         ^ (self = value) not
  872. |
  873.     between: low and: high
  874.         ^ (low <= self) and: [ self <= high ]
  875. |
  876.     max: value
  877.         ^ (self < value)
  878.             ifTrue: [ value ]
  879.             ifFalse: [ self ]
  880. |
  881.     min: value
  882.         ^ (self < value)
  883.             ifTrue: [ self ]
  884.             ifFalse: [ value ]
  885. ]
  886. Class Method
  887.     compileWithClass: aClass
  888.         ^ <39 aClass text self>
  889. |
  890.     name
  891.         ^ message
  892. |
  893.     message: aSymbol
  894.         message <- aSymbol
  895. |
  896.     text
  897.         ^ text
  898. |
  899.     text: aString
  900.         text <- aString
  901. ]
  902. Class Number
  903.     maxgen: value
  904.         ^ (self generality > value generality)
  905.             ifTrue: [ self ]
  906.             ifFalse: [ value coerce: self ]
  907. |
  908.     + value
  909.         ^ (self maxgen: value) + (value maxgen: self)
  910. |
  911.     - value
  912.         ^ (self maxgen: value) - (value maxgen: self)
  913. |
  914.     < value
  915.         ^ (self maxgen: value) < (value maxgen: self)
  916. |
  917.     = value
  918.         ^ (self maxgen: value) = (value maxgen: self)
  919. |
  920.     * value
  921.         ^ (self maxgen: value) * (value maxgen: self)
  922. |
  923.     / value
  924.         ^ (self maxgen: value) / (value maxgen: self)
  925. |
  926.     abs
  927.         ^ (self < 0)
  928.             ifTrue: [ 0 - self ]
  929.             ifFalse: [ self ]
  930. |
  931.     exp
  932.         ^ self asFloat exp
  933. |
  934.     gamma
  935.         ^ self asFloat gamma
  936. |
  937.     ln
  938.         ^ self asFloat ln
  939. |
  940.     log: value
  941.         ^ self ln / value ln
  942. |
  943.     negated
  944.         ^ 0 - self
  945. |
  946.     negative
  947.         ^ self < 0
  948. |
  949.     positive
  950.         ^ self >= 0
  951. |
  952.     raisedTo: value
  953.         ^ ( value * self ln ) exp
  954. |
  955.     reciprocal
  956.         ^ 1.00 / self
  957. |
  958.     roundTo: value
  959.         ^ (self / value ) rounded * value
  960. |
  961.     sign
  962.         ^ self negative ifTrue: [ -1 ]
  963.             ifFalse: [ self strictlyPositive 
  964.                     ifTrue: [ 1 ] ifFalse: [ 0 ] ]
  965. |
  966.     squared
  967.         ^ self * self
  968. |
  969.     strictlyPositive
  970.         ^ self > 0
  971. |
  972.     to: value
  973.         ^ Interval new; lower: self; upper: value; step: 1
  974. |
  975.     to: value by: step
  976.         ^ Interval new; lower: self; upper: value; step: step
  977. |
  978.     trucateTo: value
  979.         ^ (self / value) trucated * value
  980. ]
  981. Class Random
  982.     between: low and: high
  983.         ^ (self next * (high - low)) + low
  984. |
  985.     next
  986.         ^ (<3> rem: 1000) / 1000
  987. |
  988.     next: value    | list |
  989.         list <- List new.
  990.         value timesRepeat: [ list add: self next ].
  991.         ^ list
  992. |
  993.     randInteger: value
  994.         ^ 1 + (<3> rem: value)
  995. |
  996.     set: value
  997.         <55 value>
  998. ]
  999. Class Set
  1000.     add: value
  1001.         (self includes: value)
  1002.             ifFalse: [ self addFirst: value ]
  1003. ]
  1004. Class String
  1005.     , value
  1006.         ^ (value isMemberOf: String)
  1007.             ifTrue: [ <24 self value> ]
  1008.             ifFalse: [ self , value printString ]
  1009. |
  1010.     = value
  1011.         (value isKindOf: String)
  1012.             ifTrue: [ ^ super = value ]
  1013.             ifFalse: [ ^ false ]
  1014. |
  1015.     < value
  1016.         (value isKindOf: String)
  1017.             ifTrue: [ ^ super < value ]
  1018.             ifFalse: [ ^ false ]
  1019. |
  1020.     asInteger        | value |
  1021.         value <- 0.
  1022.         self do: [:x | value <- value * 10 + x digitValue ].
  1023.         ^ value
  1024. |
  1025.     basicAt: index
  1026.         ^  Char new ; value: (super basicAt: index).
  1027. |
  1028.     basicAt: index put: aValue
  1029.         (aValue isMemberOf: Char)
  1030.             ifTrue: [ super basicAt: index put: aValue asciiValue ]
  1031.             ifFalse: [ smalltalk error:
  1032.                 'cannot put non Char into string' ]
  1033. |
  1034.     asSymbol
  1035.         ^ <83 self>
  1036. |
  1037.     size
  1038.         ^ <81 self>
  1039. |
  1040.     copy
  1041.         ^ <82 self>
  1042. ]
  1043. Class Smalltalk
  1044.     class: aClass doesNotRespond: aMessage
  1045.         ^ self error: aClass printString ,
  1046.             ' does not respond to ' , aMessage
  1047. |
  1048.     cantFindGlobal: name
  1049.         ^ self error: 'cant find global symbol ' , name
  1050. |
  1051.     flushMessageCache
  1052.         <2>
  1053. |
  1054.     saveImage: file
  1055.         ^ <87 file>
  1056. ]
  1057. Class Symbol
  1058.     asString
  1059.         ^ <82 self>
  1060. |
  1061.     printString
  1062.         ^ '#' , self asString
  1063. ]
  1064. Class False
  1065.     ifTrue: trueBlock ifFalse: falseBlock
  1066.         ^ falseBlock value
  1067. |
  1068.     not
  1069.         ^ true
  1070. ]
  1071. Class True
  1072.     ifTrue: trueBlock ifFalse: falseBlock
  1073.         ^ trueBlock value
  1074. |
  1075.     not
  1076.         ^ false
  1077. ]
  1078. Class UndefinedObject
  1079.     isNil
  1080.         ^ true
  1081. |
  1082.     notNil
  1083.         ^ false
  1084. |
  1085.     printString
  1086.         ^ 'nil'
  1087. ]
  1088. End
  1089. echo unbundling unixclasses 1>&2
  1090. cat >unixclasses <<'End'
  1091. *
  1092. * Little Smalltalk, version 2
  1093. * Written by Tim Budd, Oregon State University, July 1987
  1094. *
  1095. *  methods for the unix front end - single process version
  1096. *
  1097. *    (override previous declaration, adding new instance variable)
  1098. Declare Smalltalk Object errorRecoveryBlock
  1099. *    (better override instance as well )
  1100. Instance Smalltalk smalltalk
  1101. *
  1102. Class Method
  1103.     executeWith: arguments
  1104.         ^ ( Context new ; method: self ; 
  1105.             temporaries: ( Array new: temporarySize) ;
  1106.             arguments: arguments )
  1107.            executeFrom: 0
  1108. ]
  1109. Class Class
  1110.     addMethod
  1111.         self doEdit: ''
  1112. |
  1113.     editMethod: name        | theMethod |
  1114.         theMethod <- methods at: name
  1115.                 ifAbsent: [ 'no such method ' print. ^ nil ].
  1116.         self doEdit: theMethod text
  1117. |
  1118.     doEdit: startingText        | theMethod |
  1119.         theMethod <- Method new;
  1120.             text: startingText edit.
  1121.         (theMethod compileWithClass: self)
  1122.             ifTrue: [ methods at: theMethod name put: theMethod .
  1123.                   smalltalk flushMessageCache ]
  1124. |
  1125.     viewMethod: name
  1126.         " edit, but don't do anything with result "
  1127.         (methods at: name
  1128.             ifAbsent: [ 'no such method ' print. ^ nil ]) text edit
  1129. ]
  1130. Class Smalltalk
  1131.     error: aString
  1132.         ('Error: ' ,  aString) print.
  1133.         errorRecoveryBlock value
  1134. |
  1135.     getString
  1136.         ^ <1>
  1137. |
  1138.     init        | string |
  1139.         [ '>    ' printNoReturn. 
  1140.           string <- smalltalk getString. string notNil ]
  1141.             whileTrue: [ (string size > 0)
  1142.                     ifTrue: [ smalltalk doIt: string ] ]
  1143. |
  1144.     doIt: aString        | method |
  1145.         errorRecoveryBlock <- [ ^ nil ].
  1146.         method <- Method new.
  1147.         method text: ( 'proceed ', aString ).
  1148.         (method compileWithClass: Smalltalk)
  1149.             ifTrue: [ method executeWith: #( 1 ) ]
  1150. |
  1151.     saveImage        | name |
  1152.         'type image name: ' printNoReturn.
  1153.         name <- self getString.
  1154.         (self saveImage: name)
  1155.             ifTrue: [ ('image ', name, ' created') print ]
  1156.             ifFalse: [ 'image not created' print ]
  1157. ]
  1158. Class String
  1159.     edit
  1160.         ^ <89 self>
  1161. |
  1162.     print
  1163.         ^ <88 self>
  1164. |
  1165.     printNoReturn
  1166.         ^ <86 self>
  1167. ]
  1168. End
  1169. echo unbundling multclasses 1>&2
  1170. cat >multclasses <<'End'
  1171. *
  1172. * Little Smalltalk, version 2
  1173. * Written by Tim Budd, Oregon State University, July 1987
  1174. *
  1175. * multiprocess scheduler - this is optional
  1176. *
  1177. Declare Scheduler Object processList
  1178. Declare Process Object interpreter
  1179. Declare Interpreter Object context prev creating stack stackTop byteCodePointer
  1180. Instance Scheduler scheduler
  1181. Class Block
  1182.     newProcess
  1183.         ^ (context newInterpreter: bytecodeCounter) newProcess
  1184. |
  1185.     fork
  1186.         self newProcess resume
  1187. ]
  1188. Class Method
  1189.     executeWith: arguments
  1190.         ( ( Context new ; method: self ; 
  1191.             temporaries: ( Array new: temporarySize) ;
  1192.             arguments: arguments ) newInterpreter: 0 )
  1193.                 newProcess resume
  1194. ]
  1195. Class Scheduler
  1196.     new
  1197.         processList <- Set new
  1198. |
  1199.     addProcess: aProcess
  1200.         processList add: aProcess
  1201. |
  1202.     removeProcess: aProcess
  1203.         processList remove: aProcess
  1204. |
  1205.     run
  1206.         [ processList size ~= 0 ] whileTrue:
  1207.             [ processList do: [ :x | x execute ] ]
  1208. ]
  1209. Class Process
  1210.     execute     | i |
  1211.         i <- 0.
  1212.         [(i < 200) and: [ interpreter notNil ]]
  1213.             whileTrue: [ interpreter <- interpreter execute.
  1214.                     i <- i + 1 ].
  1215.         (interpreter isNil)
  1216.             ifTrue: [ self terminate ]
  1217. |
  1218.     interpreter: value
  1219.         interpreter <- value
  1220. |
  1221.     resume
  1222.         scheduler addProcess: self
  1223. |
  1224.     terminate
  1225.         scheduler removeProcess: self
  1226. ]
  1227. Class Interpreter
  1228.     new
  1229.         stackTop <- 0.
  1230.         byteCodePointer <- 0
  1231. |
  1232.     execute
  1233.         ^ <19 self>
  1234. |
  1235.     byteCounter: start
  1236.         byteCodePointer <- start
  1237. |
  1238.     context: value
  1239.         context <- value
  1240. |
  1241.     stack: value
  1242.         stack <- value.
  1243. |
  1244.     newProcess
  1245.         ^ Process new; interpreter: self
  1246. ]
  1247. Class Context
  1248.     newInterpreter: start
  1249.         ^ Interpreter new;
  1250.             context: self;
  1251.             byteCounter: start;
  1252.             stack: (Array new: 20)
  1253. ]
  1254. End
  1255. echo unbundling unix2classes 1>&2
  1256. cat >unix2classes <<'End'
  1257. *
  1258. * Little Smalltalk, version 2
  1259. * Written by Tim Budd, Oregon State University, July 1987
  1260. *
  1261. * unix specific routines for the multiprocess front end
  1262. *
  1263. *    (override previous declaration, adding new instance variable)
  1264. Declare Smalltalk Object errorRecoveryBlock
  1265. *    (better override instance as well )
  1266. Instance Smalltalk smalltalk
  1267. *
  1268. Class Class
  1269.     addMethod
  1270.         self doEdit: ''
  1271. |
  1272.     editMethod: name        | theMethod |
  1273.         theMethod <- methods at: name
  1274.                 ifAbsent: [ 'no such method ' print. ^ nil ].
  1275.         self doEdit: theMethod text
  1276. |
  1277.     doEdit: startingText        | theMethod |
  1278.         theMethod <- Method new;
  1279.             text: startingText edit.
  1280.         (theMethod compileWithClass: self)
  1281.             ifTrue: [ methods at: theMethod name put: theMethod .
  1282.                   smalltalk flushMessageCache ]
  1283. ]
  1284. Class Smalltalk
  1285.     error: aString
  1286.         ('Error: ' ,  aString) print.
  1287.         errorRecoveryBlock value
  1288. |
  1289.     getString
  1290.         ^ <1>
  1291. |
  1292.     init        | string |
  1293.         scheduler new.
  1294.         [ '>    ' printNoReturn. 
  1295.             string <- smalltalk getString. string notNil ]
  1296.             whileTrue: [ (string size > 0)
  1297.                     ifTrue: [ smalltalk doIt: string ] ]
  1298. |
  1299.     doIt: aString        | method |
  1300.         errorRecoveryBlock <- [ ^ nil ].
  1301.         method <- Method new.
  1302.         method text: ( 'proceed ', aString ).
  1303.         (method compileWithClass: Smalltalk)
  1304.             ifTrue: [ method executeWith: #( 1 ). 
  1305.                   scheduler run ]
  1306. |
  1307.     saveImage        | name |
  1308.         'type image name: ' printNoReturn.
  1309.         name <- self getString.
  1310.         self saveImage: name.
  1311.         ('image ', name, ' created') print
  1312. ]
  1313. Class String
  1314.     edit
  1315.         ^ <89 self>
  1316. |
  1317.     print
  1318.         ^ <88 self>
  1319. |
  1320.     printNoReturn
  1321.         ^ <86 self>
  1322. ]
  1323. End
  1324. echo unbundling testclasses 1>&2
  1325. cat >testclasses <<'End'
  1326. *
  1327. *
  1328. * Little Smalltalk, version 2
  1329. * Written by Tim Budd, Oregon State University, July 1987
  1330. *
  1331. *  a few test cases.
  1332. * invoke by messages to global variable ``test'', i.e.
  1333. *        test queen
  1334. *
  1335. * all test cases can be run by sending the message all to test
  1336. *         test all
  1337. *
  1338. Declare Test Object
  1339. Declare Queen Object row column neighbor
  1340. Declare One Object
  1341. Declare Two One
  1342. Declare Three Two
  1343. Declare Four Three
  1344. Instance Test test
  1345. Class Queen
  1346.     setColumn: aNumber neighbor: aQueen
  1347.         column <- aNumber.
  1348.         neighbor <- aQueen
  1349. |
  1350.     first
  1351.         (neighbor notNil)
  1352.             ifTrue: [ neighbor first ].
  1353.         row <- 1.
  1354.         ^ self testPosition
  1355. |
  1356.     next
  1357.         (row = 8)
  1358.             ifTrue: [ ((neighbor isNil) or: [neighbor next isNil])
  1359.                 ifTrue: [ ^ nil ].
  1360.                 row <- 0 ].
  1361.         row <- row + 1.
  1362.         ^ self testPosition
  1363. |
  1364.     testPosition
  1365.         (neighbor isNil) ifTrue: [ ^ self ].
  1366.         (neighbor checkRow: row column: column)
  1367.             ifTrue: [ ^ self next ]
  1368.             ifFalse: [ ^ self ]
  1369. |
  1370.     checkRow: testRow column: testColumn | columnDifference |
  1371.         columnDifference <- testColumn - column.
  1372.         (((row = testRow) or: 
  1373.             [ row + columnDifference = testRow]) or:
  1374.             [ row - columnDifference = testRow])
  1375.                 ifTrue: [ ^ true ].
  1376.         (neighbor notNil)
  1377.             ifTrue: [ ^ neighbor checkRow: testRow 
  1378.                     column: testColumn ]
  1379.             ifFalse: [ ^ false ]
  1380. |
  1381.     printBoard
  1382.         (neighbor notNil)
  1383.             ifTrue: [ neighbor printBoard ].
  1384.         ('column ', column , ' row ', row ) print.
  1385. ]
  1386. Class One
  1387.         test
  1388.                 ^ 1
  1389. |
  1390.     result1
  1391.                 ^ self test
  1392. ]
  1393. Class Two
  1394.         test
  1395.                 ^ 2
  1396. ]
  1397. Class Three
  1398.         result2
  1399.                 ^ self result1
  1400. |
  1401.     result3
  1402.                 ^ super test
  1403. ]
  1404. Class Four
  1405.         test
  1406.                 ^ 4
  1407. ]
  1408. Class Test
  1409.     all
  1410.         self fork.
  1411.         self queen.
  1412.         self super.
  1413. |
  1414.     fork
  1415.         (Block respondsTo: #fork)
  1416.             ifTrue: [ [ (1 to: 10) do: [:x | x print] ] fork.
  1417.                   [ (30 to: 40) do: [:y | y print] ] fork ]
  1418. |
  1419.     queen        | lastQueen |
  1420.         lastQueen <- nil.
  1421.         (1 to: 8) do: [:i | lastQueen <- Queen new;
  1422.                     setColumn: i neighbor: lastQueen ].
  1423.         lastQueen first.
  1424.         lastQueen printBoard
  1425. |
  1426.     super         | x1 x2 x3 x4 |
  1427.                 x1 <- One new.
  1428.                 x2 <- Two new.
  1429.                 x3 <- Three new.
  1430.                 x4 <- Four new.
  1431.                 x1 test print.
  1432.                 x1 result1 print.
  1433.                 x2 test print.
  1434.                 x2 result1 print.
  1435.                 x3 test print.
  1436.                 x4 result1 print.
  1437.                 x3 result2 print.
  1438.                 x4 result2 print.
  1439.                 x3 result3 print.
  1440.                 x4 result3 print
  1441. ]
  1442. End
  1443. echo unbundling stest.out 1>&2
  1444. cat >stest.out <<'End'
  1445. initially 1778 objects
  1446. >    column 1 row 1
  1447. column 2 row 5
  1448. column 3 row 8
  1449. column 4 row 6
  1450. column 5 row 3
  1451. column 6 row 7
  1452. column 7 row 2
  1453. column 8 row 4
  1454. 1
  1455. 1
  1456. 2
  1457. 2
  1458. 2
  1459. 4
  1460. 2
  1461. 4
  1462. 2
  1463. 2
  1464. >    finally 1789 objects
  1465. End
  1466.