cgen: split up array_init() (#14178)
parent
07d465cbaa
commit
8a75d68421
|
@ -22,182 +22,165 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
|
||||||
array_styp = g.typ(array_type.typ)
|
array_styp = g.typ(array_type.typ)
|
||||||
g.write('HEAP($array_styp, ')
|
g.write('HEAP($array_styp, ')
|
||||||
}
|
}
|
||||||
|
len := node.exprs.len
|
||||||
if array_type.unaliased_sym.kind == .array_fixed {
|
if array_type.unaliased_sym.kind == .array_fixed {
|
||||||
if node.has_it {
|
g.fixed_array_init(node, array_type)
|
||||||
g.inside_lambda = true
|
} else if len == 0 {
|
||||||
tmp := g.new_tmp_var()
|
// `[]int{len: 6, cap:10, init:22}`
|
||||||
mut s := g.go_before_stmt(0)
|
g.array_init_with_fields(node, elem_type, is_amp, shared_styp)
|
||||||
s_ends_with_ln := s.ends_with('\n')
|
} else {
|
||||||
s = s.trim_space()
|
// `[1, 2, 3]`
|
||||||
ret_typ := g.typ(node.typ)
|
elem_styp := g.typ(elem_type.typ)
|
||||||
elem_typ := g.typ(node.elem_type)
|
noscan := g.check_noscan(elem_type.typ)
|
||||||
g.empty_line = true
|
if elem_type.unaliased_sym.kind == .function {
|
||||||
g.write('$ret_typ $tmp =')
|
g.write('new_array_from_c_array($len, $len, sizeof(voidptr), _MOV((voidptr[$len]){')
|
||||||
g.write('{')
|
} else if g.is_empty_struct(elem_type) {
|
||||||
if node.has_val {
|
g.write('new_array_from_c_array${noscan}($len, $len, sizeof(voidptr), _MOV(($elem_styp[$len]){')
|
||||||
for i, expr in node.exprs {
|
} else {
|
||||||
if expr.is_auto_deref_var() {
|
g.write('new_array_from_c_array${noscan}($len, $len, sizeof($elem_styp), _MOV(($elem_styp[$len]){')
|
||||||
g.write('*')
|
}
|
||||||
}
|
if len > 8 {
|
||||||
g.write('0')
|
g.writeln('')
|
||||||
if i != node.exprs.len - 1 {
|
g.write('\t\t')
|
||||||
g.write(', ')
|
}
|
||||||
}
|
for i, expr in node.exprs {
|
||||||
}
|
if node.expr_types[i] == ast.string_type && expr !is ast.StringLiteral
|
||||||
} else if node.has_default {
|
&& expr !is ast.StringInterLiteral {
|
||||||
g.write('0')
|
g.write('string_clone(')
|
||||||
info := array_type.unaliased_sym.info as ast.ArrayFixed
|
g.expr(expr)
|
||||||
for _ in 1 .. info.size {
|
g.write(')')
|
||||||
|
} else {
|
||||||
|
g.expr_with_cast(expr, node.expr_types[i], node.elem_type)
|
||||||
|
}
|
||||||
|
if i != len - 1 {
|
||||||
|
if i > 0 && i & 7 == 0 { // i > 0 && i % 8 == 0
|
||||||
|
g.writeln(',')
|
||||||
|
g.write('\t\t')
|
||||||
|
} else {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.write('0')
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
g.write('0')
|
|
||||||
}
|
}
|
||||||
g.write('}')
|
|
||||||
g.writeln(';')
|
|
||||||
g.writeln('{')
|
|
||||||
g.indent++
|
|
||||||
g.writeln('$elem_typ* pelem = ($elem_typ*)$tmp;')
|
|
||||||
g.writeln('int _len = (int)sizeof($tmp) / sizeof($elem_typ);')
|
|
||||||
g.writeln('for(int it=0; it<_len; it++, pelem++) {')
|
|
||||||
g.indent++
|
|
||||||
g.write('*pelem = ')
|
|
||||||
g.expr(node.default_expr)
|
|
||||||
g.writeln(';')
|
|
||||||
g.indent--
|
|
||||||
g.writeln('}')
|
|
||||||
g.indent--
|
|
||||||
g.writeln('}')
|
|
||||||
if s_ends_with_ln {
|
|
||||||
g.writeln(s)
|
|
||||||
} else {
|
|
||||||
g.write(s)
|
|
||||||
}
|
|
||||||
g.write(tmp)
|
|
||||||
g.inside_lambda = false
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
need_tmp_var := g.inside_call && !g.inside_struct_init && node.exprs.len == 0
|
g.write('}))')
|
||||||
mut stmt_str := ''
|
if g.is_shared {
|
||||||
mut tmp_var := ''
|
g.write('}, sizeof($shared_styp))')
|
||||||
if need_tmp_var {
|
} else if is_amp {
|
||||||
tmp_var = g.new_tmp_var()
|
g.write(')')
|
||||||
stmt_str = g.go_before_stmt(0)
|
|
||||||
ret_typ := g.typ(node.typ)
|
|
||||||
g.empty_line = true
|
|
||||||
g.write('$ret_typ $tmp_var = ')
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type) {
|
||||||
|
if node.has_it {
|
||||||
|
g.inside_lambda = true
|
||||||
|
tmp := g.new_tmp_var()
|
||||||
|
mut s := g.go_before_stmt(0)
|
||||||
|
s_ends_with_ln := s.ends_with('\n')
|
||||||
|
s = s.trim_space()
|
||||||
|
ret_typ := g.typ(node.typ)
|
||||||
|
elem_typ := g.typ(node.elem_type)
|
||||||
|
g.empty_line = true
|
||||||
|
g.write('$ret_typ $tmp =')
|
||||||
g.write('{')
|
g.write('{')
|
||||||
if node.has_val {
|
if node.has_val {
|
||||||
for i, expr in node.exprs {
|
for i, expr in node.exprs {
|
||||||
if expr.is_auto_deref_var() {
|
if expr.is_auto_deref_var() {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
g.write('0')
|
||||||
if i != node.exprs.len - 1 {
|
if i != node.exprs.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if node.has_default {
|
} else if node.has_default {
|
||||||
g.expr(node.default_expr)
|
g.write('0')
|
||||||
info := array_type.unaliased_sym.info as ast.ArrayFixed
|
info := array_type.unaliased_sym.info as ast.ArrayFixed
|
||||||
for _ in 1 .. info.size {
|
for _ in 1 .. info.size {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
g.expr(node.default_expr)
|
g.write('0')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.write('0')
|
g.write('0')
|
||||||
}
|
}
|
||||||
g.write('}')
|
g.write('}')
|
||||||
if need_tmp_var {
|
g.writeln(';')
|
||||||
g.writeln(';')
|
g.writeln('{')
|
||||||
g.write(stmt_str)
|
g.indent++
|
||||||
g.write(tmp_var)
|
g.writeln('$elem_typ* pelem = ($elem_typ*)$tmp;')
|
||||||
|
g.writeln('int _len = (int)sizeof($tmp) / sizeof($elem_typ);')
|
||||||
|
g.writeln('for(int it=0; it<_len; it++, pelem++) {')
|
||||||
|
g.indent++
|
||||||
|
g.write('*pelem = ')
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
g.writeln(';')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
if s_ends_with_ln {
|
||||||
|
g.writeln(s)
|
||||||
|
} else {
|
||||||
|
g.write(s)
|
||||||
}
|
}
|
||||||
|
g.write(tmp)
|
||||||
|
g.inside_lambda = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
need_tmp_var := g.inside_call && !g.inside_struct_init && node.exprs.len == 0
|
||||||
|
mut stmt_str := ''
|
||||||
|
mut tmp_var := ''
|
||||||
|
if need_tmp_var {
|
||||||
|
tmp_var = g.new_tmp_var()
|
||||||
|
stmt_str = g.go_before_stmt(0)
|
||||||
|
ret_typ := g.typ(node.typ)
|
||||||
|
g.empty_line = true
|
||||||
|
g.write('$ret_typ $tmp_var = ')
|
||||||
|
}
|
||||||
|
g.write('{')
|
||||||
|
if node.has_val {
|
||||||
|
for i, expr in node.exprs {
|
||||||
|
if expr.is_auto_deref_var() {
|
||||||
|
g.write('*')
|
||||||
|
}
|
||||||
|
g.expr(expr)
|
||||||
|
if i != node.exprs.len - 1 {
|
||||||
|
g.write(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if node.has_default {
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
info := array_type.unaliased_sym.info as ast.ArrayFixed
|
||||||
|
for _ in 1 .. info.size {
|
||||||
|
g.write(', ')
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g.write('0')
|
||||||
|
}
|
||||||
|
g.write('}')
|
||||||
|
if need_tmp_var {
|
||||||
|
g.writeln(';')
|
||||||
|
g.write(stmt_str)
|
||||||
|
g.write(tmp_var)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// `[]int{len: 6, cap: 10, init: it * it}`
|
||||||
|
fn (mut g Gen) array_init_with_fields(node ast.ArrayInit, elem_type Type, is_amp bool, shared_styp string) {
|
||||||
elem_styp := g.typ(elem_type.typ)
|
elem_styp := g.typ(elem_type.typ)
|
||||||
noscan := g.check_noscan(elem_type.typ)
|
noscan := g.check_noscan(elem_type.typ)
|
||||||
if node.exprs.len == 0 {
|
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
||||||
is_default_array := elem_type.unaliased_sym.kind == .array && node.has_default
|
is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default
|
||||||
is_default_map := elem_type.unaliased_sym.kind == .map && node.has_default
|
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
|
||||||
if node.has_it { // []int{len: 6, init: it * it} when variable it is used in init expression
|
g.inside_lambda = true
|
||||||
g.inside_lambda = true
|
tmp := g.new_tmp_var()
|
||||||
tmp := g.new_tmp_var()
|
mut s := g.go_before_stmt(0)
|
||||||
mut s := g.go_before_stmt(0)
|
s_ends_with_ln := s.ends_with('\n')
|
||||||
s_ends_with_ln := s.ends_with('\n')
|
s = s.trim_space()
|
||||||
s = s.trim_space()
|
ret_typ := g.typ(node.typ)
|
||||||
ret_typ := g.typ(node.typ)
|
elem_typ := g.typ(node.elem_type)
|
||||||
elem_typ := g.typ(node.elem_type)
|
g.empty_line = true
|
||||||
g.empty_line = true
|
g.write('$ret_typ $tmp =')
|
||||||
g.write('$ret_typ $tmp =')
|
|
||||||
if is_default_array {
|
|
||||||
g.write('__new_array_with_array_default${noscan}(')
|
|
||||||
} else if is_default_map {
|
|
||||||
g.write('__new_array_with_map_default${noscan}(')
|
|
||||||
} else {
|
|
||||||
g.write('__new_array_with_default${noscan}(')
|
|
||||||
}
|
|
||||||
if node.has_len {
|
|
||||||
g.expr(node.len_expr)
|
|
||||||
g.write(', ')
|
|
||||||
} else {
|
|
||||||
g.write('0, ')
|
|
||||||
}
|
|
||||||
if node.has_cap {
|
|
||||||
g.expr(node.cap_expr)
|
|
||||||
g.write(', ')
|
|
||||||
} else {
|
|
||||||
g.write('0, ')
|
|
||||||
}
|
|
||||||
if elem_type.unaliased_sym.kind == .function || g.is_empty_struct(elem_type) {
|
|
||||||
g.write('sizeof(voidptr), ')
|
|
||||||
} else {
|
|
||||||
g.write('sizeof($elem_styp), ')
|
|
||||||
}
|
|
||||||
if is_default_array {
|
|
||||||
g.write('($elem_styp[]){')
|
|
||||||
g.expr(node.default_expr)
|
|
||||||
g.write('}[0])')
|
|
||||||
} else if node.has_len && node.elem_type == ast.string_type {
|
|
||||||
g.write('&($elem_styp[]){')
|
|
||||||
g.write('_SLIT("")')
|
|
||||||
g.write('})')
|
|
||||||
} else if node.has_len && elem_type.unaliased_sym.kind in [.array, .map] {
|
|
||||||
g.write('(voidptr)&($elem_styp[]){')
|
|
||||||
g.write(g.type_default(node.elem_type))
|
|
||||||
g.write('}[0])')
|
|
||||||
} else {
|
|
||||||
g.write('0)')
|
|
||||||
}
|
|
||||||
if g.is_shared {
|
|
||||||
g.write('}, sizeof($shared_styp))')
|
|
||||||
} else if is_amp {
|
|
||||||
g.write(')')
|
|
||||||
}
|
|
||||||
g.writeln(';')
|
|
||||||
g.writeln('{')
|
|
||||||
g.indent++
|
|
||||||
g.writeln('$elem_typ* pelem = ($elem_typ*)${tmp}.data;')
|
|
||||||
g.writeln('for(int it=0; it<${tmp}.len; it++, pelem++) {')
|
|
||||||
g.indent++
|
|
||||||
g.write('*pelem = ')
|
|
||||||
g.expr(node.default_expr)
|
|
||||||
g.writeln(';')
|
|
||||||
g.indent--
|
|
||||||
g.writeln('}')
|
|
||||||
g.indent--
|
|
||||||
g.writeln('}')
|
|
||||||
if s_ends_with_ln {
|
|
||||||
g.writeln(s)
|
|
||||||
} else {
|
|
||||||
g.write(s)
|
|
||||||
}
|
|
||||||
g.write(tmp)
|
|
||||||
g.inside_lambda = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if is_default_array {
|
if is_default_array {
|
||||||
g.write('__new_array_with_array_default${noscan}(')
|
g.write('__new_array_with_array_default${noscan}(')
|
||||||
} else if is_default_map {
|
} else if is_default_map {
|
||||||
|
@ -222,14 +205,10 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
|
||||||
} else {
|
} else {
|
||||||
g.write('sizeof($elem_styp), ')
|
g.write('sizeof($elem_styp), ')
|
||||||
}
|
}
|
||||||
if is_default_array || is_default_map {
|
if is_default_array {
|
||||||
g.write('($elem_styp[]){')
|
g.write('($elem_styp[]){')
|
||||||
g.expr(node.default_expr)
|
g.expr(node.default_expr)
|
||||||
g.write('}[0])')
|
g.write('}[0])')
|
||||||
} else if node.has_default {
|
|
||||||
g.write('&($elem_styp[]){')
|
|
||||||
g.expr_with_cast(node.default_expr, node.default_type, node.elem_type)
|
|
||||||
g.write('})')
|
|
||||||
} else if node.has_len && node.elem_type == ast.string_type {
|
} else if node.has_len && node.elem_type == ast.string_type {
|
||||||
g.write('&($elem_styp[]){')
|
g.write('&($elem_styp[]){')
|
||||||
g.write('_SLIT("")')
|
g.write('_SLIT("")')
|
||||||
|
@ -246,39 +225,71 @@ fn (mut g Gen) array_init(node ast.ArrayInit) {
|
||||||
} else if is_amp {
|
} else if is_amp {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
g.writeln(';')
|
||||||
|
g.writeln('{')
|
||||||
|
g.indent++
|
||||||
|
g.writeln('$elem_typ* pelem = ($elem_typ*)${tmp}.data;')
|
||||||
|
g.writeln('for(int it=0; it<${tmp}.len; it++, pelem++) {')
|
||||||
|
g.indent++
|
||||||
|
g.write('*pelem = ')
|
||||||
|
g.expr(node.default_expr)
|
||||||
|
g.writeln(';')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
g.indent--
|
||||||
|
g.writeln('}')
|
||||||
|
if s_ends_with_ln {
|
||||||
|
g.writeln(s)
|
||||||
|
} else {
|
||||||
|
g.write(s)
|
||||||
|
}
|
||||||
|
g.write(tmp)
|
||||||
|
g.inside_lambda = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
len := node.exprs.len
|
if is_default_array {
|
||||||
if elem_type.unaliased_sym.kind == .function {
|
g.write('__new_array_with_array_default${noscan}(')
|
||||||
g.write('new_array_from_c_array($len, $len, sizeof(voidptr), _MOV((voidptr[$len]){')
|
} else if is_default_map {
|
||||||
} else if g.is_empty_struct(elem_type) {
|
g.write('__new_array_with_map_default${noscan}(')
|
||||||
g.write('new_array_from_c_array${noscan}($len, $len, sizeof(voidptr), _MOV(($elem_styp[$len]){')
|
|
||||||
} else {
|
} else {
|
||||||
g.write('new_array_from_c_array${noscan}($len, $len, sizeof($elem_styp), _MOV(($elem_styp[$len]){')
|
g.write('__new_array_with_default${noscan}(')
|
||||||
}
|
}
|
||||||
if len > 8 {
|
if node.has_len {
|
||||||
g.writeln('')
|
g.expr(node.len_expr)
|
||||||
g.write('\t\t')
|
g.write(', ')
|
||||||
|
} else {
|
||||||
|
g.write('0, ')
|
||||||
}
|
}
|
||||||
for i, expr in node.exprs {
|
if node.has_cap {
|
||||||
if node.expr_types[i] == ast.string_type && expr !is ast.StringLiteral
|
g.expr(node.cap_expr)
|
||||||
&& expr !is ast.StringInterLiteral {
|
g.write(', ')
|
||||||
g.write('string_clone(')
|
} else {
|
||||||
g.expr(expr)
|
g.write('0, ')
|
||||||
g.write(')')
|
}
|
||||||
} else {
|
if elem_type.unaliased_sym.kind == .function || g.is_empty_struct(elem_type) {
|
||||||
g.expr_with_cast(expr, node.expr_types[i], node.elem_type)
|
g.write('sizeof(voidptr), ')
|
||||||
}
|
} else {
|
||||||
if i != len - 1 {
|
g.write('sizeof($elem_styp), ')
|
||||||
if i > 0 && i & 7 == 0 { // i > 0 && i % 8 == 0
|
}
|
||||||
g.writeln(',')
|
if is_default_array || is_default_map {
|
||||||
g.write('\t\t')
|
g.write('($elem_styp[]){')
|
||||||
} else {
|
g.expr(node.default_expr)
|
||||||
g.write(', ')
|
g.write('}[0])')
|
||||||
}
|
} else if node.has_default {
|
||||||
}
|
g.write('&($elem_styp[]){')
|
||||||
|
g.expr_with_cast(node.default_expr, node.default_type, node.elem_type)
|
||||||
|
g.write('})')
|
||||||
|
} else if node.has_len && node.elem_type == ast.string_type {
|
||||||
|
g.write('&($elem_styp[]){')
|
||||||
|
g.write('_SLIT("")')
|
||||||
|
g.write('})')
|
||||||
|
} else if node.has_len && elem_type.unaliased_sym.kind in [.array, .map] {
|
||||||
|
g.write('(voidptr)&($elem_styp[]){')
|
||||||
|
g.write(g.type_default(node.elem_type))
|
||||||
|
g.write('}[0])')
|
||||||
|
} else {
|
||||||
|
g.write('0)')
|
||||||
}
|
}
|
||||||
g.write('}))')
|
|
||||||
if g.is_shared {
|
if g.is_shared {
|
||||||
g.write('}, sizeof($shared_styp))')
|
g.write('}, sizeof($shared_styp))')
|
||||||
} else if is_amp {
|
} else if is_amp {
|
||||||
|
|
Loading…
Reference in New Issue