a[start..end] slicing
parent
678ce54e70
commit
570a7aaaf3
|
@ -169,7 +169,7 @@ fn types_to_c(types []Type, table &Table) string {
|
||||||
return sb.str()
|
return sb.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexCfg) {
|
fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) {
|
||||||
// Erase var name we generated earlier: "int a = m, 0"
|
// Erase var name we generated earlier: "int a = m, 0"
|
||||||
// "m, 0" gets killed since we need to start from scratch. It's messy.
|
// "m, 0" gets killed since we need to start from scratch. It's messy.
|
||||||
// "m, 0" is an index expression, save it before deleting and insert later in map_get()
|
// "m, 0" is an index expression, save it before deleting and insert later in map_get()
|
||||||
|
@ -195,16 +195,22 @@ fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexCfg) {
|
||||||
p.gen('$index_expr ]')
|
p.gen('$index_expr ]')
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if cfg.is_ptr {
|
amp := if cfg.is_ptr { '&' } else { '' }
|
||||||
p.gen('( *($typ*) array_get(* $index_expr) )')
|
if cfg.is_slice {
|
||||||
} else {
|
p.gen(' array_slice($amp $index_expr) ')
|
||||||
p.gen('( *($typ*) array_get($index_expr) )')
|
}
|
||||||
|
else {
|
||||||
|
p.gen('( *($typ*) array_get($amp $index_expr) )')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if cfg.is_str && !p.builtin_mod {
|
else if cfg.is_str && !p.builtin_mod {
|
||||||
|
if cfg.is_slice {
|
||||||
|
p.gen('string_substr($index_expr)')
|
||||||
|
} else {
|
||||||
p.gen('string_at($index_expr)')
|
p.gen('string_at($index_expr)')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Zero the string after map_get() if it's nil, numbers are automatically 0
|
// Zero the string after map_get() if it's nil, numbers are automatically 0
|
||||||
// This is ugly, but what can I do without generics?
|
// This is ugly, but what can I do without generics?
|
||||||
// TODO what about user types?
|
// TODO what about user types?
|
||||||
|
|
|
@ -70,7 +70,7 @@ fn types_to_c(types []Type, table &Table) string {
|
||||||
return sb.str()
|
return sb.str()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexCfg) {
|
fn (p mut Parser) index_get(typ string, fn_ph int, cfg IndexConfig) {
|
||||||
p.cgen.cur_line = p.cgen.cur_line.replace(',', '[') + ']'
|
p.cgen.cur_line = p.cgen.cur_line.replace(',', '[') + ']'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2091,6 +2091,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||||
is_arr0 := typ.starts_with('array_')
|
is_arr0 := typ.starts_with('array_')
|
||||||
is_arr := is_arr0 || typ == 'array'
|
is_arr := is_arr0 || typ == 'array'
|
||||||
is_ptr := typ == 'byte*' || typ == 'byteptr' || typ.contains('*')
|
is_ptr := typ == 'byte*' || typ == 'byteptr' || typ.contains('*')
|
||||||
|
mut is_slice := false
|
||||||
is_indexer := p.tok == .lsbr
|
is_indexer := p.tok == .lsbr
|
||||||
mut close_bracket := false
|
mut close_bracket := false
|
||||||
index_error_tok_pos := p.token_idx
|
index_error_tok_pos := p.token_idx
|
||||||
|
@ -2163,6 +2164,19 @@ 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')
|
||||||
}
|
}
|
||||||
|
if p.tok == .dotdot {
|
||||||
|
if is_arr {
|
||||||
|
typ = 'array_' + typ
|
||||||
|
} else if is_str {
|
||||||
|
typ = 'string'
|
||||||
|
} else {
|
||||||
|
p.error('slicing is supported by arrays and strings only')
|
||||||
|
}
|
||||||
|
is_slice = true
|
||||||
|
p.next()
|
||||||
|
p.gen(',')
|
||||||
|
p.check_types(p.expression(), 'int')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
T := p.table.find_type(p.expression())
|
T := p.table.find_type(p.expression())
|
||||||
|
@ -2197,6 +2211,7 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// `m[key] = val`
|
||||||
// TODO move this from index_expr()
|
// TODO move this from index_expr()
|
||||||
if (p.tok == .assign && !p.is_sql) || p.tok.is_assign() {
|
if (p.tok == .assign && !p.is_sql) || p.tok.is_assign() {
|
||||||
if is_indexer && is_str && !p.builtin_mod {
|
if is_indexer && is_str && !p.builtin_mod {
|
||||||
|
@ -2216,26 +2231,27 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||||
// else if p.pref.is_verbose && p.assigned_var != '' {
|
// else if p.pref.is_verbose && p.assigned_var != '' {
|
||||||
// p.error('didnt assign')
|
// p.error('didnt assign')
|
||||||
// }
|
// }
|
||||||
// m[key]. no =, just a getter
|
// `m[key]`. no =, just a getter
|
||||||
else if (is_map || is_arr || (is_str && !p.builtin_mod)) && is_indexer {
|
else if (is_map || is_arr || (is_str && !p.builtin_mod)) && is_indexer {
|
||||||
p.index_get(typ, fn_ph, IndexCfg{
|
p.index_get(typ, fn_ph, IndexConfig{
|
||||||
is_arr: is_arr
|
is_arr: is_arr
|
||||||
is_map: is_map
|
is_map: is_map
|
||||||
is_ptr: is_ptr
|
is_ptr: is_ptr
|
||||||
is_str: is_str
|
is_str: is_str
|
||||||
|
is_slice: is_slice
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// else if is_arr && is_indexer{}
|
// else if is_arr && is_indexer{}
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IndexCfg {
|
struct IndexConfig {
|
||||||
is_map bool
|
is_map bool
|
||||||
is_str bool
|
is_str bool
|
||||||
is_ptr bool
|
is_ptr bool
|
||||||
is_arr bool
|
is_arr bool
|
||||||
is_arr0 bool
|
is_arr0 bool
|
||||||
|
is_slice bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debugging only
|
// for debugging only
|
||||||
|
|
Loading…
Reference in New Issue