Mercurial > repos > tabletprog
diff modules/array.tp @ 84:9811040704ac
Add support for llMessage:withVars:andCode and llProperty:withType for specifying low level code without having to stick C inside the compiler. Redo array built-in type to use this feature.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 21 Jul 2012 22:30:21 -0700 |
parents | |
children | 547153211389 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/array.tp Sat Jul 21 22:30:21 2012 -0700 @@ -0,0 +1,102 @@ +#{ + 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: 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 { + fun: acc el + } + } + + foldr:with <- :acc :fun { + idx <- length - 1 + while: {idx >= 0} do: { + fun: acc (get: idx) + } + } + + map <- :fun { + new <- #[] + foreach: self :idx el { + new append: (fun: el) + } + } + + 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 + } +}