module builtin struct array { arr JS.Array pub: len int cap int } #function flatIntoArray(target, source, sourceLength, targetIndex, depth) { #"use strict"; # #for (var sourceIndex = 0; sourceIndex < sourceLength; ++sourceIndex) { #if (sourceIndex in source) { #var element = source[sourceIndex]; #if (depth > 0 && Array.isArray(element)) #targetIndex = flatIntoArray(target, element, element.length, targetIndex, depth - 1); #else { #target[targetIndex] = element; #++targetIndex; #} #} #} #return targetIndex; #} #function flatArray(target,depth) { #var array = target #var length = array.length; #var depthNum = 1; # #if (depth !== undefined) #depthNum = +depth # #var result = [] # #flatIntoArray(result, array, length, 0, depthNum); #return result; #} [unsafe] pub fn (a array) repeat_to_depth(count int, depth int) array { if count < 0 { panic('array.repeat: count is negative: $count') } mut arr := empty_array() #let tmp = new Array(a.arr.length * +count); #tmp.fill(a.arr); # #arr.arr = flatArray(tmp,depth+1); return arr } // last returns the last element of the array. pub fn (a array) last() voidptr { mut res := voidptr(0) #res = a.arr[a.len-1]; return res } fn (a array) get(ix int) voidptr { mut result := voidptr(0) #result = a.arr[ix] return result } pub fn (a array) repeat(count int) array { unsafe { return a.repeat_to_depth(count, 0) } } fn empty_array() array { mut arr := array{} #arr = new array([]) return arr } fn (a &array) set_len(i int) { #a.arr.length=i } pub fn (mut a array) sort_with_compare(compare voidptr) { #a.val.arr.sort(compare) } pub fn (mut a array) sort() { #a.val.arr.sort($sortComparator) } pub fn (a array) index(v string) int { for i in 0 .. a.len { #if (a.arr[i].toString() == v.toString()) { return i } } return -1 } pub fn (a array) slice(start int, end int) array { mut result := a #result = new array(a.arr.slice(start,end)) return result } pub fn (mut a array) insert(i int, val voidptr) { #a.val.arr.splice(i,0,val) } pub fn (mut a array) insert_many(i int, val voidptr, size int) { #a.val.arr.splice(i,0,...val.slice(0,+size)) } pub fn (mut a array) join(separator string) string { mut res := '' #res = new string(a.val.arr.join(separator +'')); return res } fn (a array) push(val voidptr) { #a.arr.push(val) } #array.prototype[Symbol.iterator] = function () { return this.arr[Symbol.iterator](); } #array.prototype.entries = function () { let result = []; for (const [key,val] of this.arr.entries()) { result.push([new int(key), val]); } return result[Symbol.iterator](); } #array.prototype.map = function(callback) { return new array(this.arr.map(callback)); } #array.prototype.filter = function(callback) { return new array(this.arr.filter( function (it) { return (+callback(it)) != 0; } )); } #Object.defineProperty(array.prototype,'cap',{ get: function () { return this.len; } }) #array.prototype.any = function (value) { #let val ;if (typeof value == 'function') { val = function (x) { return value(x); } } else { val = function (x) { return vEq(x,value); } } #for (let i = 0;i < this.arr.length;i++) #if (val(this.arr[i])) #return true; # #return false; #} #array.prototype.all = function (value) { #let val ;if (typeof value == 'function') { val = function (x) { return value(x); } } else { val = function (x) { return vEq(x,value); } } #for (let i = 0;i < this.arr.length;i++) #if (!val(this.arr[i])) #return false; # #return true; #} // delete deletes array element at index `i`. pub fn (mut a array) delete(i int) { a.delete_many(i, 1) } // delete_many deletes `size` elements beginning with index `i` pub fn (mut a array) delete_many(i int, size int) { #a.val.arr.splice(i.valueOf(),size.valueOf()) } // prepend prepends one value to the array. pub fn (mut a array) prepend(val voidptr) { a.insert(0, val) } // prepend_many prepends another array to this array. [unsafe] pub fn (mut a array) prepend_many(val voidptr, size int) { unsafe { a.insert_many(0, val, size) } } pub fn (a array) reverse() array { mut res := array{} #res.arr = Array.from(a.arr).reverse() return res } pub fn (mut a array) reverse_in_place() { #a.val.arr.reverse() } #array.prototype.$includes = function (elem) { return this.arr.find(function(e) { return vEq(elem,e); }) !== undefined;} // reduce executes a given reducer function on each element of the array, // resulting in a single output value. pub fn (a array) reduce(iter fn (int, int) int, accum_start int) int { mut accum_ := accum_start #for (let i = 0;i < a.arr.length;i++) { #accum_ = iter(accum_, a.arr[i]) #} return accum_ } pub fn (mut a array) pop() voidptr { mut res := voidptr(0) #res = a.val.arr.pop() return res } pub fn (a array) first() voidptr { mut res := voidptr(0) #res = a.arr[0] return res } #array.prototype.toString = function () { #let res = "[" #for (let i = 0; i < this.arr.length;i++) { #res += this.arr[i].toString(); #if (i != this.arr.length-1) #res += ', ' #} #res += ']' #return res; # #} pub fn (a array) contains(key voidptr) bool { #for (let i = 0; i < a.arr.length;i++) #if (vEq(a.arr[i],key)) return new bool(true); return false } // delete_last effectively removes last element of an array. pub fn (mut a array) delete_last() { #a.val.arr.pop(); } [unsafe] pub fn (a array) free() { } // todo: once (a []byte) will work rewrite this pub fn (a array) bytestr() string { res := '' #a.arr.forEach((item) => res.str += String.fromCharCode(+item)) return res } /* pub fn (a []string) str() string { mut sb := strings.new_builder(a.len * 3) sb.write_string('[') for i in 0 .. a.len { val := a[i] sb.write_string("'") sb.write_string(val) sb.write_string("'") if i < a.len - 1 { sb.write_string(', ') } } sb.write_string(']') res := sb.str() return res }*/