cgen: minor cleanup infix_expr (#9445)

pull/9457/head
zakuro 2021-03-25 06:21:54 +09:00 committed by GitHub
parent 6bc9ef7373
commit 837cada30c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 204 additions and 183 deletions

View File

@ -3300,6 +3300,206 @@ fn (mut g Gen) enum_expr(node ast.Expr) {
}
}
fn (mut g Gen) infix_gen_equality(node ast.InfixExpr, left_type table.Type, left_sym table.TypeSymbol, right_sym table.TypeSymbol) {
has_eq_overloaded := left_sym.has_method('==')
if left_sym.kind != right_sym.kind {
return
}
match left_sym.kind {
.array {
ptr_typ := g.gen_array_equality_fn(left_type.clear_flag(.shared_f))
if node.op == .ne {
g.write('!')
}
g.write('${ptr_typ}_arr_eq(')
if node.left_type.is_ptr() && !node.left_type.has_flag(.shared_f) {
g.write('*')
}
g.expr(node.left)
if node.left_type.has_flag(.shared_f) {
if node.left_type.is_ptr() {
g.write('->val')
} else {
g.write('.val')
}
}
g.write(', ')
if node.right_type.is_ptr() && !node.right_type.has_flag(.shared_f) {
g.write('*')
}
g.expr(node.right)
if node.right_type.has_flag(.shared_f) {
if node.right_type.is_ptr() {
g.write('->val')
} else {
g.write('.val')
}
}
g.write(')')
}
.array_fixed {
ptr_typ := g.gen_fixed_array_equality_fn(left_type)
if node.op == .ne {
g.write('!')
}
g.write('${ptr_typ}_arr_eq(')
if node.left_type.is_ptr() {
g.write('*')
}
if node.left is ast.ArrayInit {
s := g.typ(left_type)
g.write('($s)')
}
g.expr(node.left)
g.write(', ')
if node.right is ast.ArrayInit {
s := g.typ(left_type)
g.write('($s)')
}
g.expr(node.right)
g.write(')')
}
.alias {
ptr_typ := g.gen_alias_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_alias_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_alias_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
}
.map {
ptr_typ := g.gen_map_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_map_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_map_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
}
.struct_ {
if has_eq_overloaded {
// Define `==` as negation of Autogenerated `!=`
styp := g.typ(left_type)
if node.op == .ne {
g.write('!${styp}__eq(')
} else if node.op == .eq {
g.write('${styp}__eq(')
}
} else {
// Auto generate both `==` and `!=`
ptr_typ := g.gen_struct_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_struct_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_struct_eq(')
}
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
}
.sum_type {
ptr_typ := g.gen_sumtype_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_sumtype_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_sumtype_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
}
else {}
}
}
fn (mut g Gen) infix_in_or_not_in(node ast.InfixExpr, left_sym table.TypeSymbol, right_sym table.TypeSymbol) {
if node.op == .not_in {
g.write('!')
}
if right_sym.kind == .array {
if mut node.right is ast.ArrayInit {
if node.right.exprs.len > 0 {
// `a in [1,2,3]` optimization => `a == 1 || a == 2 || a == 3`
// avoids an allocation
// g.write('/*in opt*/')
g.write('(')
g.in_optimization(node.left, node.right)
g.write(')')
return
}
}
fn_name := g.gen_array_contains_method(node.right_type)
g.write('(${fn_name}(')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write('))')
return
} else if right_sym.kind == .map {
g.write('_IN_MAP(')
if !node.left_type.is_ptr() {
left_type_str := g.table.type_to_str(node.left_type)
g.write('ADDR($left_type_str, ')
g.expr(node.left)
g.write(')')
} else {
g.expr(node.left)
}
g.write(', ')
if !node.right_type.is_ptr() {
g.write('ADDR(map, ')
g.expr(node.right)
g.write(')')
} else {
g.expr(node.right)
}
g.write(')')
} else if right_sym.kind == .string {
g.write('string_contains(')
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write(')')
}
}
fn (mut g Gen) infix_expr(node ast.InfixExpr) {
if node.auto_locked != '' {
g.writeln('sync__RwMutex_lock(&$node.auto_locked->mtx);')
@ -3321,7 +3521,6 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
op_is_eq_or_ne := node.op in [.eq, .ne]
right_sym := g.table.get_type_symbol(node.right_type)
right_final_sym := g.table.get_final_type_symbol(node.right_type)
has_eq_overloaded := !left_sym.has_method('==')
unaliased_right := if right_sym.info is table.Alias {
right_sym.info.parent_type
} else {
@ -3403,189 +3602,11 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
g.expr(node.right)
g.write(')')
}
} else if op_is_eq_or_ne && left_sym.kind == .array && right_sym.kind == .array {
ptr_typ := g.gen_array_equality_fn(left_type.clear_flag(.shared_f))
if node.op == .ne {
g.write('!')
}
g.write('${ptr_typ}_arr_eq(')
if node.left_type.is_ptr() && !node.left_type.has_flag(.shared_f) {
g.write('*')
}
g.expr(node.left)
if node.left_type.has_flag(.shared_f) {
if node.left_type.is_ptr() {
g.write('->val')
} else {
g.write('.val')
}
}
g.write(', ')
if node.right_type.is_ptr() && !node.right_type.has_flag(.shared_f) {
g.write('*')
}
g.expr(node.right)
if node.right_type.has_flag(.shared_f) {
if node.right_type.is_ptr() {
g.write('->val')
} else {
g.write('.val')
}
}
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == .array_fixed && right_sym.kind == .array_fixed {
ptr_typ := g.gen_fixed_array_equality_fn(left_type)
if node.op == .ne {
g.write('!')
}
g.write('${ptr_typ}_arr_eq(')
if node.left_type.is_ptr() {
g.write('*')
}
if node.left is ast.ArrayInit {
s := g.typ(left_type)
g.write('($s)')
}
g.expr(node.left)
g.write(', ')
if node.right is ast.ArrayInit {
s := g.typ(left_type)
g.write('($s)')
}
g.expr(node.right)
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == .alias && right_sym.kind == .alias {
ptr_typ := g.gen_alias_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_alias_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_alias_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == .map && right_sym.kind == .map {
ptr_typ := g.gen_map_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_map_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_map_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == .struct_ && right_sym.kind == .struct_ {
if !has_eq_overloaded {
// Define `==` as negation of Autogenerated `!=`
styp := g.typ(left_type)
if node.op == .ne {
g.write('!${styp}__eq(')
} else if node.op == .eq {
g.write('${styp}__eq(')
}
}
if has_eq_overloaded {
// Auto generate both `==` and `!=`
ptr_typ := g.gen_struct_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_struct_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_struct_eq(')
}
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == .sum_type && right_sym.kind == .sum_type {
ptr_typ := g.gen_sumtype_equality_fn(left_type)
if node.op == .eq {
g.write('${ptr_typ}_sumtype_eq(')
} else if node.op == .ne {
g.write('!${ptr_typ}_sumtype_eq(')
}
if node.left_type.is_ptr() {
g.write('*')
}
g.expr(node.left)
g.write(', ')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(')')
} else if op_is_eq_or_ne && left_sym.kind == right_sym.kind
&& left_sym.kind in [.array, .array_fixed, .alias, .map, .struct_, .sum_type] {
g.infix_gen_equality(node, left_type, left_sym, right_sym)
} else if op_is_key_in_or_not_in {
if node.op == .not_in {
g.write('!')
}
if right_sym.kind == .array {
if mut node.right is ast.ArrayInit {
if node.right.exprs.len > 0 {
// `a in [1,2,3]` optimization => `a == 1 || a == 2 || a == 3`
// avoids an allocation
// g.write('/*in opt*/')
g.write('(')
g.in_optimization(node.left, node.right)
g.write(')')
return
}
}
fn_name := g.gen_array_contains_method(node.right_type)
g.write('(${fn_name}(')
if node.right_type.is_ptr() {
g.write('*')
}
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write('))')
return
} else if right_sym.kind == .map {
g.write('_IN_MAP(')
if !node.left_type.is_ptr() {
left_type_str := g.table.type_to_str(node.left_type)
g.write('ADDR($left_type_str, ')
g.expr(node.left)
g.write(')')
} else {
g.expr(node.left)
}
g.write(', ')
if !node.right_type.is_ptr() {
g.write('ADDR(map, ')
g.expr(node.right)
g.write(')')
} else {
g.expr(node.right)
}
g.write(')')
} else if right_sym.kind == .string {
g.write('string_contains(')
g.expr(node.right)
g.write(', ')
g.expr(node.left)
g.write(')')
}
g.infix_in_or_not_in(node, left_sym, right_sym)
} else if node.op == .left_shift && left_final_sym.kind == .array {
// arr << val
tmp := g.new_tmp_var()