cgen: minor cleanup in for_in_stmt() (#8962)
parent
2e381f427a
commit
c7587c0760
|
@ -1334,147 +1334,147 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
|
|||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) for_in_stmt(it ast.ForInStmt) {
|
||||
if it.label.len > 0 {
|
||||
g.writeln('\t$it.label: {}')
|
||||
fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
|
||||
if node.label.len > 0 {
|
||||
g.writeln('\t$node.label: {}')
|
||||
}
|
||||
if it.is_range {
|
||||
if node.is_range {
|
||||
// `for x in 1..10 {`
|
||||
i := if it.val_var == '_' { g.new_tmp_var() } else { c_name(it.val_var) }
|
||||
i := if node.val_var == '_' { g.new_tmp_var() } else { c_name(node.val_var) }
|
||||
g.write('for (int $i = ')
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.write('; $i < ')
|
||||
g.expr(it.high)
|
||||
g.expr(node.high)
|
||||
g.writeln('; ++$i) {')
|
||||
} else if it.kind == .array {
|
||||
} else if node.kind == .array {
|
||||
// `for num in nums {`
|
||||
g.writeln('// FOR IN array')
|
||||
styp := g.typ(it.val_type)
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
styp := g.typ(node.val_type)
|
||||
val_sym := g.table.get_type_symbol(node.val_type)
|
||||
tmp := g.new_tmp_var()
|
||||
g.write(g.typ(it.cond_type))
|
||||
g.write(g.typ(node.cond_type))
|
||||
g.write(' $tmp = ')
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln(';')
|
||||
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||
op_field := if it.cond_type.is_ptr() { '->' } else { '.' } +
|
||||
if it.cond_type.share() == .shared_t { 'val.' } else { '' }
|
||||
i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
|
||||
op_field := if node.cond_type.is_ptr() { '->' } else { '.' } +
|
||||
if node.cond_type.share() == .shared_t { 'val.' } else { '' }
|
||||
g.writeln('for (int $i = 0; $i < $tmp${op_field}len; ++$i) {')
|
||||
if it.val_var != '_' {
|
||||
if node.val_var != '_' {
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var))
|
||||
g.writeln(' = ((voidptr*)$tmp${op_field}data)[$i];')
|
||||
} else {
|
||||
// If val is mutable (pointer behind the scenes), we need to generate
|
||||
// `int* val = ((int*)arr.data) + i;`
|
||||
// instead of
|
||||
// `int* val = ((int**)arr.data)[i];`
|
||||
// right := if it.val_is_mut { styp } else { styp + '*' }
|
||||
right := if it.val_is_mut {
|
||||
// right := if node.val_is_mut { styp } else { styp + '*' }
|
||||
right := if node.val_is_mut {
|
||||
'(($styp)$tmp${op_field}data) + $i'
|
||||
} else {
|
||||
'(($styp*)$tmp${op_field}data)[$i]'
|
||||
}
|
||||
g.writeln('\t$styp ${c_name(it.val_var)} = $right;')
|
||||
g.writeln('\t$styp ${c_name(node.val_var)} = $right;')
|
||||
}
|
||||
}
|
||||
} else if it.kind == .array_fixed {
|
||||
} else if node.kind == .array_fixed {
|
||||
atmp := g.new_tmp_var()
|
||||
atmp_type := g.typ(it.cond_type).trim('*')
|
||||
if it.cond_type.is_ptr() || it.cond is ast.ArrayInit {
|
||||
if !it.cond.is_lvalue() {
|
||||
atmp_type := g.typ(node.cond_type).trim('*')
|
||||
if node.cond_type.is_ptr() || node.cond is ast.ArrayInit {
|
||||
if !node.cond.is_lvalue() {
|
||||
g.write('$atmp_type *$atmp = (($atmp_type)')
|
||||
} else {
|
||||
g.write('$atmp_type *$atmp = (')
|
||||
}
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln(');')
|
||||
}
|
||||
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||
cond_sym := g.table.get_type_symbol(it.cond_type)
|
||||
i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
|
||||
cond_sym := g.table.get_type_symbol(node.cond_type)
|
||||
info := cond_sym.info as table.ArrayFixed
|
||||
g.writeln('for (int $i = 0; $i != $info.size; ++$i) {')
|
||||
if it.val_var != '_' {
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
if node.val_var != '_' {
|
||||
val_sym := g.table.get_type_symbol(node.val_type)
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var))
|
||||
} else {
|
||||
styp := g.typ(it.val_type)
|
||||
g.write('\t$styp ${c_name(it.val_var)}')
|
||||
styp := g.typ(node.val_type)
|
||||
g.write('\t$styp ${c_name(node.val_var)}')
|
||||
}
|
||||
addr := if it.val_is_mut { '&' } else { '' }
|
||||
if it.cond_type.is_ptr() || it.cond is ast.ArrayInit {
|
||||
addr := if node.val_is_mut { '&' } else { '' }
|
||||
if node.cond_type.is_ptr() || node.cond is ast.ArrayInit {
|
||||
g.writeln(' = ${addr}(*$atmp)[$i];')
|
||||
} else {
|
||||
g.write(' = $addr')
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln('[$i];')
|
||||
}
|
||||
}
|
||||
} else if it.kind == .map {
|
||||
} else if node.kind == .map {
|
||||
// `for key, val in map {
|
||||
g.writeln('// FOR IN map')
|
||||
idx := g.new_tmp_var()
|
||||
atmp := g.new_tmp_var()
|
||||
arw_or_pt := if it.cond_type.is_ptr() { '->' } else { '.' }
|
||||
g.write(g.typ(it.cond_type))
|
||||
arw_or_pt := if node.cond_type.is_ptr() { '->' } else { '.' }
|
||||
g.write(g.typ(node.cond_type))
|
||||
g.write(' $atmp = ')
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln(';')
|
||||
g.writeln('for (int $idx = 0; $idx < $atmp${arw_or_pt}key_values.len; ++$idx) {')
|
||||
// TODO: don't have this check when the map has no deleted elements
|
||||
g.writeln('\tif (!DenseArray_has_index(&$atmp${arw_or_pt}key_values, $idx)) {continue;}')
|
||||
if it.key_var != '_' {
|
||||
key_styp := g.typ(it.key_type)
|
||||
key := c_name(it.key_var)
|
||||
if node.key_var != '_' {
|
||||
key_styp := g.typ(node.key_type)
|
||||
key := c_name(node.key_var)
|
||||
g.writeln('\t$key_styp $key = /*key*/ *($key_styp*)DenseArray_key(&$atmp${arw_or_pt}key_values, $idx);')
|
||||
// TODO: analyze whether it.key_type has a .clone() method and call .clone() for all types:
|
||||
if it.key_type == table.string_type {
|
||||
// TODO: analyze whether node.key_type has a .clone() method and call .clone() for all types:
|
||||
if node.key_type == table.string_type {
|
||||
g.writeln('\t$key = string_clone($key);')
|
||||
}
|
||||
}
|
||||
if it.val_var != '_' {
|
||||
val_sym := g.table.get_type_symbol(it.val_type)
|
||||
if node.val_var != '_' {
|
||||
val_sym := g.table.get_type_symbol(node.val_type)
|
||||
if val_sym.kind == .function {
|
||||
g.write('\t')
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
|
||||
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(node.val_var))
|
||||
g.write(' = (*(voidptr*)')
|
||||
} else {
|
||||
val_styp := g.typ(it.val_type)
|
||||
if it.val_type.is_ptr() {
|
||||
g.write('\t$val_styp ${c_name(it.val_var)} = &(*($val_styp)')
|
||||
val_styp := g.typ(node.val_type)
|
||||
if node.val_type.is_ptr() {
|
||||
g.write('\t$val_styp ${c_name(node.val_var)} = &(*($val_styp)')
|
||||
} else {
|
||||
g.write('\t$val_styp ${c_name(it.val_var)} = (*($val_styp*)')
|
||||
g.write('\t$val_styp ${c_name(node.val_var)} = (*($val_styp*)')
|
||||
}
|
||||
}
|
||||
g.writeln('DenseArray_value(&$atmp${arw_or_pt}key_values, $idx));')
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
if it.key_type == table.string_type && !g.is_builtin_mod {
|
||||
g.stmts(node.stmts)
|
||||
if node.key_type == table.string_type && !g.is_builtin_mod {
|
||||
// g.writeln('string_free(&$key);')
|
||||
}
|
||||
if it.label.len > 0 {
|
||||
g.writeln('\t${it.label}__continue: {}')
|
||||
if node.label.len > 0 {
|
||||
g.writeln('\t${node.label}__continue: {}')
|
||||
}
|
||||
g.writeln('}')
|
||||
if it.label.len > 0 {
|
||||
g.writeln('\t${it.label}__break: {}')
|
||||
if node.label.len > 0 {
|
||||
g.writeln('\t${node.label}__break: {}')
|
||||
}
|
||||
return
|
||||
} else if it.kind == .string {
|
||||
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||
} else if node.kind == .string {
|
||||
i := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
|
||||
g.write('for (int $i = 0; $i < ')
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln('.len; ++$i) {')
|
||||
if it.val_var != '_' {
|
||||
g.write('\tbyte ${c_name(it.val_var)} = ')
|
||||
g.expr(it.cond)
|
||||
if node.val_var != '_' {
|
||||
g.write('\tbyte ${c_name(node.val_var)} = ')
|
||||
g.expr(node.cond)
|
||||
g.writeln('.str[$i];')
|
||||
}
|
||||
} else if it.kind == .struct_ {
|
||||
cond_type_sym := g.table.get_type_symbol(it.cond_type)
|
||||
} else if node.kind == .struct_ {
|
||||
cond_type_sym := g.table.get_type_symbol(node.cond_type)
|
||||
next_fn := cond_type_sym.find_method('next') or {
|
||||
verror('`next` method not found')
|
||||
return
|
||||
|
@ -1485,26 +1485,26 @@ fn (mut g Gen) for_in_stmt(it ast.ForInStmt) {
|
|||
receiver_styp := g.typ(next_fn.params[0].typ)
|
||||
fn_name := receiver_styp.replace_each(['*', '', '.', '__']) + '_next'
|
||||
g.write('\t${g.typ(ret_typ)} $t = ${fn_name}(')
|
||||
if !it.cond_type.is_ptr() {
|
||||
if !node.cond_type.is_ptr() {
|
||||
g.write('&')
|
||||
}
|
||||
g.expr(it.cond)
|
||||
g.expr(node.cond)
|
||||
g.writeln(');')
|
||||
g.writeln('\tif (!${t}.ok) { break; }')
|
||||
val := if it.val_var in ['', '_'] { g.new_tmp_var() } else { it.val_var }
|
||||
val_styp := g.typ(it.val_type)
|
||||
val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
|
||||
val_styp := g.typ(node.val_type)
|
||||
g.writeln('\t$val_styp $val = *($val_styp*)${t}.data;')
|
||||
} else {
|
||||
s := g.table.type_to_str(it.cond_type)
|
||||
g.error('for in: unhandled symbol `$it.cond` of type `$s`', it.pos)
|
||||
s := g.table.type_to_str(node.cond_type)
|
||||
g.error('for in: unhandled symbol `$node.cond` of type `$s`', node.pos)
|
||||
}
|
||||
g.stmts(it.stmts)
|
||||
if it.label.len > 0 {
|
||||
g.writeln('\t${it.label}__continue: {}')
|
||||
g.stmts(node.stmts)
|
||||
if node.label.len > 0 {
|
||||
g.writeln('\t${node.label}__continue: {}')
|
||||
}
|
||||
g.writeln('}')
|
||||
if it.label.len > 0 {
|
||||
g.writeln('\t${it.label}__break: {}')
|
||||
if node.label.len > 0 {
|
||||
g.writeln('\t${node.label}__break: {}')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue