/vm/tinyrb/hash.c

http://github.com/feyeleanor/RubyGoLightly · C · 61 lines · 53 code · 7 blank · 1 comment · 6 complexity · 0b9b10272f28a1c0f5e634225531fdf0 MD5 · raw file

  1. #include "tr.h"
  2. #include "internal.h"
  3. OBJ TrHash_new(VM) {
  4. TrHash *h = TR_INIT_CORE_OBJECT(Hash);
  5. h->kh = kh_init(OBJ);
  6. return (OBJ)h;
  7. }
  8. OBJ TrHash_new2(VM, size_t n, OBJ items[]) {
  9. TrHash *h = (TrHash *)TrHash_new(vm);
  10. size_t i;
  11. int ret;
  12. for (i = 0; i < n; i+=2) {
  13. khiter_t k = kh_put(OBJ, h->kh, items[i], &ret);
  14. kh_value(h->kh, k) = items[i+1];
  15. }
  16. return (OBJ)h;
  17. }
  18. static OBJ TrHash_size(VM, OBJ self) {
  19. TrHash *h = TR_CHASH(self);
  20. return TR_INT2FIX(kh_size(h->kh));
  21. }
  22. /* TODO use Object#hash as the key */
  23. static OBJ TrHash_get(VM, OBJ self, OBJ key) {
  24. TrHash *h = TR_CHASH(self);
  25. khiter_t k = kh_get(OBJ, h->kh, key);
  26. if (k != kh_end(h->kh)) return kh_value(h->kh, k);
  27. return TR_NIL;
  28. }
  29. static OBJ TrHash_set(VM, OBJ self, OBJ key, OBJ value) {
  30. TrHash *h = TR_CHASH(self);
  31. int ret;
  32. khiter_t k = kh_put(OBJ, h->kh, key, &ret);
  33. if (!ret) kh_del(OBJ, h->kh, k);
  34. kh_value(h->kh, k) = value;
  35. return value;
  36. }
  37. static OBJ TrHash_delete(VM, OBJ self, OBJ key) {
  38. TrHash *h = TR_CHASH(self);
  39. khiter_t k = kh_get(OBJ, h->kh, key);
  40. if (k != kh_end(h->kh)) {
  41. OBJ value = kh_value(h->kh, k);
  42. kh_del(OBJ, h->kh, k);
  43. return value;
  44. }
  45. return TR_NIL;
  46. }
  47. void TrHash_init(VM) {
  48. OBJ c = TR_INIT_CORE_CLASS(Hash, Object);
  49. tr_def(c, "length", TrHash_size, 0);
  50. tr_def(c, "size", TrHash_size, 0);
  51. tr_def(c, "[]", TrHash_get, 1);
  52. tr_def(c, "[]=", TrHash_set, 2);
  53. tr_def(c, "delete", TrHash_delete, 1);
  54. }