parent
f4c8f897fe
commit
1250ce4353
|
@ -3353,10 +3353,18 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
|
||||||
}
|
}
|
||||||
if array_init.is_fixed {
|
if array_init.is_fixed {
|
||||||
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len)
|
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len)
|
||||||
array_init.typ = ast.new_type(idx)
|
if elem_type.has_flag(.generic) {
|
||||||
|
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||||
|
} else {
|
||||||
|
array_init.typ = ast.new_type(idx)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
idx := c.table.find_or_register_array(elem_type)
|
idx := c.table.find_or_register_array(elem_type)
|
||||||
array_init.typ = ast.new_type(idx)
|
if elem_type.has_flag(.generic) {
|
||||||
|
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||||
|
} else {
|
||||||
|
array_init.typ = ast.new_type(idx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
array_init.elem_type = elem_type
|
array_init.elem_type = elem_type
|
||||||
} else if array_init.is_fixed && array_init.exprs.len == 1
|
} else if array_init.is_fixed && array_init.exprs.len == 1
|
||||||
|
@ -3391,8 +3399,11 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
|
||||||
c.error('fixed size cannot be zero or negative', init_expr.position())
|
c.error('fixed size cannot be zero or negative', init_expr.position())
|
||||||
}
|
}
|
||||||
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size)
|
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size)
|
||||||
array_type := ast.new_type(idx)
|
if array_init.elem_type.has_flag(.generic) {
|
||||||
array_init.typ = array_type
|
array_init.typ = ast.new_type(idx).set_flag(.generic)
|
||||||
|
} else {
|
||||||
|
array_init.typ = ast.new_type(idx)
|
||||||
|
}
|
||||||
if array_init.has_default {
|
if array_init.has_default {
|
||||||
c.expr(array_init.default_expr)
|
c.expr(array_init.default_expr)
|
||||||
}
|
}
|
||||||
|
@ -6047,10 +6058,13 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
||||||
c.check_dup_keys(node, i)
|
c.check_dup_keys(node, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
map_type := ast.new_type(c.table.find_or_register_map(key0_type, val0_type))
|
mut map_type := ast.new_type(c.table.find_or_register_map(key0_type, val0_type))
|
||||||
node.typ = map_type
|
node.typ = map_type
|
||||||
node.key_type = key0_type
|
node.key_type = key0_type
|
||||||
node.value_type = val0_type
|
node.value_type = val0_type
|
||||||
|
if node.key_type.has_flag(.generic) || node.value_type.has_flag(.generic) {
|
||||||
|
map_type = map_type.set_flag(.generic)
|
||||||
|
}
|
||||||
return map_type
|
return map_type
|
||||||
}
|
}
|
||||||
return node.typ
|
return node.typ
|
||||||
|
|
|
@ -3633,7 +3633,7 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
// arr << val
|
// arr << val
|
||||||
tmp := g.new_tmp_var()
|
tmp := g.new_tmp_var()
|
||||||
info := left_final_sym.info as ast.Array
|
info := left_final_sym.info as ast.Array
|
||||||
if right_final_sym.kind == .array && info.elem_type != node.right_type {
|
if right_final_sym.kind == .array && info.elem_type != g.unwrap_generic(node.right_type) {
|
||||||
// push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`)
|
// push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`)
|
||||||
g.write('_PUSH_MANY(')
|
g.write('_PUSH_MANY(')
|
||||||
mut expected_push_many_atype := left_type
|
mut expected_push_many_atype := left_type
|
||||||
|
|
|
@ -605,7 +605,7 @@ 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
|
if left_sym.kind == .array
|
||||||
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice'] {
|
&& node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'pop', 'clone', 'reverse', 'slice', 'pointers'] {
|
||||||
// && 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`
|
||||||
|
|
|
@ -33,7 +33,11 @@ fn (mut p Parser) array_init() ast.ArrayInit {
|
||||||
// this is set here because it's a known type, others could be the
|
// this is set here because it's a known type, others could be the
|
||||||
// result of expr so we do those in checker
|
// result of expr so we do those in checker
|
||||||
idx := p.table.find_or_register_array(elem_type)
|
idx := p.table.find_or_register_array(elem_type)
|
||||||
array_type = ast.new_type(idx)
|
if elem_type.has_flag(.generic) {
|
||||||
|
array_type = ast.new_type(idx).set_flag(.generic)
|
||||||
|
} else {
|
||||||
|
array_type = ast.new_type(idx)
|
||||||
|
}
|
||||||
has_type = true
|
has_type = true
|
||||||
}
|
}
|
||||||
last_pos = p.tok.position()
|
last_pos = p.tok.position()
|
||||||
|
|
|
@ -43,6 +43,9 @@ pub fn (mut p Parser) parse_array_type() ast.Type {
|
||||||
}
|
}
|
||||||
// sym := p.table.get_type_symbol(elem_type)
|
// sym := p.table.get_type_symbol(elem_type)
|
||||||
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
|
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
|
||||||
|
if elem_type.has_flag(.generic) {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
// array
|
// array
|
||||||
|
@ -61,6 +64,9 @@ pub fn (mut p Parser) parse_array_type() ast.Type {
|
||||||
nr_dims++
|
nr_dims++
|
||||||
}
|
}
|
||||||
idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims)
|
idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims)
|
||||||
|
if elem_type.has_flag(.generic) {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +107,9 @@ pub fn (mut p Parser) parse_map_type() ast.Type {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
idx := p.table.find_or_register_map(key_type, value_type)
|
idx := p.table.find_or_register_map(key_type, value_type)
|
||||||
|
if key_type.has_flag(.generic) || value_type.has_flag(.generic) {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +124,9 @@ pub fn (mut p Parser) parse_chan_type() ast.Type {
|
||||||
is_mut := p.tok.kind == .key_mut
|
is_mut := p.tok.kind == .key_mut
|
||||||
elem_type := p.parse_type()
|
elem_type := p.parse_type()
|
||||||
idx := p.table.find_or_register_chan(elem_type, is_mut)
|
idx := p.table.find_or_register_chan(elem_type, is_mut)
|
||||||
|
if elem_type.has_flag(.generic) {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,17 +152,24 @@ pub fn (mut p Parser) parse_thread_type() ast.Type {
|
||||||
}
|
}
|
||||||
ret_type := p.parse_type()
|
ret_type := p.parse_type()
|
||||||
idx := p.table.find_or_register_thread(ret_type)
|
idx := p.table.find_or_register_thread(ret_type)
|
||||||
|
if ret_type.has_flag(.generic) {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut p Parser) parse_multi_return_type() ast.Type {
|
pub fn (mut p Parser) parse_multi_return_type() ast.Type {
|
||||||
p.check(.lpar)
|
p.check(.lpar)
|
||||||
mut mr_types := []ast.Type{}
|
mut mr_types := []ast.Type{}
|
||||||
|
mut has_generic := false
|
||||||
for p.tok.kind != .eof {
|
for p.tok.kind != .eof {
|
||||||
mr_type := p.parse_type()
|
mr_type := p.parse_type()
|
||||||
if mr_type.idx() == 0 {
|
if mr_type.idx() == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if mr_type.has_flag(.generic) {
|
||||||
|
has_generic = true
|
||||||
|
}
|
||||||
mr_types << mr_type
|
mr_types << mr_type
|
||||||
if p.tok.kind == .comma {
|
if p.tok.kind == .comma {
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -164,6 +183,9 @@ pub fn (mut p Parser) parse_multi_return_type() ast.Type {
|
||||||
return mr_types[0]
|
return mr_types[0]
|
||||||
}
|
}
|
||||||
idx := p.table.find_or_register_multi_return(mr_types)
|
idx := p.table.find_or_register_multi_return(mr_types)
|
||||||
|
if has_generic {
|
||||||
|
return ast.new_type(idx).set_flag(.generic)
|
||||||
|
}
|
||||||
return ast.new_type(idx)
|
return ast.new_type(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
struct Group<T> {
|
||||||
|
len int
|
||||||
|
val []T
|
||||||
|
mut:
|
||||||
|
index int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn group_new<T>(val ...T) Group<T> {
|
||||||
|
mut arr := []T{cap: val.len}
|
||||||
|
for i in val {
|
||||||
|
arr << i
|
||||||
|
}
|
||||||
|
mut g := Group{
|
||||||
|
len: val.len
|
||||||
|
val: arr
|
||||||
|
}
|
||||||
|
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut it Group<T>) next<T>() ?T {
|
||||||
|
if it.index >= it.len {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
v := it.val[it.index]
|
||||||
|
it.index++
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generics_with_embed_generics() {
|
||||||
|
gx := group_new<int>(1, 2, 3)
|
||||||
|
for x in gx.val {
|
||||||
|
println(x)
|
||||||
|
}
|
||||||
|
assert gx.val == [1, 2, 3]
|
||||||
|
}
|
Loading…
Reference in New Issue