mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: remove unneeded sumtype logic and add more tests (#6959)
This commit is contained in:
parent
52b627feb3
commit
c6a8c3cad5
@ -109,8 +109,6 @@ mut:
|
|||||||
inside_const bool
|
inside_const bool
|
||||||
comp_for_method string // $for method in T {
|
comp_for_method string // $for method in T {
|
||||||
comptime_var_type_map map[string]table.Type
|
comptime_var_type_map map[string]table.Type
|
||||||
match_sumtype_exprs []ast.Expr
|
|
||||||
match_sumtype_syms []table.TypeSymbol
|
|
||||||
// tmp_arg_vars_to_free []string
|
// tmp_arg_vars_to_free []string
|
||||||
// autofree_pregen map[string]string
|
// autofree_pregen map[string]string
|
||||||
// autofree_pregen_buf strings.Builder
|
// autofree_pregen_buf strings.Builder
|
||||||
@ -2342,9 +2340,6 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||||||
g.write(node.val)
|
g.write(node.val)
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
if g.should_write_asterisk_due_to_match_sumtype(node) {
|
|
||||||
g.write('*')
|
|
||||||
}
|
|
||||||
g.ident(node)
|
g.ident(node)
|
||||||
}
|
}
|
||||||
ast.IfExpr {
|
ast.IfExpr {
|
||||||
@ -3040,13 +3035,6 @@ fn (mut g Gen) match_expr(node ast.MatchExpr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var string) {
|
fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var string) {
|
||||||
type_sym := g.table.get_type_symbol(node.cond_type)
|
|
||||||
g.match_sumtype_exprs << node.cond
|
|
||||||
g.match_sumtype_syms << type_sym
|
|
||||||
defer {
|
|
||||||
g.match_sumtype_exprs.delete_last()
|
|
||||||
g.match_sumtype_syms.delete_last()
|
|
||||||
}
|
|
||||||
for j, branch in node.branches {
|
for j, branch in node.branches {
|
||||||
mut sumtype_index := 0
|
mut sumtype_index := 0
|
||||||
// iterates through all types in sumtype branches
|
// iterates through all types in sumtype branches
|
||||||
@ -3392,37 +3380,6 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||||||
g.write(g.get_ternary_name(name))
|
g.write(g.get_ternary_name(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
[unlikely]
|
|
||||||
fn (mut g Gen) should_write_asterisk_due_to_match_sumtype(expr ast.Expr) bool {
|
|
||||||
if expr is ast.Ident {
|
|
||||||
typ := if expr.info is ast.IdentVar { (expr.info as ast.IdentVar).typ } else { (expr.info as ast.IdentFn).typ }
|
|
||||||
return typ.is_ptr() && g.match_sumtype_has_no_struct_and_contains(expr)
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[unlikely]
|
|
||||||
fn (mut g Gen) match_sumtype_has_no_struct_and_contains(node ast.Ident) bool {
|
|
||||||
for i, expr in g.match_sumtype_exprs {
|
|
||||||
if expr is ast.Ident && node.name == (expr as ast.Ident).name {
|
|
||||||
info := g.match_sumtype_syms[i].info
|
|
||||||
match info {
|
|
||||||
table.SumType {
|
|
||||||
for typ in info.variants {
|
|
||||||
if g.table.get_type_symbol(typ).kind == .struct_ {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
|
fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
|
||||||
styp := g.typ(node.return_type)
|
styp := g.typ(node.return_type)
|
||||||
sym := g.table.get_type_symbol(node.return_type)
|
sym := g.table.get_type_symbol(node.return_type)
|
||||||
|
@ -419,8 +419,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
|||||||
// g.write('/*${g.typ(node.receiver_type)}*/')
|
// g.write('/*${g.typ(node.receiver_type)}*/')
|
||||||
// g.write('/*expr_type=${g.typ(node.left_type)} rec type=${g.typ(node.receiver_type)}*/')
|
// g.write('/*expr_type=${g.typ(node.left_type)} rec type=${g.typ(node.receiver_type)}*/')
|
||||||
// }
|
// }
|
||||||
if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name == 'str' &&
|
if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name == 'str' {
|
||||||
!g.should_write_asterisk_due_to_match_sumtype(node.left) {
|
|
||||||
g.write('ptr_str(')
|
g.write('ptr_str(')
|
||||||
} else {
|
} else {
|
||||||
g.write('${name}(')
|
g.write('${name}(')
|
||||||
|
@ -36,6 +36,25 @@ fn test_sum_type_match() {
|
|||||||
assert get_sum('3', int(5)) == 8.0
|
assert get_sum('3', int(5)) == 8.0
|
||||||
assert get_sum('3', f64(1.2)) == 4.2
|
assert get_sum('3', f64(1.2)) == 4.2
|
||||||
assert get_sum('3', f64(3.5)) == 6.5
|
assert get_sum('3', f64(3.5)) == 6.5
|
||||||
|
assert verify_complex_expr(int(1), false)
|
||||||
|
assert !verify_complex_expr(int(2), false)
|
||||||
|
assert verify_complex_expr(f64(2.5), false)
|
||||||
|
assert !verify_complex_expr(f64(1.5), false)
|
||||||
|
assert verify_complex_expr(int(0), true)
|
||||||
|
assert as_string(int(1)) == 'This is the string representation of "1"'
|
||||||
|
assert as_string(f64(3.14)) == 'This is the string representation of "3.14"'
|
||||||
|
assert as_string('String') == 'This is the string representation of "String"'
|
||||||
|
assert as_string(IntAndStr{foo: 2, bar: 'hi', baz: &IntAndStr{foo: 3, bar: 'hello', baz: 0}}) == 'This is the string representation of "5_hi_hello"'
|
||||||
|
assert as_string(true) == 'This is the string representation of "true"'
|
||||||
|
assert as_string(CommonType(Color.red)) == 'This is the string representation of "enum1_red"'
|
||||||
|
assert as_string(CommonType(Color.green)) == 'This is the string representation of "enum2_green"'
|
||||||
|
assert as_string(CommonType(Color.blue)) == 'This is the string representation of "enum3_blue"'
|
||||||
|
assert sumtype_match_with_string_interpolation(1) == "it's an int: 5"
|
||||||
|
assert sumtype_match_with_string_interpolation(2) == "it's a string: hello"
|
||||||
|
assert sumtype_match_with_string_interpolation(3) == "green_green"
|
||||||
|
assert sumtype_match_with_string_interpolation(4) == "it's a f64: 1.5"
|
||||||
|
assert sumtype_match_with_string_interpolation(5) == "it's a bool: false"
|
||||||
|
assert sumtype_match_with_string_interpolation(6) == "it's an IntAndStr: 2_hi_3_hello"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test moving structs between master/sub arrays
|
// Test moving structs between master/sub arrays
|
||||||
@ -235,7 +254,6 @@ fn test_int_cast_to_sumtype() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: change definition once types other than int and f64 (int, f64, etc) are supported in sumtype
|
|
||||||
type Number = int | f64
|
type Number = int | f64
|
||||||
|
|
||||||
fn is_gt_simple(val string, dst Number) bool {
|
fn is_gt_simple(val string, dst Number) bool {
|
||||||
@ -307,6 +325,166 @@ fn get_sum(val string, dst Number) f64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_complex_expr(dst Number, get_final bool) bool {
|
||||||
|
if !get_final {
|
||||||
|
match dst {
|
||||||
|
int {
|
||||||
|
dst2 := dst
|
||||||
|
dst3 := dst2
|
||||||
|
dst4 := (dst2 + dst3).str()
|
||||||
|
temp := 2 * dst3 + 1
|
||||||
|
res := temp - 3
|
||||||
|
foo := 1 + dst - dst2
|
||||||
|
dst5 := foo.str().int().str()
|
||||||
|
return (foo + res) * res - res == 0 && dst4.len == 1 && dst5.len == 1
|
||||||
|
}
|
||||||
|
f64 {
|
||||||
|
dst2 := dst
|
||||||
|
dst3, foo := dst2, 2
|
||||||
|
mut dst4 := dst3 + 1
|
||||||
|
dst4 = dst / 1
|
||||||
|
dst4 -= dst2
|
||||||
|
mut temp := foo - 4
|
||||||
|
temp += foo * (foo - 1)
|
||||||
|
bar := !(dst2 < 1) && dst3 - foo - temp > 0 && dst4 == 0
|
||||||
|
return bar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo := 10
|
||||||
|
temp := foo
|
||||||
|
return temp + 10 == 20
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IntAndStr {
|
||||||
|
foo int
|
||||||
|
bar string
|
||||||
|
baz &IntAndStr
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Color { red green blue }
|
||||||
|
|
||||||
|
type CommonType = int | f64 | string | IntAndStr | bool | Color
|
||||||
|
|
||||||
|
fn as_string(val CommonType) string {
|
||||||
|
return 'This is the string representation of "' + val.str() + '"'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (c CommonType) str() string {
|
||||||
|
match c {
|
||||||
|
string {
|
||||||
|
d := c.int()
|
||||||
|
e := d
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
int {
|
||||||
|
d := c
|
||||||
|
e := c + d - d
|
||||||
|
return e.str()
|
||||||
|
}
|
||||||
|
f64 {
|
||||||
|
return c.str()
|
||||||
|
}
|
||||||
|
IntAndStr {
|
||||||
|
return (c.foo + c.baz.foo).str() + '_' + c.bar + '_' + c.baz.bar
|
||||||
|
}
|
||||||
|
bool {
|
||||||
|
d := c
|
||||||
|
return if d { 'true' } else { 'false' }
|
||||||
|
}
|
||||||
|
Color {
|
||||||
|
d := c
|
||||||
|
match d {
|
||||||
|
.red { return 'enum1_' + d.str() }
|
||||||
|
.green { return 'enum2_' + d.str() }
|
||||||
|
.blue { return 'enum3_' + d.str() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sumtype_match_with_string_interpolation(code int) string {
|
||||||
|
match code {
|
||||||
|
1 {
|
||||||
|
bar := CommonType(5)
|
||||||
|
match bar {
|
||||||
|
f64 { return "shouldn't happen" }
|
||||||
|
bool { return "shouldn't happen" }
|
||||||
|
IntAndStr { return "shouldn't happen" }
|
||||||
|
int { return "it's an int: $bar" }
|
||||||
|
string { return "shouldn't happen" }
|
||||||
|
Color { return "shouldn't happen" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2 {
|
||||||
|
bar := CommonType('hello')
|
||||||
|
match bar {
|
||||||
|
string { return "it's a string: $bar" }
|
||||||
|
int { return "shouldn't happen" }
|
||||||
|
Color { return "shouldn't happen" }
|
||||||
|
f64 { return "shouldn't happen" }
|
||||||
|
bool { return "shouldn't happen" }
|
||||||
|
IntAndStr { return "shouldn't happen" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
3 {
|
||||||
|
bar := CommonType(Color.green)
|
||||||
|
match bar {
|
||||||
|
string { return "shouldn't happen" }
|
||||||
|
int { return "shouldn't happen" }
|
||||||
|
f64 { return "shouldn't happen" }
|
||||||
|
bool { return "shouldn't happen" }
|
||||||
|
IntAndStr { return "shouldn't happen" }
|
||||||
|
Color {
|
||||||
|
match bar {
|
||||||
|
.red { return 'red_$bar'}
|
||||||
|
.green { return 'green_$bar' }
|
||||||
|
.blue { return 'blue_$bar' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
4 {
|
||||||
|
bar := CommonType(1.5)
|
||||||
|
match bar {
|
||||||
|
string { return "shouldn't happen" }
|
||||||
|
int { return "shouldn't happen" }
|
||||||
|
Color { return "shouldn't happen" }
|
||||||
|
f64 { return "it's a f64: $bar" }
|
||||||
|
bool { return "shouldn't happen" }
|
||||||
|
IntAndStr { return "shouldn't happen" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
5 {
|
||||||
|
mut bar := CommonType('hello')
|
||||||
|
bar = CommonType(false)
|
||||||
|
match bar {
|
||||||
|
string { return "shouldn't happen" }
|
||||||
|
int { return "shouldn't happen" }
|
||||||
|
Color { return "shouldn't happen" }
|
||||||
|
f64 { return "shouldn't happen" }
|
||||||
|
bool { return "it's a bool: $bar" }
|
||||||
|
IntAndStr { return "shouldn't happen" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6 {
|
||||||
|
// TODO: this should work
|
||||||
|
// mut bar := CommonType(100)
|
||||||
|
// bar = CommonType(IntAndStr{foo: 2, bar: 'hi', baz: &IntAndStr{foo: 3, bar: 'hello', baz: 0}})
|
||||||
|
bar := CommonType(IntAndStr{foo: 2, bar: 'hi', baz: &IntAndStr{foo: 3, bar: 'hello', baz: 0}})
|
||||||
|
match bar {
|
||||||
|
string { return "shouldn't happen" }
|
||||||
|
int { return "shouldn't happen" }
|
||||||
|
Color { return "shouldn't happen" }
|
||||||
|
f64 { return "shouldn't happen" }
|
||||||
|
bool { return "shouldn't happen" }
|
||||||
|
IntAndStr { return "it's an IntAndStr: ${bar.foo}_${bar.bar}_${bar.baz.foo}_${bar.baz.bar}" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { return 'wrong' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle(e Expr) string {
|
fn handle(e Expr) string {
|
||||||
is_literal := e is IntegerLiteral
|
is_literal := e is IntegerLiteral
|
||||||
assert is_literal
|
assert is_literal
|
||||||
|
Loading…
Reference in New Issue
Block a user