Mercurial > repos > tabletprog
view modules/array.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 | 884cd5d54c0f |
line wrap: on
line source
#{ llProperty: size withType: uint32_t llProperty: storage withType: uint32_t llProperty: data withType: ((object ptr) ptr) llMessage: get withVars: { index <- obj_int32 ptr } andCode: :index { if: (index num) >= 0 && (index num) < size { (self data) get: (index num) } else: { false } } llMessage: set withVars: { index <- obj_int32 ptr value <- object ptr } andCode: :index value { if: (index num) >= 0 && (index num) < size { data set: (index num) value } self } llMessage: foreach withVars: { clos <- lambda ptr i <- uint32_t index <- obj_int32 ptr } andCode: :clos { i <- 0 while: { i < size } do: { index <- make_object: (addr_of: obj_int32_meta) NULL 0 index num!: i ccall: clos 2 index (data get: i) i <- i + 1 } self } llMessage: append withVars: { value <- object ptr tmp <- (object ptr) ptr } andCode: :value { if: storage = size { storage <- storage * 2 tmp <- GC_REALLOC: data storage * (sizeof: (object ptr)) if: (not: tmp) { fputs: "Failed to increase array size\n" stderr exit: 1 } data <- tmp } data set: size value size <- size + 1 self } llMessage: resize withVars: { newsize <- obj_uint32 ptr tmp <- (object ptr) ptr } andCode: :newsize { self storage!: (newsize num) tmp <- GC_REALLOC: data storage * (sizeof: (object ptr)) if: (not: tmp) { fputs: "Failed to adjust array size\n" stderr exit: 1 } data <- tmp if: size > storage { size <- storage } self } llMessage: length withVars: { intret <- obj_int32 ptr } andCode: { intret <- make_object: (addr_of: obj_int32_meta) NULL 0 intret num!: size intret } fold:with <- :acc :fun { foreach: self :idx el { acc <- fun: acc el } acc } foldr:with <- :acc :fun { idx <- length - 1 while: {idx >= 0} do: { acc <- fun: acc (get: idx) idx <- idx - 1 } acc } map <- :fun { new <- #[] foreach: self :idx el { new append: (fun: el) } new } filter <- :fun { new <- #[] foreach: self :idx el { if: (fun: el) { new append: el } } new } find:withDefault <- :pred :default{ idx <- 0 l <- length ret <- default while: {idx < l} do: { v <- get: idx if: (pred: v) { ret <- #{ key <- idx value <- v } idx <- l } } ret } sort <- { n <- length tmp <- #[] tmp resize: n while: { (tmp length) < n} do: { tmp append: false } src <- self dst <- tmp merge <- :lStart rStart rEnd { dstIdx <- lStart left <- lStart right <- rStart while: { dstIdx < rEnd } do: { if: left < rStart && (right >= rEnd || (src get: left) <= (src get: right)) { dst set: dstIdx (src get: left) left <- left + 1 } else: { dst set: dstIdx (src get: right) right <- right + 1 } dstIdx <- dstIdx + 1 } } needsCopy? <- false subSize <- 1 while: { subSize < n} do: { group <- subSize * 2 i <- 0 while: { i < n} do: { right <- i + subSize end <- i + group if: right > n { right <- n end <- n } else: { if: end > n { end <- n } } merge: i right end i <- i + group } tmp <- dst dst <- src src <- tmp needsCopy? <- not: needsCopy? subSize <- subSize + subSize } if: needsCopy? { foreach: src :index val { self set: index val } } } join <- :sep { if: length > 0 { str <- string: (get: 0) idx <- 1 l <- length while: { idx < l } do: { str <- str . sep . (get: idx) idx <- idx + 1 } str } else: { "" } } jsonEncode <- { parts <- map: :el { jsonEncoder encode: el } "[" . (parts join: ",") . "]" } }