1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

compiler: add [..2] & [2..] support for slices

This commit is contained in:
joe-conigliaro 2019-10-27 17:36:04 +11:00 committed by Alexander Medvednikov
parent e80cf185b9
commit a075ce160e
6 changed files with 47 additions and 10 deletions

View File

@ -146,6 +146,12 @@ pub fn (s array) right(n int) array {
return s.slice(n, s.len) return s.slice(n, s.len)
} }
// used internally for [2..4]
fn (s array) slice2(start, _end int, end_max bool) array {
end := if end_max { s.len } else { _end }
return s.slice(start, end)
}
pub fn (s array) slice(start, _end int) array { pub fn (s array) slice(start, _end int) array {
mut end := _end mut end := _end
if start > end { if start > end {

View File

@ -118,10 +118,13 @@ fn test_right() {
a := [1, 2, 3, 4] a := [1, 2, 3, 4]
b := a.right(1) b := a.right(1)
c := a[1..a.len] c := a[1..a.len]
d := a[1..]
assert b[0] == 2 assert b[0] == 2
assert b[1] == 3 assert b[1] == 3
assert c[0] == 2 assert c[0] == 2
assert c[1] == 3 assert c[1] == 3
assert d[0] == 2
assert d[1] == 3
} }
fn test_right_with_n_bigger_than_array_size() { fn test_right_with_n_bigger_than_array_size() {
@ -142,10 +145,13 @@ fn test_left() {
a := [1, 2, 3] a := [1, 2, 3]
b := a.left(2) b := a.left(2)
c := a[0..2] c := a[0..2]
d := a[..2]
assert b[0] == 1 assert b[0] == 1
assert b[1] == 2 assert b[1] == 2
assert c[0] == 1 assert c[0] == 1
assert c[1] == 2 assert c[1] == 2
assert d[0] == 1
assert d[1] == 2
} }
fn test_slice() { fn test_slice() {

View File

@ -394,6 +394,12 @@ pub fn (s string) right(n int) string {
return s.substr(n, s.len) return s.substr(n, s.len)
} }
// used internally for [2..4]
fn (s string) substr2(start, _end int, end_max bool) string {
end := if end_max { s.len } else { _end }
return s.substr(start, end)
}
// substr // substr
pub fn (s string) substr(start, end int) string { pub fn (s string) substr(start, end int) string {
if start > end || start > s.len || end > s.len || start < 0 || end < 0 { if start > end || start > s.len || end > s.len || start < 0 || end < 0 {

View File

@ -210,6 +210,10 @@ fn test_runes() {
assert s2.substr(1, 4) == 'riv' assert s2.substr(1, 4) == 'riv'
assert s2[1..4].len == 3 assert s2[1..4].len == 3
assert s2[1..4] == 'riv' assert s2[1..4] == 'riv'
assert s2[..4].len == 4
assert s2[..4] == 'priv'
assert s2[2..].len == 4
assert s2[2..] == 'ivet'
assert u.substr(1, 4).len == 6 assert u.substr(1, 4).len == 6
assert u.substr(1, 4) == 'рив' assert u.substr(1, 4) == 'рив'
assert s2.substr(1, 2) == 'r' assert s2.substr(1, 2) == 'r'

View File

@ -197,7 +197,7 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) {
else { else {
ref := if cfg.is_ptr { '*' } else { '' } ref := if cfg.is_ptr { '*' } else { '' }
if cfg.is_slice { if cfg.is_slice {
p.gen(' array_slice($ref $index_expr) ') p.gen(' array_slice2($ref $index_expr) ')
} }
else { else {
p.gen('( *($typ*) array_get($ref $index_expr) )') p.gen('( *($typ*) array_get($ref $index_expr) )')
@ -206,7 +206,7 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) {
} }
else if cfg.is_str && !p.builtin_mod { else if cfg.is_str && !p.builtin_mod {
if cfg.is_slice { if cfg.is_slice {
p.gen('string_substr($index_expr)') p.gen('string_substr2($index_expr)')
} else { } else {
p.gen('string_at($index_expr)') p.gen('string_at($index_expr)')
} }

View File

@ -2155,6 +2155,8 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
} }
// expression inside [ ] // expression inside [ ]
if is_arr || is_str { if is_arr || is_str {
// [2..
if p.tok != .dotdot {
index_pos := p.cgen.cur_line.len index_pos := p.cgen.cur_line.len
T := p.table.find_type(p.expression()) T := p.table.find_type(p.expression())
// Allows only i8-64 and byte-64 to be used when accessing an array // Allows only i8-64 and byte-64 to be used when accessing an array
@ -2164,6 +2166,11 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
if p.cgen.cur_line.right(index_pos).replace(' ', '').int() < 0 { if p.cgen.cur_line.right(index_pos).replace(' ', '').int() < 0 {
p.error('cannot access negative array index') p.error('cannot access negative array index')
} }
}
// [..
else {
p.gen('0')
}
if p.tok == .dotdot { if p.tok == .dotdot {
if is_arr { if is_arr {
typ = 'array_' + typ typ = 'array_' + typ
@ -2175,7 +2182,15 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
is_slice = true is_slice = true
p.next() p.next()
p.gen(',') p.gen(',')
// ..4]
if p.tok != .rsbr {
p.check_types(p.expression(), 'int') p.check_types(p.expression(), 'int')
p.gen(', false')
}
// ..]
else {
p.gen('-1, true')
}
} }
} }
else { else {