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

pull/2560/head
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)
}
// 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 {
mut end := _end
if start > end {

View File

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

View File

@ -394,6 +394,12 @@ pub fn (s string) right(n int) string {
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
pub fn (s string) substr(start, end int) string {
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[1..4].len == 3
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) == 'рив'
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 {
ref := if cfg.is_ptr { '*' } else { '' }
if cfg.is_slice {
p.gen(' array_slice($ref $index_expr) ')
p.gen(' array_slice2($ref $index_expr) ')
}
else {
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 {
if cfg.is_slice {
p.gen('string_substr($index_expr)')
p.gen('string_substr2($index_expr)')
} else {
p.gen('string_at($index_expr)')
}

View File

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