builtin: implement array.pop()
parent
de0b96f52c
commit
cf7d03bda6
|
@ -256,6 +256,22 @@ pub fn (a array) last() voidptr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// array.pop returns the last element of the array, and removes it
|
||||||
|
pub fn (mut a array) pop() voidptr {
|
||||||
|
// in a sense, this is the opposite of `a << x`
|
||||||
|
$if !no_bounds_checking? {
|
||||||
|
if a.len == 0 {
|
||||||
|
panic('array.pop: array is empty')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_len := a.len - 1
|
||||||
|
last_elem := unsafe { byteptr(a.data) + (new_len) * a.element_size }
|
||||||
|
a.len = new_len
|
||||||
|
// NB: a.cap is not changed here *on purpose*, so that
|
||||||
|
// further << ops on that array will be more efficient.
|
||||||
|
return memdup(last_elem, a.element_size)
|
||||||
|
}
|
||||||
|
|
||||||
// array.slice returns an array using the same buffer as original array
|
// array.slice returns an array using the same buffer as original array
|
||||||
// but starting from the `start` element and ending with the element before
|
// but starting from the `start` element and ending with the element before
|
||||||
// the `end` element of the original array with the length and capacity
|
// the `end` element of the original array with the length and capacity
|
||||||
|
|
|
@ -946,3 +946,29 @@ fn test_reverse_in_place() {
|
||||||
c.reverse_in_place()
|
c.reverse_in_place()
|
||||||
assert c == [[5, 6], [3, 4], [1, 2]]
|
assert c == [[5, 6], [3, 4], [1, 2]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_array_int_pop() {
|
||||||
|
mut a := [1,2,3,4,5]
|
||||||
|
assert a.len == 5
|
||||||
|
x := a.last()
|
||||||
|
y := a.pop()
|
||||||
|
assert x == y
|
||||||
|
assert a.len == 4
|
||||||
|
z := a.pop()
|
||||||
|
assert a.len == 3
|
||||||
|
assert z == 4
|
||||||
|
a.pop()
|
||||||
|
a.pop()
|
||||||
|
final := a.pop()
|
||||||
|
assert final == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_array_string_pop() {
|
||||||
|
mut a := ['abc', 'def', 'xyz']
|
||||||
|
assert a.len == 3
|
||||||
|
assert a.pop() == 'xyz'
|
||||||
|
assert a.pop() == 'def'
|
||||||
|
assert a.pop() == 'abc'
|
||||||
|
assert a.len == 0
|
||||||
|
assert a.cap == 3
|
||||||
|
}
|
||||||
|
|
|
@ -859,10 +859,14 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
call_expr.return_type = left_type
|
call_expr.return_type = left_type
|
||||||
call_expr.receiver_type = left_type.to_ptr()
|
call_expr.receiver_type = left_type.to_ptr()
|
||||||
return call_expr.return_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', 'pop'] {
|
||||||
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
|
||||||
|
if method_name == 'pop' {
|
||||||
|
call_expr.receiver_type = left_type.to_ptr()
|
||||||
|
} else {
|
||||||
call_expr.receiver_type = left_type
|
call_expr.receiver_type = left_type
|
||||||
|
}
|
||||||
return call_expr.return_type
|
return call_expr.return_type
|
||||||
} else if left_type_sym.kind == .array && method_name in ['insert', 'prepend'] {
|
} else if left_type_sym.kind == .array && method_name in ['insert', 'prepend'] {
|
||||||
array_info := left_type_sym.info as table.Array
|
array_info := left_type_sym.info as table.Array
|
||||||
|
|
|
@ -352,12 +352,12 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
// TODO performance, detect `array` method differently
|
// TODO performance, detect `array` method differently
|
||||||
if left_sym.kind == .array && node.name in
|
if left_sym.kind == .array && node.name in
|
||||||
['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'clone', 'reverse', 'slice'] {
|
['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice'] {
|
||||||
// && rec_sym.name == 'array' {
|
// && rec_sym.name == 'array' {
|
||||||
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
|
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
|
||||||
// `array_byte_clone` => `array_clone`
|
// `array_byte_clone` => `array_clone`
|
||||||
receiver_type_name = 'array'
|
receiver_type_name = 'array'
|
||||||
if node.name in ['last', 'first'] {
|
if node.name in ['last', 'first', 'pop'] {
|
||||||
return_type_str := g.typ(node.return_type)
|
return_type_str := g.typ(node.return_type)
|
||||||
g.write('*($return_type_str*)')
|
g.write('*($return_type_str*)')
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue