mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
array: map() function
This commit is contained in:
parent
87813e84e9
commit
182e7071bf
@ -340,7 +340,7 @@ fn double_up(a mut []int) {
|
||||
}
|
||||
|
||||
fn double_up_v2(a mut []int) {
|
||||
for i, val in a {
|
||||
for i, _ in a {
|
||||
a[i] = a[i]*2 // or val*2, doesn't matter
|
||||
}
|
||||
}
|
||||
@ -525,26 +525,19 @@ fn test_filter() {
|
||||
}
|
||||
|
||||
fn test_map() {
|
||||
// QTODO
|
||||
/*
|
||||
println(1)
|
||||
a := [1, 2, 3, 4, 5, 6]
|
||||
b := a.map(it * 10)
|
||||
assert b.len == 6
|
||||
assert b[0] == 10
|
||||
assert b[1] == 20
|
||||
assert b[2] == 30
|
||||
c := ['v', 'is', 'awesome']
|
||||
d := c.map(it.to_upper())
|
||||
assert d[0] == 'V'
|
||||
assert d[1] == 'IS'
|
||||
assert d[2] == 'AWESOME'
|
||||
bools := c.map(it == 'v')
|
||||
assert bools.len == 3
|
||||
assert bools[0] == true
|
||||
assert bools[1] == false
|
||||
assert bools[2] == false
|
||||
*/
|
||||
nums := [1, 2, 3, 4, 5, 6]
|
||||
strs := ['v', 'is', 'awesome']
|
||||
|
||||
assert nums.map(it * 10) == [10, 20, 30, 40, 50, 60]
|
||||
assert nums.map('$it') == ['1', '2', '3', '4', '5', '6']
|
||||
assert nums.map(it % 2 == 0) == [false, true, false, true, false, true]
|
||||
|
||||
assert strs.map(it.to_upper()) == ['V', 'IS', 'AWESOME']
|
||||
assert strs.map(it == 'awesome') == [false, false, true]
|
||||
assert strs.map(7) == [7, 7, 7]
|
||||
|
||||
assert nums == [1, 2, 3, 4, 5, 6]
|
||||
assert strs == ['v', 'is', 'awesome']
|
||||
}
|
||||
|
||||
fn test_array_str() {
|
||||
|
@ -599,6 +599,7 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type {
|
||||
left_type_sym := c.table.get_type_symbol(left_type)
|
||||
method_name := call_expr.name
|
||||
// TODO: remove this for actual methods, use only for compiler magic
|
||||
// FIXME: Argument count != 1 will break these
|
||||
if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse',
|
||||
'map', 'slice'] {
|
||||
if method_name in ['filter', 'map'] {
|
||||
@ -606,24 +607,28 @@ pub fn (mut c Checker) call_method(call_expr mut ast.CallExpr) table.Type {
|
||||
mut scope := c.file.scope.innermost(call_expr.pos.pos)
|
||||
scope.update_var_type('it', array_info.elem_type)
|
||||
}
|
||||
|
||||
mut arg_type := left_type
|
||||
for arg in call_expr.args {
|
||||
c.expr(arg.expr)
|
||||
arg_type = c.expr(arg.expr)
|
||||
}
|
||||
// need to return `array_xxx` instead of `array`
|
||||
|
||||
call_expr.return_type = left_type
|
||||
if method_name == 'clone' {
|
||||
call_expr.receiver_type = left_type
|
||||
if method_name == 'map' && call_expr.args.len == 1 {
|
||||
call_expr.return_type = c.table.find_or_register_array(arg_type, 1)
|
||||
} else if method_name == 'clone' {
|
||||
// need to return `array_xxx` instead of `array`
|
||||
// in ['clone', 'str'] {
|
||||
call_expr.receiver_type = left_type.to_ptr()
|
||||
// call_expr.return_type = call_expr.receiver_type
|
||||
} else {
|
||||
call_expr.receiver_type = left_type
|
||||
}
|
||||
return left_type
|
||||
return call_expr.return_type
|
||||
} else if left_type_sym.kind == .array && method_name in ['first', 'last'] {
|
||||
info := left_type_sym.info as table.Array
|
||||
call_expr.return_type = info.elem_type
|
||||
call_expr.receiver_type = left_type
|
||||
return info.elem_type
|
||||
return call_expr.return_type
|
||||
}
|
||||
if method := c.table.type_find_method(left_type_sym, method_name) {
|
||||
if !method.is_pub && !c.is_builtin_mod && !c.pref.is_test && left_type_sym.mod != c.mod &&
|
||||
|
@ -2494,6 +2494,41 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||
g.write(')')
|
||||
}
|
||||
|
||||
// `nums.map(it % 2 == 0)`
|
||||
fn (mut g Gen) gen_map(node ast.CallExpr) {
|
||||
tmp := g.new_tmp_var()
|
||||
s := g.out.after(g.stmt_start_pos) // the already generated part of current statement
|
||||
g.out.go_back(s.len)
|
||||
// println('filter s="$s"')
|
||||
ret_typ := g.typ(node.return_type)
|
||||
//inp_typ := g.typ(node.receiver_type)
|
||||
ret_sym := g.table.get_type_symbol(node.return_type)
|
||||
inp_sym := g.table.get_type_symbol(node.receiver_type)
|
||||
ret_info := ret_sym.info as table.Array
|
||||
ret_elem_type := g.typ(ret_info.elem_type)
|
||||
inp_info := inp_sym.info as table.Array
|
||||
inp_elem_type := g.typ(inp_info.elem_type)
|
||||
if inp_sym.kind != .array {
|
||||
verror('map() requires an array')
|
||||
}
|
||||
g.writeln('')
|
||||
g.write('int ${tmp}_len = ')
|
||||
g.expr(node.left)
|
||||
g.writeln('.len;')
|
||||
g.writeln('$ret_typ $tmp = __new_array(0, ${tmp}_len, sizeof($ret_elem_type));')
|
||||
g.writeln('for (int i = 0; i < ${tmp}_len; i++) {')
|
||||
g.write('$inp_elem_type it = (($inp_elem_type*) ')
|
||||
g.expr(node.left)
|
||||
g.writeln('.data)[i];')
|
||||
g.write('$ret_elem_type ti = ')
|
||||
g.expr(node.args[0].expr) // the first arg is the filter condition
|
||||
g.writeln(';')
|
||||
g.writeln('array_push(&$tmp, &ti);')
|
||||
g.writeln('}')
|
||||
g.write(s)
|
||||
g.write(tmp)
|
||||
}
|
||||
|
||||
// `nums.filter(it % 2 == 0)`
|
||||
fn (mut g Gen) gen_filter(node ast.CallExpr) {
|
||||
tmp := g.new_tmp_var()
|
||||
|
@ -242,6 +242,10 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||
g.write('._object)')
|
||||
return
|
||||
}
|
||||
if typ_sym.kind == .array && node.name == 'map' {
|
||||
g.gen_map(node)
|
||||
return
|
||||
}
|
||||
// rec_sym := g.table.get_type_symbol(node.receiver_type)
|
||||
if typ_sym.kind == .array && node.name == 'filter' {
|
||||
g.gen_filter(node)
|
||||
|
Loading…
Reference in New Issue
Block a user