Guest User

Untitled

a guest
Jan 13th, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.24 KB | None | 0 0
  1. /* Cifre Standard Library
  2. (c) Jeremy Tregunna, 2006, All Rights Reserved.
  3.  
  4. This program is open source software, and redistributable under the terms
  5. and conditions of the BSD Licence. */
  6.  
  7. Dictionary := SortedCollection clone do(
  8. Node := Object clone do(
  9. newSlot("key")
  10. newSlot("value")
  11. newSlot("left")
  12. newSlot("right")
  13. newSlot("parent")
  14. newSlot("isRed", true)
  15.  
  16. with := method(aKey, aValue,
  17. if(call message arguments size != 2,
  18. InvalidArgumentException raise("'with' requires a key and a value as arguments only")
  19. )
  20. self clone setKey(aKey) setValue(aValue)
  21. )
  22. )
  23. Node removeSlot("type") // setSlotWithType related -- we don't want a type slot
  24.  
  25. newSlot("root")
  26. newSlot("sentinel")
  27. newSlot("lastNodeFound")
  28. newSlot("size", 0)
  29.  
  30. init := method(
  31. node := Node clone
  32. setSentinel(node)
  33. sentinel setLeft(sentinel)
  34. sentinel setRight(sentinel)
  35. setLastNodeFound(sentinel)
  36. setRoot(sentinel)
  37. )
  38.  
  39. docSlot("atPut(aKey, aValue)", "Stores the object aValue in the Dictionary associated with the key aKey. Returns the modified Dictionary.")
  40. atPut := method(aKey, aValue,
  41. if(call message arguments size < 1,
  42. InvalidArgumentException raise("atPut requires at least 1 argument")
  43. )
  44. checkKeyValidity(aKey)
  45. result := 0
  46. node := Node clone
  47. temp := root
  48. while(temp != sentinel,
  49. node setParent(temp)
  50. result = cmp(aKey, temp key)
  51. if(result == 0, return node)
  52. if(result > 0, temp = temp right, temp = temp left)
  53. )
  54. node setKey(aKey)
  55. node setValue(aValue)
  56. node setLeft(self sentinel)
  57. node setRight(self sentinel)
  58. if(node parent,
  59. result = cmp(node key, node parent key)
  60. if(result > 0, node parent setRight(node), node parent setLeft(node))
  61. ,
  62. setRoot(node)
  63. )
  64. restoreAfterInsert(node)
  65. self setSize(self size + 1)
  66. self
  67. )
  68.  
  69. docSlot("at(aKey)", "Retrieves the object associated with the key aKey, and returns it. Raises a NotFoundException if the object was not found.")
  70. at := method(aKey,
  71. checkKeyValidity(aKey)
  72. result := 0
  73. if(cmp(aKey, lastNodeFound ?key) == 0,
  74. return lastNodeFound value
  75. ,
  76. node := root
  77. while(node != sentinel,
  78. result = cmp(aKey, node key)
  79. if(result == 0,
  80. setLastNodeFound(node)
  81. return node value
  82. )
  83. if(result < 0, node = node left, node = node right)
  84. )
  85. )
  86. NotFoundException raise("item not found")
  87. )
  88.  
  89. docSlot("atIfAbsentDo(aKey, msg)", "Retrieves the object associated with the key aKey, and returns it. If the key is not found, executes the message tree msg, and returns its result.")
  90. atIfAbsentDo := method(aKey,
  91. r := nil
  92. try(r = at(aKey)) catch(NotFoundException, r = call evalArgAt(1))
  93. r
  94. )
  95.  
  96. docSlot("atIfAbsentPut(aKey, msg)", "Searches the Dictionary for the key aKey. If the key is not found, evaluates the message msg within the context of the caller, and puts the value returned into the Dictionary associated with the key aKey. Returns the item at the key, or the result of the message.")
  97. atIfAbsentPut := method(aKey,
  98. r := nil
  99. try(r = at(aKey)) catch(NotFoundException, r = atPut(aKey, call evalArgAt(1)))
  100. r
  101. )
  102.  
  103. docSlot("removeAt(aKey)", "Removes the key->value pair from the dictionary associated with aKey. If the key is not found, a NotFoundException is raised.")
  104. removeAt := method(aKey,
  105. checkKeyValidity(aKey)
  106. node := nil
  107. if(cmp(aKey, lastNodeFound ?key) == 0,
  108. node = lastNodeFound
  109. ,
  110. node = root
  111. while(node != sentinel,
  112. result := cmp(aKey, node key)
  113. if(result == 0, break)
  114. if(result < 0, node = node left, node = node right)
  115. )
  116. if(node == sentinel, NotFoundException raise("item not found"))
  117. )
  118. delete(node)
  119. self setSize(self size - 1)
  120. node
  121. )
  122.  
  123. docSlot("empty", "Clears all items in the dictionary. Returns the emptied dictionary.")
  124. empty := method(
  125. setRoot(sentinel)
  126. setSize(0)
  127. self
  128. )
  129.  
  130. docSlot("isEmpty", "Returns true if the dictionary is empty, false otherwise.")
  131. isEmpty := method(root isNil or root == sentinel)
  132.  
  133. docSlot("hasKey(aKey)", "Returns true if the key aKey is present in the receiver, or false otherwise.")
  134. hasKey := method(aKey,
  135. checkKeyValidity(aKey)
  136. r := true
  137. try(at(aKey)) catch(NotFoundException, r = false)
  138. r
  139. )
  140.  
  141. docSlot("hasValue(aValue)", "Returns true if the object aValue is present in the receiver, or false otherwise.")
  142. hasValue := method(aValue,
  143. r := false
  144. if(self isEmpty not,
  145. self foreach(v, if(getSlot("v") == getSlot("aValue"), r = true))
  146. )
  147. r
  148. )
  149.  
  150. docSlot("keys", "Returns a LinkedList of the receivers keys.")
  151. keys := method(
  152. r := LinkedList clone
  153. if(size > 0, self foreach(k, v, r append(getSlot("k"))))
  154. r
  155. )
  156.  
  157. docSlot("values", "Returns a LinkedList of the receivers values.")
  158. values := method(
  159. r := LinkedList clone
  160. if(size > 0, self foreach(v, r append(getSlot("v"))))
  161. r
  162. )
  163.  
  164. docSlot("foreach([aKey], aValue, msg)", "For each key/value pair, sets the locals aKey to the key, and aValue to the value and executes the message msg.")
  165. foreach := method(
  166. r := nil
  167. key := call argAt(0)
  168. val := call argAt(1)
  169. body := call argAt(2)
  170. if(val isNil, InvalidArgumentException raise("'foreach' requires at least 2 arguments."))
  171. if(body isNil,
  172. key = nil
  173. val = call argAt(0)
  174. body = call argAt(1)
  175. )
  176. traverse(root, Stack clone) foreach(node,
  177. if(getSlot("key"), call sender setSlot(key name, node key))
  178. call sender setSlot(val name, node value)
  179. call sender doMessage(body)
  180. )
  181. )
  182.  
  183. docSlot("asString", "Returns a string containing the contents of the dictionary.")
  184. asString := method(
  185. s := Sequence with(self type asMutable lowercase .. "(")
  186. if(self size != 0,
  187. i := 0
  188. self foreach(k, v,
  189. s appendSeq(k asSimpleString .. " : " .. getSlot("v") asSimpleString)
  190. if(i != self size - 1, s appendSeq(", "))
  191. i = i + 1
  192. )
  193. )
  194. s appendSeq(")") asSymbol
  195. )
  196.  
  197. // Undocumented routines
  198.  
  199. restoreAfterInsert := method(x,
  200. y := nil
  201. while((x != root) and x parent isRed,
  202. if(x parent == x parent parent left,
  203. y = x parent parent right
  204. if(y and y isRed,
  205. x parent setIsRed(false)
  206. y setIsRed(false)
  207. x parent parent setIsRed(true)
  208. x = x parent parent
  209. ,
  210. if(x == x parent right,
  211. x = x parent
  212. rotateLeft(x)
  213. )
  214. x parent setIsRed(false)
  215. x parent parent setIsRed(true)
  216. rotateRight(x parent parent)
  217. )
  218. ,
  219. y = x parent parent left
  220. if(y and y isRed,
  221. x parent setIsRed(false)
  222. y setIsRed(false)
  223. x parent parent setIsRed(true)
  224. x = x parent parent
  225. ,
  226. if(x == x parent left,
  227. x = x parent
  228. rotateRight(x)
  229. )
  230. x parent setIsRed(false)
  231. x parent parent setIsRed(true)
  232. rotateLeft(x parent parent)
  233. )
  234. )
  235. )
  236. root setIsRed(false)
  237. self
  238. )
  239.  
  240. rotateLeft := method(x,
  241. y := x right
  242. x setRight(y left)
  243. if(y left != sentinel, y left setParent(x))
  244. if(y != sentinel, y setParent(x parent))
  245. if(x parent,
  246. if(x == x parent left, x parent setLeft(y), x parent setRight(y))
  247. ,
  248. setRoot(y)
  249. )
  250. y setLeft(x)
  251. if(x != sentinel, x setParent(y))
  252. self
  253. )
  254.  
  255. rotateRight := method(x,
  256. y := x left
  257. x setLeft(y right)
  258. if(y right != sentinel, y right setParent(x))
  259. if(y != sentinel, y setParent(x parent))
  260. if(x parent,
  261. if(x == x parent right, x parent setRight(y), x parent setLeft(y))
  262. ,
  263. setRoot(y)
  264. )
  265. y setRight(x)
  266. if(x != sentinel, x setParent(y))
  267. self
  268. )
  269.  
  270. delete := method(z,
  271. x := Node clone
  272. y := nil
  273. if((z left == sentinel) or z right == sentinel,
  274. y = z
  275. ,
  276. y = z right
  277. while(y left != sentinel, y = y left)
  278. )
  279. if(y left != sentinel, x = y left, x = y right)
  280. x setParent(y parent)
  281. if(y parent,
  282. if(y == y parent left, y parent setLeft(x), y parent setRight(x))
  283. ,
  284. setRoot(x)
  285. )
  286. if(y != z,
  287. z setKey(y key)
  288. z setValue(y value)
  289. )
  290. if(y isRed not, restoreAfterDelete(x))
  291. setLastNodeFound(sentinel)
  292. self
  293. )
  294.  
  295. restoreAfterDelete := method(x,
  296. y := nil
  297. while((x != root) and x isRed not,
  298. if(x == x parent left,
  299. y = x parent right
  300. if(y isRed,
  301. y setIsRed(false)
  302. x parent setIsRed(true)
  303. rotateLeft(x parent)
  304. y = x parent right
  305. )
  306. if(y left isRed not and y right isRed not,
  307. y setIsRed(true)
  308. x = x parent
  309. ,
  310. if(y right isRed not,
  311. y left setIsRed(false)
  312. y setIsRed(true)
  313. rotateRight(y)
  314. y = x parent right
  315. )
  316. y setIsRed(x parent isRed)
  317. x parent setIsRed(false)
  318. y right setIsRed(false)
  319. rotateLeft(x parent)
  320. x = root
  321. )
  322. ,
  323. y = x parent left
  324. if(y isRed,
  325. y setIsRed(false)
  326. x parent setIsRed(true)
  327. rotateRight(x parent)
  328. y = x parent left
  329. )
  330. if(y right isRed not and y left isRed not,
  331. y setIsRed(true)
  332. x = x parent
  333. ,
  334. if(y left isRed not,
  335. y right setIsRed(false)
  336. y setIsRed(true)
  337. rotateLeft(y)
  338. y = x parent left
  339. )
  340. y setIsRed(x parent isRed)
  341. x parent setIsRed(false)
  342. y left setIsRed(false)
  343. rotateRight(x parent)
  344. x = root
  345. )
  346. )
  347. )
  348. x setIsRed(false)
  349. self
  350. )
  351.  
  352. traverse := method(node, stack,
  353. if(node != node left,
  354. if(node right and node right != sentinel,
  355. traverse(node left, stack)
  356. )
  357. if(stack and node key, stack push(node))
  358. if(node right and node right != sentinel,
  359. traverse(node right, stack)
  360. )
  361. )
  362. stack
  363. )
  364.  
  365. checkKeyValidity := method(aKey,
  366. unless(aKey isKindOf(Sequence),
  367. InvalidArgumentException raise("key must be a Sequence")
  368. )
  369. if(aKey isMutable, aKey = aKey asSymbol)
  370. )
  371. )
Add Comment
Please, Sign In to add comment