cgen: remove unneeded sumtype logic and add more tests (#6959)
parent
52b627feb3
commit
c6a8c3cad5
|
@ -109,8 +109,6 @@ mut:
|
|||
inside_const bool
|
||||
comp_for_method string // $for method in T {
|
||||
comptime_var_type_map map[string]table.Type
|
||||
match_sumtype_exprs []ast.Expr
|
||||
match_sumtype_syms []table.TypeSymbol
|
||||
// tmp_arg_vars_to_free []string
|
||||
// autofree_pregen map[string]string
|
||||
// autofree_pregen_buf strings.Builder
|
||||
|
@ -2342,9 +2340,6 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
g.write(node.val)
|
||||
}
|
||||
ast.Ident {
|
||||
if g.should_write_asterisk_due_to_match_sumtype(node) {
|
||||
g.write('*')
|
||||
}
|
||||
g.ident(node)
|
||||
}
|
||||
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) {
|
||||
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 {
|
||||
mut sumtype_index := 0
|
||||
// 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))
|
||||
}
|
||||
|
||||
[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) {
|
||||
styp := g.typ(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('/*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' &&
|
||||
!g.should_write_asterisk_due_to_match_sumtype(node.left) {
|
||||
if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name == 'str' {
|
||||
g.write('ptr_str(')
|
||||
} else {
|
||||
g.write('${name}(')
|
||||
|
|
|
@ -36,6 +36,25 @@ fn test_sum_type_match() {
|
|||
assert get_sum('3', int(5)) == 8.0
|
||||
assert get_sum('3', f64(1.2)) == 4.2
|
||||
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
|
||||
|
@ -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
|
||||
|
||||
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 {
|
||||
is_literal := e is IntegerLiteral
|
||||
assert is_literal
|
||||
|
|
Loading…
Reference in New Issue