Mercurial > repos > tabletprog
view modules/dict.tp @ 331:61f5b794d939
Breaking change: method call syntax now always uses the syntactic receiver as the actual receiver. This makes its behavior different from function call syntax, but solves some problems with methods being shadowed by local variables and the like.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Mar 2015 14:21:04 -0700 |
parents | eef8a5cea812 |
children | 7de6ac24eb64 |
line wrap: on
line source
{ _jsonEncode <- :dict { parts <- #[] foreach: dict :key val { //TODO: escape field names parts append: (key jsonEncode) . ":" . (jsonEncoder encode: val) } "{" . (parts join: ",") . "}" } linearWithEls <- :els { key:val <- :k v { #{ key <- k val <- v } } find <- :tofind { idx <- 0 while: { if: idx < (els length) { ((els get: idx) key: ) != tofind } else: {false} } do: { idx <- idx + 1 } if: idx < (els length) {idx} else: {-1} } #{ set <- :k v { idx <- find: k if: idx < 0 { els append: (key: k val: v) } else: { (els get: idx) val!: v } self } get <- :k { get: k withDefault: false } get:withDefault <- :k default { idx <- find: k if: idx < 0 { default } else: { (els get: idx) val } } get:elseSet <- :k :else { get: k else: { v <- else: els append: (key: k val: v) v } } get:else <- :k :else { idx <- find: k if: idx < 0 { else: } else: { (els get: idx) val } } contains? <- :k { (find: k) >= 0 } foreach <- :l { foreach: els :idx el { l: (el key) (el val) } } map <- :fun { newels <- #[] foreach: els :idx el { newels append: (key: (el key) val: (fun: (el val))) } linearWithEls: newels } length <- { els length } jsonEncode <- { _jsonEncode: self } } } _empty <- #{ empty? <- { true } } _makeBucket <- :key val { #{ empty? <- { false } k <- key v <- val = <- :other { k = other } } } #{ //requires only that keys support equality linear <- { linearWithEls: #[] } //requires that keys support equality and hash hash <- { _buckets <- #[ _empty _empty _empty _empty] _size <- 0 _hashdiffs <- #[0] #{ size <- { size } ifget:else <- :key ifpres :ifnot { basehash <- key hash notdone <- true i <- 0 ret <- _empty while: { if: notdone { i < (_hashdiffs length)}} do: { hv <- basehash + (_hashdiffs get: i) trunc <- hv % (_buckets length) if: trunc < 0 { trunc <- 0 - trunc } bucket <- _buckets get: trunc if: (bucket empty?) { notdone <- false } else: { if: bucket = key { ret <- bucket notdone <- false } } i <- i + 1 } if: (ret empty?) ifnot else: { ifpres: (ret v) } } get:else <- :key :else { ifget: key :val { val } else: else } contains? <- :key { ifget: key :_ { true } else: { false } } set <- :key val { notdone <- true basehash <- key hash i <- 0 while: { if: notdone { i < (_hashdiffs length) } } do: { hv <- basehash + (_hashdiffs get: i) trunc <- hv % (_buckets length) if: trunc < 0 { trunc <- 0 - trunc } bucket <- (_buckets get: trunc) if: (bucket empty?) { _size <- _size + 1 _buckets set: trunc (_makeBucket: key val) notdone <- false } else: { if: bucket = key { bucket v!: val notdone <- false } } i <- i + 1 } if: notdone { newsize <- (_buckets length) * 3 + 1 lastdiff <- _hashdiffs get: ((_hashdiffs length) - 1) if: lastdiff <= 0 { _hashdiffs append: 0 - lastdiff + 1 } else: { _hashdiffs append: 0 - lastdiff } newbucks <- #[] newbucks resize: newsize while: { (newbucks length) < newsize } do: { newbucks append: _empty } oldbucks <- _buckets _buckets <- newbucks _size <- 0 foreach: oldbucks :idx el { if: (not: (el empty?)) { set: (el k) (el v) } } set: key val } self } foreach <- :fun { foreach: _buckets :idx el { if: (not: (el empty?)) { fun: (el k) (el v) } } } jsonEncode <- { _jsonEncode: self } } } main <- { d <- hash d set: "foo" "bar" d set: "baz" "qux" i <- 0 while: { i < 32 } do: { d set: (string: i) "blah " . (string: i) i <- i + 1 } foreach: d :k v { print: "k: " . k . ", v: " . v . "\n" } 0 } } }