array: map() function
parent
87813e84e9
commit
182e7071bf
|
@ -340,7 +340,7 @@ fn double_up(a mut []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn double_up_v2(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
|
a[i] = a[i]*2 // or val*2, doesn't matter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,26 +525,19 @@ fn test_filter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_map() {
|
fn test_map() {
|
||||||
// QTODO
|
nums := [1, 2, 3, 4, 5, 6]
|
||||||
/*
|
strs := ['v', 'is', 'awesome']
|
||||||
println(1)
|
|
||||||
a := [1, 2, 3, 4, 5, 6]
|
assert nums.map(it * 10) == [10, 20, 30, 40, 50, 60]
|
||||||
b := a.map(it * 10)
|
assert nums.map('$it') == ['1', '2', '3', '4', '5', '6']
|
||||||
assert b.len == 6
|
assert nums.map(it % 2 == 0) == [false, true, false, true, false, true]
|
||||||
assert b[0] == 10
|
|
||||||
assert b[1] == 20
|
assert strs.map(it.to_upper()) == ['V', 'IS', 'AWESOME']
|
||||||
assert b[2] == 30
|
assert strs.map(it == 'awesome') == [false, false, true]
|
||||||
c := ['v', 'is', 'awesome']
|
assert strs.map(7) == [7, 7, 7]
|
||||||
d := c.map(it.to_upper())
|
|
||||||
assert d[0] == 'V'
|
assert nums == [1, 2, 3, 4, 5, 6]
|
||||||
assert d[1] == 'IS'
|
assert strs == ['v', 'is', 'awesome']
|
||||||
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
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_array_str() {
|
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)
|
left_type_sym := c.table.get_type_symbol(left_type)
|
||||||
method_name := call_expr.name
|
method_name := call_expr.name
|
||||||
// TODO: remove this for actual methods, use only for compiler magic
|
// 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',
|
if left_type_sym.kind == .array && method_name in ['filter', 'clone', 'repeat', 'reverse',
|
||||||
'map', 'slice'] {
|
'map', 'slice'] {
|
||||||
if method_name in ['filter', 'map'] {
|
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)
|
mut scope := c.file.scope.innermost(call_expr.pos.pos)
|
||||||
scope.update_var_type('it', array_info.elem_type)
|
scope.update_var_type('it', array_info.elem_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mut arg_type := left_type
|
||||||
for arg in call_expr.args {
|
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
|
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'] {
|
// in ['clone', 'str'] {
|
||||||
call_expr.receiver_type = left_type.to_ptr()
|
call_expr.receiver_type = left_type.to_ptr()
|
||||||
// call_expr.return_type = call_expr.receiver_type
|
// 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'] {
|
} else if left_type_sym.kind == .array && method_name in ['first', 'last'] {
|
||||||
info := left_type_sym.info as table.Array
|
info := left_type_sym.info as table.Array
|
||||||
call_expr.return_type = info.elem_type
|
call_expr.return_type = info.elem_type
|
||||||
call_expr.receiver_type = left_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 := 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 &&
|
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(')')
|
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)`
|
// `nums.filter(it % 2 == 0)`
|
||||||
fn (mut g Gen) gen_filter(node ast.CallExpr) {
|
fn (mut g Gen) gen_filter(node ast.CallExpr) {
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
|
|
|
@ -242,6 +242,10 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
g.write('._object)')
|
g.write('._object)')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if typ_sym.kind == .array && node.name == 'map' {
|
||||||
|
g.gen_map(node)
|
||||||
|
return
|
||||||
|
}
|
||||||
// rec_sym := g.table.get_type_symbol(node.receiver_type)
|
// rec_sym := g.table.get_type_symbol(node.receiver_type)
|
||||||
if typ_sym.kind == .array && node.name == 'filter' {
|
if typ_sym.kind == .array && node.name == 'filter' {
|
||||||
g.gen_filter(node)
|
g.gen_filter(node)
|
||||||
|
|
Loading…
Reference in New Issue