v.gen.js: fix for array filter, add more tests and other fixes (#10999)
							parent
							
								
									ab6ab519e6
								
							
						
					
					
						commit
						a7ca051016
					
				|  | @ -138,7 +138,7 @@ pub fn (a array) str() string { | |||
| #array.prototype[Symbol.iterator] = function () { return this.arr[Symbol.iterator](); } | ||||
| #array.prototype.entries = function () { return this.arr.entries(); } | ||||
| #array.prototype.map = function(callback) { return this.arr.map(callback); } | ||||
| #array.prototype.filter = function(callback) { return this.arr.filter(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; } }) | ||||
| // delete deletes array element at index `i`.
 | ||||
| pub fn (mut a array) delete(i int) { | ||||
|  | @ -160,3 +160,23 @@ pub fn (mut a array) prepend(val voidptr) { | |||
| 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 | ||||
| } | ||||
| 
 | ||||
| #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 of a)  { | ||||
| 	#accum_ = iter(accum_, a.arr[i]) | ||||
| 	#} | ||||
| 
 | ||||
| 	return accum_ | ||||
| } | ||||
|  |  | |||
|  | @ -263,6 +263,7 @@ struct BuiltinPrototypeConfig { | |||
| 	value_of      string = 'this.val' | ||||
| 	to_string     string = 'this.val.toString()' | ||||
| 	eq            string = 'this.val === other.val' | ||||
| 	to_jsval      string = 'this' | ||||
| 	extras        string | ||||
| 	has_strfn     bool | ||||
| } | ||||
|  | @ -284,6 +285,7 @@ fn (mut g JsGen) gen_builtin_prototype(c BuiltinPrototypeConfig) { | |||
| 	g.writeln('valueOf() { return $c.value_of },') | ||||
| 	g.writeln('toString() { return $c.to_string },') | ||||
| 	g.writeln('eq(other) { return $c.eq },') | ||||
| 	g.writeln('\$toJS() { return $c.to_jsval }, ') | ||||
| 	if c.has_strfn { | ||||
| 		g.writeln('str() { return new string(this.toString()) }') | ||||
| 	} | ||||
|  | @ -306,6 +308,7 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					value_of: 'this.val | 0' | ||||
| 					to_string: 'this.valueOf().toString()' | ||||
| 					eq: 'this.valueOf() === other.valueOf()' | ||||
| 					to_jsval: '+this' | ||||
| 				) | ||||
| 			} | ||||
| 			'byte' { | ||||
|  | @ -316,18 +319,22 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					value_of: 'this.val | 0' | ||||
| 					to_string: 'new string(this.val + "")' | ||||
| 					eq: 'this.valueOf() === other.valueOf()' | ||||
| 					to_jsval: '+this' | ||||
| 				) | ||||
| 			} | ||||
| 			'f32', 'f64', 'float_literal' { | ||||
| 				g.gen_builtin_prototype( | ||||
| 					typ_name: typ_name | ||||
| 					default_value: 'new Number(0)' | ||||
| 					to_jsval: '+this' | ||||
| 				) | ||||
| 			} | ||||
| 			'bool' { | ||||
| 				g.gen_builtin_prototype( | ||||
| 					constructor: 'this.val = +val !== 0' | ||||
| 					typ_name: typ_name | ||||
| 					default_value: 'new Boolean(false)' | ||||
| 					to_jsval: '+this != 0' | ||||
| 				) | ||||
| 			} | ||||
| 			'string' { | ||||
|  | @ -340,6 +347,7 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					to_string: 'this.str' | ||||
| 					eq: 'this.str === other.str' | ||||
| 					has_strfn: false | ||||
| 					to_jsval: 'this.str' | ||||
| 				) | ||||
| 			} | ||||
| 			'map' { | ||||
|  | @ -348,9 +356,10 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					val_name: 'map' | ||||
| 					default_value: 'new Map()' | ||||
| 					constructor: 'this.map = map' | ||||
| 					value_of: 'this.map' | ||||
| 					value_of: 'this' | ||||
| 					to_string: 'this.map.toString()' | ||||
| 					eq: 'vEq(this, other)' | ||||
| 					to_jsval: 'this.map' | ||||
| 				) | ||||
| 			} | ||||
| 			'array' { | ||||
|  | @ -359,9 +368,10 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					val_name: 'arr' | ||||
| 					default_value: 'new Array()' | ||||
| 					constructor: 'this.arr = arr' | ||||
| 					value_of: 'this.arr' | ||||
| 					value_of: 'this' | ||||
| 					to_string: 'JSON.stringify(this.arr.map(it => it.valueOf()))' | ||||
| 					eq: 'vEq(this, other)' | ||||
| 					to_jsval: 'this.arr' | ||||
| 				) | ||||
| 			} | ||||
| 			'any' { | ||||
|  | @ -373,6 +383,7 @@ fn (mut g JsGen) gen_builtin_type_defs() { | |||
| 					value_of: 'this.val' | ||||
| 					to_string: '"&" + this.val' | ||||
| 					eq: 'this == other' // compare by ptr
 | ||||
| 					to_jsval: 'this.val.\$toJS()' | ||||
| 				) | ||||
| 			} | ||||
| 			else {} | ||||
|  |  | |||
|  | @ -5,8 +5,8 @@ function vEq(a, b) { | |||
| 
 | ||||
| 	if (a && b && typeof a == 'object' && typeof b == 'object') { | ||||
| 		if (a.constructor !== b.constructor) return false; | ||||
| 		a = a.valueOf(); | ||||
| 		b = b.valueOf(); | ||||
| 		a = a.$toJS(); | ||||
| 		b = b.$toJS(); | ||||
| 		var length, i, keys; | ||||
| 		if (Array.isArray(a)) { | ||||
| 			length = a.length; | ||||
|  |  | |||
|  | @ -1079,6 +1079,7 @@ fn (mut g JsGen) gen_for_c_stmt(it ast.ForCStmt) { | |||
| 		g.write('; ') | ||||
| 	} | ||||
| 	if it.has_cond { | ||||
| 		g.write('+') // convert to number or boolean
 | ||||
| 		g.expr(it.cond) | ||||
| 	} | ||||
| 	g.write('; ') | ||||
|  | @ -1174,6 +1175,7 @@ fn (mut g JsGen) gen_for_stmt(it ast.ForStmt) { | |||
| 	if it.is_inf { | ||||
| 		g.write('true') | ||||
| 	} else { | ||||
| 		g.write('+') // convert expr to number or boolean
 | ||||
| 		g.expr(it.cond) | ||||
| 	} | ||||
| 	g.writeln(') {') | ||||
|  | @ -1325,6 +1327,7 @@ fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) { | |||
| 	// offering similar performance
 | ||||
| 	g.write('new array(') | ||||
| 	g.inc_indent() | ||||
| 
 | ||||
| 	if it.has_len { | ||||
| 		t1 := g.new_tmp_var() | ||||
| 		t2 := g.new_tmp_var() | ||||
|  | @ -1349,6 +1352,31 @@ fn (mut g JsGen) gen_array_init_expr(it ast.ArrayInit) { | |||
| 		g.writeln('return $t1;') | ||||
| 		g.dec_indent() | ||||
| 		g.write('})()') | ||||
| 	} else if it.is_fixed && it.exprs.len == 1 { | ||||
| 		// [100]byte codegen
 | ||||
| 		t1 := g.new_tmp_var() | ||||
| 		t2 := g.new_tmp_var() | ||||
| 		g.writeln('(function() {') | ||||
| 		g.inc_indent() | ||||
| 		g.writeln('const $t1 = [];') | ||||
| 		g.write('for (let $t2 = 0; $t2 < ') | ||||
| 		g.expr(it.exprs[0]) | ||||
| 		g.writeln('; $t2++) {') | ||||
| 		g.inc_indent() | ||||
| 		g.write('${t1}.push(') | ||||
| 		if it.has_default { | ||||
| 			g.expr(it.default_expr) | ||||
| 		} else { | ||||
| 			// Fill the array with the default values for its type
 | ||||
| 			t := g.to_js_typ_val(it.elem_type) | ||||
| 			g.write(t) | ||||
| 		} | ||||
| 		g.writeln(');') | ||||
| 		g.dec_indent() | ||||
| 		g.writeln('};') | ||||
| 		g.writeln('return $t1;') | ||||
| 		g.dec_indent() | ||||
| 		g.write('})()') | ||||
| 	} else { | ||||
| 		g.gen_array_init_values(it.exprs) | ||||
| 	} | ||||
|  | @ -1549,7 +1577,9 @@ fn (mut g JsGen) gen_if_expr(node ast.IfExpr) { | |||
| 				g.write(' : ') | ||||
| 			} | ||||
| 			if i < node.branches.len - 1 || !node.has_else { | ||||
| 				g.write('(') | ||||
| 				g.expr(branch.cond) | ||||
| 				g.write(')') | ||||
| 				g.write('.valueOf()') | ||||
| 				g.write(' ? ') | ||||
| 			} | ||||
|  | @ -1570,7 +1600,9 @@ fn (mut g JsGen) gen_if_expr(node ast.IfExpr) { | |||
| 						if '$branch.cond' == 'js' { | ||||
| 							g.write('true') | ||||
| 						} else { | ||||
| 							g.write('(') | ||||
| 							g.expr(branch.cond) | ||||
| 							g.write(')') | ||||
| 							g.write('.valueOf()') | ||||
| 						} | ||||
| 						g.writeln(') {') | ||||
|  | @ -1578,7 +1610,9 @@ fn (mut g JsGen) gen_if_expr(node ast.IfExpr) { | |||
| 				} | ||||
| 			} else if i < node.branches.len - 1 || !node.has_else { | ||||
| 				g.write('} else if (') | ||||
| 				g.write('(') | ||||
| 				g.expr(branch.cond) | ||||
| 				g.write(')') | ||||
| 				g.write('.valueOf()') | ||||
| 				g.writeln(') {') | ||||
| 			} else if i == node.branches.len - 1 && node.has_else { | ||||
|  | @ -1608,7 +1642,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) { | |||
| 	if expr.index is ast.RangeExpr { | ||||
| 		g.expr(expr.left) | ||||
| 		if expr.left_type.is_ptr() { | ||||
| 			g.write('.val') | ||||
| 			g.write('.valueOf()') | ||||
| 		} | ||||
| 		g.write('.slice(') | ||||
| 		if expr.index.has_low { | ||||
|  | @ -1622,7 +1656,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) { | |||
| 		} else { | ||||
| 			g.expr(expr.left) | ||||
| 			if expr.left_type.is_ptr() { | ||||
| 				g.write('.val') | ||||
| 				g.write('.valueOf()') | ||||
| 			} | ||||
| 			g.write('.length') | ||||
| 		} | ||||
|  | @ -1649,7 +1683,7 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) { | |||
| 			g.write('new byte(') | ||||
| 			g.expr(expr.left) | ||||
| 			if expr.left_type.is_ptr() { | ||||
| 				g.write('.val') | ||||
| 				g.write('.valueOf()') | ||||
| 			} | ||||
| 			g.write('.str.charCodeAt(') | ||||
| 			g.expr(expr.index) | ||||
|  | @ -1659,10 +1693,10 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) { | |||
| 		// TODO Does this cover all cases?
 | ||||
| 		g.expr(expr.left) | ||||
| 		if expr.left_type.is_ptr() { | ||||
| 			g.write('.val') | ||||
| 			g.write('.valueOf()') | ||||
| 		} | ||||
| 		g.write('.arr') | ||||
| 		g.write('[') | ||||
| 		g.write('[+') | ||||
| 		g.cast_stack << ast.int_type_idx | ||||
| 		g.expr(expr.index) | ||||
| 		g.cast_stack.delete_last() | ||||
|  | @ -1682,7 +1716,10 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { | |||
| 	if it.op == .eq || it.op == .ne { | ||||
| 		// Shallow equatables
 | ||||
| 		if l_sym.kind in js.shallow_equatables && r_sym.kind in js.shallow_equatables { | ||||
| 			// wrap left expr in parens so binary operations will work correctly.
 | ||||
| 			g.write('(') | ||||
| 			g.expr(it.left) | ||||
| 			g.write(')') | ||||
| 			g.write('.eq(') | ||||
| 			g.cast_stack << int(l_sym.kind) | ||||
| 			g.expr(it.right) | ||||
|  | @ -1713,7 +1750,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { | |||
| 		} else if r_sym.kind == .string { | ||||
| 			g.write('.str.includes(') | ||||
| 		} else { | ||||
| 			g.write('.arr.includes(') | ||||
| 			g.write('.\$includes(') | ||||
| 		} | ||||
| 		g.expr(it.left) | ||||
| 		if l_sym.kind == .string { | ||||
|  | @ -1728,14 +1765,15 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { | |||
| 		is_arithmetic := it.op in [token.Kind.plus, .minus, .mul, .div, .mod] | ||||
| 		mut needs_cast := is_arithmetic && it.left_type != it.right_type | ||||
| 		mut greater_typ := 0 | ||||
| 		if needs_cast { | ||||
| 		// todo(playX): looks like this cast is always required to perform .eq operation on types.
 | ||||
| 		if true || needs_cast { | ||||
| 			greater_typ = g.greater_typ(it.left_type, it.right_type) | ||||
| 			if g.cast_stack.len > 0 { | ||||
| 				needs_cast = g.cast_stack.last() != greater_typ | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if needs_cast { | ||||
| 		if true || needs_cast { | ||||
| 			if g.ns.name == 'builtin' { | ||||
| 				g.write('new ') | ||||
| 			} | ||||
|  | @ -1746,7 +1784,7 @@ fn (mut g JsGen) gen_infix_expr(it ast.InfixExpr) { | |||
| 		g.write(' $it.op ') | ||||
| 		g.expr(it.right) | ||||
| 
 | ||||
| 		if needs_cast { | ||||
| 		if true || needs_cast { | ||||
| 			g.cast_stack.delete_last() | ||||
| 			g.write(')') | ||||
| 		} | ||||
|  |  | |||
|  | @ -9,8 +9,8 @@ function vEq(a, b) { | |||
| 
 | ||||
| 	if (a && b && typeof a == 'object' && typeof b == 'object') { | ||||
| 		if (a.constructor !== b.constructor) return false; | ||||
| 		a = a.valueOf(); | ||||
| 		b = b.valueOf(); | ||||
| 		a = a.\$toJS(); | ||||
| 		b = b.\$toJS(); | ||||
| 		var length, i, keys; | ||||
| 		if (Array.isArray(a)) { | ||||
| 			length = a.length; | ||||
|  |  | |||
|  | @ -108,4 +108,57 @@ abc | |||
| 6 | ||||
| 1 | ||||
| 4 | ||||
| 6 | ||||
| 6 | ||||
| [4,3,2,1] | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| 0 | ||||
| [0,0,0,0] | ||||
| [0,7,0,0] | ||||
| 0 | ||||
| [2,4,6,8,10,12,14,16,18,20] | ||||
| [2,4,6,8,10,12,14,16,18,20] | ||||
| [2,4,6,8,10] | ||||
| 2 | ||||
| [1,2] | ||||
| 0 | ||||
| 1 | ||||
| -1 | ||||
| 0 | ||||
| 3 | ||||
| -1 | ||||
| 0 | ||||
| 2 | ||||
| -1 | ||||
| 1 | ||||
| 2 | ||||
| -1 | ||||
| 2 | ||||
| 3 | ||||
| 1 | ||||
| 3 | ||||
| 6 | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| true | ||||
| 0 | ||||
| 0 | ||||
| 0 | ||||
| 0 | ||||
| 0 | ||||
| [2,4,6] | ||||
| ["is","awesome"] | ||||
| [2,3,4,6,8,9,10] | ||||
| [4,5,6] | ||||
| [5,10] | ||||
|  |  | |||
|  | @ -6,6 +6,42 @@ struct Kkk { | |||
| 	q []Chunk | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
| 	c_n = 5 | ||||
| ) | ||||
| 
 | ||||
| fn filter_test_helper_1(a int) bool { | ||||
| 	return a > 3 | ||||
| } | ||||
| 
 | ||||
| fn sum(prev int, curr int) int { | ||||
| 	return prev + curr | ||||
| } | ||||
| 
 | ||||
| fn sub(prev int, curr int) int { | ||||
| 	return prev - curr | ||||
| } | ||||
| 
 | ||||
| struct Foooj { | ||||
| 	a [5]int // c_n
 | ||||
| } | ||||
| 
 | ||||
| fn double_up(mut a []int) { | ||||
| 	for i := 0; i < a.len; i++ { | ||||
| 		a[i] = a[i] * 2 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn double_up_v2(mut a []int) { | ||||
| 	for i, _ in a { | ||||
| 		a[i] = a[i] * 2 // or val*2, doesn't matter
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| fn modify(mut numbers []int) { | ||||
| 	numbers[0] = 777 | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	{ | ||||
| 		// test pointer
 | ||||
|  | @ -262,6 +298,7 @@ fn main() { | |||
| 		} | ||||
| 	} | ||||
| 	{ | ||||
| 		// todo(playX): deep repeat does not yet work.
 | ||||
| 		/* | ||||
| 		// test deep repeat
 | ||||
| 		mut a3 := [[[1, 1], [2, 2], [3, 3]], [[4, 4], [5, 5], [6, 6]]] | ||||
|  | @ -319,4 +356,175 @@ fn main() { | |||
| 		println(a[3]) | ||||
| 		println(a[5]) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test reverse
 | ||||
| 		a := [1, 2, 3, 4] | ||||
| 		b := ['test', 'array', 'reverse'] | ||||
| 		c := a.reverse() | ||||
| 		println(c) | ||||
| 		d := b.reverse() | ||||
| 		for i, _ in c { | ||||
| 			println(c[i] == a[a.len - i - 1]) | ||||
| 		} | ||||
| 		for i, _ in d { | ||||
| 			println(d[i] == b[b.len - i - 1]) | ||||
| 		} | ||||
| 		e := []int{} | ||||
| 		f := e.reverse() | ||||
| 		println(f.len) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test fixed
 | ||||
| 		mut nums := [4]int{} | ||||
| 		// x := nums[1..3]
 | ||||
| 		// assert x.len == 2
 | ||||
| 
 | ||||
| 		println(nums) | ||||
| 		nums[1] = 7 | ||||
| 		println(nums) | ||||
| 		nums2 := [5]int{} // c_n
 | ||||
| 		println(nums2[c_n - 1]) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test mut slice
 | ||||
| 		/* | ||||
| 		todo(playX): slices do not work yet. We have to implement custom wrapper for them. | ||||
| 		mut n := [1, 2, 3] | ||||
| 		// modify(mut n)
 | ||||
| 		modify(mut n[..2]) | ||||
| 		assert n[0] == 777 | ||||
| 		modify(mut n[2..]) | ||||
| 		assert n[2] == 777 | ||||
| 		println(n) | ||||
| 		*/ | ||||
| 	} | ||||
| 	{ | ||||
| 		// test mut arg
 | ||||
| 		mut arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||||
| 		double_up(mut arr) | ||||
| 		println(arr.str()) | ||||
| 		arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||||
| 		double_up_v2(mut arr) | ||||
| 		println(arr.str()) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test doubling
 | ||||
| 		mut nums := [1, 2, 3, 4, 5] | ||||
| 		for i in 0 .. nums.len { | ||||
| 			nums[i] *= 2 | ||||
| 		} | ||||
| 		println(nums.str()) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test single element
 | ||||
| 
 | ||||
| 		mut a := [1] | ||||
| 		a << 2 | ||||
| 		println(a.len) | ||||
| 		assert a[0] == 1 | ||||
| 		assert a[1] == 2 | ||||
| 		println(a) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test find index
 | ||||
| 
 | ||||
| 		// string
 | ||||
| 		a := ['v', 'is', 'great'] | ||||
| 		println(a.index('v')) | ||||
| 		println(a.index('is')) | ||||
| 		println(a.index('gre')) | ||||
| 		// int
 | ||||
| 		b := [1, 2, 3, 4] | ||||
| 		println(b.index(1)) | ||||
| 		println(b.index(4)) | ||||
| 		println(b.index(5)) | ||||
| 		// byte
 | ||||
| 		c := [0x22, 0x33, 0x55] | ||||
| 		println(c.index(0x22)) | ||||
| 		println(c.index(0x55)) | ||||
| 		println(c.index(0x99)) | ||||
| 		// char
 | ||||
| 		d := [`a`, `b`, `c`] | ||||
| 		println(d.index(`b`)) | ||||
| 		println(d.index(`c`)) | ||||
| 		println(d.index(`u`)) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test multi
 | ||||
| 
 | ||||
| 		a := [[1, 2, 3], [4, 5, 6]] | ||||
| 		println(a.len) | ||||
| 		println(a[0].len) | ||||
| 		println(a[0][0]) | ||||
| 		println(a[0][2]) | ||||
| 		println(a[1][2]) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test in
 | ||||
| 		a := [1, 2, 3] | ||||
| 		println(1 in a) | ||||
| 		println(2 in a) | ||||
| 		println(3 in a) | ||||
| 		println(!(4 in a)) | ||||
| 		println(!(0 in a)) | ||||
| 		println(0 !in a) | ||||
| 		println(4 !in a) | ||||
| 		b := [1, 4, 0] | ||||
| 		c := [3, 6, 2, 0] | ||||
| 		println(0 in b) | ||||
| 		println(0 in c) | ||||
| 	} | ||||
| 	{ | ||||
| 		// test reduce
 | ||||
| 		a := [1, 2, 3, 4, 5] | ||||
| 		b := a.reduce(sum, 0) | ||||
| 		c := a.reduce(sum, 5) | ||||
| 		d := a.reduce(sum, -1) | ||||
| 		println(b) | ||||
| 		println(c) | ||||
| 		println(d) | ||||
| 		e := [1, 2, 3] | ||||
| 		f := e.reduce(sub, 0) | ||||
| 		g := e.reduce(sub, -1) | ||||
| 		println(f) | ||||
| 		println(g) | ||||
| 	} | ||||
| 	{ | ||||
| 		a := [1, 2, 3, 4, 5, 6] | ||||
| 		b := a.filter(it % 2 == 0) | ||||
| 		println(b) | ||||
| 
 | ||||
| 		c := ['v', 'is', 'awesome'] | ||||
| 		d := c.filter(it.len > 1) | ||||
| 		println(d) | ||||
| 		assert d[0] == 'is' | ||||
| 		assert d[1] == 'awesome' | ||||
| 		////////
 | ||||
| 		arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||||
| 		println(arr.filter(it % 2 == 0 || it % 3 == 0)) | ||||
| 
 | ||||
| 		mut mut_arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | ||||
| 		mut_arr = mut_arr.filter(it < 4) | ||||
| 		assert mut_arr.len == 3 | ||||
| 		println(a.filter(filter_test_helper_1)) | ||||
| 		println([1, 5, 10].filter(filter_test_helper_1)) | ||||
| 	} | ||||
| 	{ | ||||
| 		// todo(playX): RUNTIME ERROR: Invalid memory access
 | ||||
| 		/* | ||||
| 		// test anon fn filter
 | ||||
| 		filter_num := fn (i int) bool { | ||||
| 			return i % 2 == 0 | ||||
| 		} | ||||
| 		assert [1, 2, 3, 4, 5].filter(filter_num) == [2, 4] | ||||
| 		*/ | ||||
| 	} | ||||
| 	{ | ||||
| 		/* | ||||
| 		a := [1, 2, 3, 4].filter(fn (i int) bool { | ||||
| 			return i % 2 == 0 | ||||
| 		}) | ||||
| 		assert a == [2, 4] | ||||
| 		*/ | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue