parent
							
								
									9bc422a071
								
							
						
					
					
						commit
						14cec11cc6
					
				| 
						 | 
					@ -384,18 +384,18 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
 | 
				
			||||||
	clean_interface_v_type_name = util.strip_main_name(clean_interface_v_type_name)
 | 
						clean_interface_v_type_name = util.strip_main_name(clean_interface_v_type_name)
 | 
				
			||||||
	fn_builder.writeln('static string indent_${str_fn_name}($styp x, int indent_count) { /* gen_str_for_interface */')
 | 
						fn_builder.writeln('static string indent_${str_fn_name}($styp x, int indent_count) { /* gen_str_for_interface */')
 | 
				
			||||||
	for typ in info.types {
 | 
						for typ in info.types {
 | 
				
			||||||
		subtype := g.table.sym(typ)
 | 
							sub_sym := g.table.sym(ast.mktyp(typ))
 | 
				
			||||||
		mut func_name := g.get_str_fn(typ)
 | 
							mut func_name := g.get_str_fn(typ)
 | 
				
			||||||
		sym_has_str_method, str_method_expects_ptr, _ := subtype.str_method_info()
 | 
							sym_has_str_method, str_method_expects_ptr, _ := sub_sym.str_method_info()
 | 
				
			||||||
		if should_use_indent_func(subtype.kind) && !sym_has_str_method {
 | 
							if should_use_indent_func(sub_sym.kind) && !sym_has_str_method {
 | 
				
			||||||
			func_name = 'indent_$func_name'
 | 
								func_name = 'indent_$func_name'
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// str_intp
 | 
							// str_intp
 | 
				
			||||||
		deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
 | 
							deref := if sym_has_str_method && str_method_expects_ptr { ' ' } else { '*' }
 | 
				
			||||||
		if typ == ast.string_type {
 | 
							if typ == ast.string_type {
 | 
				
			||||||
			mut val := '${func_name}(${deref}($subtype.cname*)x._$subtype.cname'
 | 
								mut val := '${func_name}(${deref}($sub_sym.cname*)x._$sub_sym.cname'
 | 
				
			||||||
			if should_use_indent_func(subtype.kind) && !sym_has_str_method {
 | 
								if should_use_indent_func(sub_sym.kind) && !sym_has_str_method {
 | 
				
			||||||
				val += ', indent_count'
 | 
									val += ', indent_count'
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			val += ')'
 | 
								val += ')'
 | 
				
			||||||
| 
						 | 
					@ -403,11 +403,11 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
 | 
				
			||||||
				{_SLIT("${clean_interface_v_type_name}(\'"), $c.si_s_code, {.d_s = $val}},
 | 
									{_SLIT("${clean_interface_v_type_name}(\'"), $c.si_s_code, {.d_s = $val}},
 | 
				
			||||||
				{_SLIT("\')"), 0, {.d_c = 0 }}
 | 
									{_SLIT("\')"), 0, {.d_c = 0 }}
 | 
				
			||||||
			}))'
 | 
								}))'
 | 
				
			||||||
			fn_builder.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
 | 
								fn_builder.write_string('\tif (x._typ == _${styp}_${sub_sym.cname}_index)')
 | 
				
			||||||
			fn_builder.write_string(' return $res;')
 | 
								fn_builder.write_string(' return $res;')
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			mut val := '${func_name}(${deref}($subtype.cname*)x._$subtype.cname'
 | 
								mut val := '${func_name}(${deref}($sub_sym.cname*)x._$sub_sym.cname'
 | 
				
			||||||
			if should_use_indent_func(subtype.kind) && !sym_has_str_method {
 | 
								if should_use_indent_func(sub_sym.kind) && !sym_has_str_method {
 | 
				
			||||||
				val += ', indent_count'
 | 
									val += ', indent_count'
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			val += ')'
 | 
								val += ')'
 | 
				
			||||||
| 
						 | 
					@ -415,7 +415,7 @@ fn (mut g Gen) gen_str_for_interface(info ast.Interface, styp string, str_fn_nam
 | 
				
			||||||
				{_SLIT("${clean_interface_v_type_name}("), $c.si_s_code, {.d_s = $val}},
 | 
									{_SLIT("${clean_interface_v_type_name}("), $c.si_s_code, {.d_s = $val}},
 | 
				
			||||||
				{_SLIT(")"), 0, {.d_c = 0 }}
 | 
									{_SLIT(")"), 0, {.d_c = 0 }}
 | 
				
			||||||
			}))'
 | 
								}))'
 | 
				
			||||||
			fn_builder.write_string('\tif (x._typ == _${styp}_${subtype.cname}_index)')
 | 
								fn_builder.write_string('\tif (x._typ == _${styp}_${sub_sym.cname}_index)')
 | 
				
			||||||
			fn_builder.write_string(' return $res;\n')
 | 
								fn_builder.write_string(' return $res;\n')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -859,16 +859,16 @@ pub fn (mut g Gen) write_typeof_functions() {
 | 
				
			||||||
			g.definitions.writeln('static char * v_typeof_interface_${sym.cname}(int sidx);')
 | 
								g.definitions.writeln('static char * v_typeof_interface_${sym.cname}(int sidx);')
 | 
				
			||||||
			g.writeln('static char * v_typeof_interface_${sym.cname}(int sidx) { /* $sym.name */ ')
 | 
								g.writeln('static char * v_typeof_interface_${sym.cname}(int sidx) { /* $sym.name */ ')
 | 
				
			||||||
			for t in inter_info.types {
 | 
								for t in inter_info.types {
 | 
				
			||||||
				subtype := g.table.sym(t)
 | 
									sub_sym := g.table.sym(ast.mktyp(t))
 | 
				
			||||||
				g.writeln('\tif (sidx == _${sym.cname}_${subtype.cname}_index) return "${util.strip_main_name(subtype.name)}";')
 | 
									g.writeln('\tif (sidx == _${sym.cname}_${sub_sym.cname}_index) return "${util.strip_main_name(sub_sym.name)}";')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			g.writeln('\treturn "unknown ${util.strip_main_name(sym.name)}";')
 | 
								g.writeln('\treturn "unknown ${util.strip_main_name(sym.name)}";')
 | 
				
			||||||
			g.writeln('}')
 | 
								g.writeln('}')
 | 
				
			||||||
			g.writeln('')
 | 
								g.writeln('')
 | 
				
			||||||
			g.writeln('static int v_typeof_interface_idx_${sym.cname}(int sidx) { /* $sym.name */ ')
 | 
								g.writeln('static int v_typeof_interface_idx_${sym.cname}(int sidx) { /* $sym.name */ ')
 | 
				
			||||||
			for t in inter_info.types {
 | 
								for t in inter_info.types {
 | 
				
			||||||
				subtype := g.table.sym(t)
 | 
									sub_sym := g.table.sym(ast.mktyp(t))
 | 
				
			||||||
				g.writeln('\tif (sidx == _${sym.cname}_${subtype.cname}_index) return ${int(t)};')
 | 
									g.writeln('\tif (sidx == _${sym.cname}_${sub_sym.cname}_index) return ${int(t)};')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			g.writeln('\treturn ${int(ityp)};')
 | 
								g.writeln('\treturn ${int(ityp)};')
 | 
				
			||||||
			g.writeln('}')
 | 
								g.writeln('}')
 | 
				
			||||||
| 
						 | 
					@ -1319,7 +1319,11 @@ pub fn (mut g Gen) write_interface_typesymbol_declaration(sym ast.TypeSymbol) {
 | 
				
			||||||
	g.type_definitions.writeln('\tunion {')
 | 
						g.type_definitions.writeln('\tunion {')
 | 
				
			||||||
	g.type_definitions.writeln('\t\tvoid* _object;')
 | 
						g.type_definitions.writeln('\t\tvoid* _object;')
 | 
				
			||||||
	for variant in info.types {
 | 
						for variant in info.types {
 | 
				
			||||||
		vcname := g.table.sym(variant).cname
 | 
							mk_typ := ast.mktyp(variant)
 | 
				
			||||||
 | 
							if mk_typ != variant && mk_typ in info.types {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							vcname := g.table.sym(mk_typ).cname
 | 
				
			||||||
		g.type_definitions.writeln('\t\t$vcname* _$vcname;')
 | 
							g.type_definitions.writeln('\t\t$vcname* _$vcname;')
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	g.type_definitions.writeln('\t};')
 | 
						g.type_definitions.writeln('\t};')
 | 
				
			||||||
| 
						 | 
					@ -2085,11 +2089,11 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
 | 
				
			||||||
		g.expr(expr)
 | 
							g.expr(expr)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if exp_sym.info is ast.Interface && got_type_raw.idx() != expected_type.idx()
 | 
						if exp_sym.info is ast.Interface && got_type.idx() != expected_type.idx()
 | 
				
			||||||
		&& !expected_type.has_flag(.optional) {
 | 
							&& !expected_type.has_flag(.optional) {
 | 
				
			||||||
		if expr is ast.StructInit && !got_type.is_ptr() {
 | 
							if expr is ast.StructInit && !got_type.is_ptr() {
 | 
				
			||||||
			g.inside_cast_in_heap++
 | 
								g.inside_cast_in_heap++
 | 
				
			||||||
			got_styp := g.cc_type(got_type_raw.ref(), true)
 | 
								got_styp := g.cc_type(got_type.ref(), true)
 | 
				
			||||||
			// TODO: why does cc_type even add this in the first place?
 | 
								// TODO: why does cc_type even add this in the first place?
 | 
				
			||||||
			exp_styp := exp_sym.cname
 | 
								exp_styp := exp_sym.cname
 | 
				
			||||||
			mut fname := 'I_${got_styp}_to_Interface_$exp_styp'
 | 
								mut fname := 'I_${got_styp}_to_Interface_$exp_styp'
 | 
				
			||||||
| 
						 | 
					@ -2100,7 +2104,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
 | 
				
			||||||
				got_styp)
 | 
									got_styp)
 | 
				
			||||||
			g.inside_cast_in_heap--
 | 
								g.inside_cast_in_heap--
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			got_styp := g.cc_type(got_type_raw, true)
 | 
								got_styp := g.cc_type(got_type, true)
 | 
				
			||||||
			got_is_shared := got_type.has_flag(.shared_f)
 | 
								got_is_shared := got_type.has_flag(.shared_f)
 | 
				
			||||||
			exp_styp := if got_is_shared { '__shared__$exp_sym.cname' } else { exp_sym.cname }
 | 
								exp_styp := if got_is_shared { '__shared__$exp_sym.cname' } else { exp_sym.cname }
 | 
				
			||||||
			// If it's shared, we need to use the other caster:
 | 
								// If it's shared, we need to use the other caster:
 | 
				
			||||||
| 
						 | 
					@ -5334,10 +5338,10 @@ fn (mut g Gen) interface_table() string {
 | 
				
			||||||
		iinidx_minimum_base := 1000 // Note: NOT 0, to avoid map entries set to 0 later, so `if already_generated_mwrappers[name] > 0 {` works.
 | 
							iinidx_minimum_base := 1000 // Note: NOT 0, to avoid map entries set to 0 later, so `if already_generated_mwrappers[name] > 0 {` works.
 | 
				
			||||||
		mut current_iinidx := iinidx_minimum_base
 | 
							mut current_iinidx := iinidx_minimum_base
 | 
				
			||||||
		for st in inter_info.types {
 | 
							for st in inter_info.types {
 | 
				
			||||||
			st_sym := g.table.sym(st)
 | 
								st_sym := g.table.sym(ast.mktyp(st))
 | 
				
			||||||
			// cctype is the Cleaned Concrete Type name, *without ptr*,
 | 
								// cctype is the Cleaned Concrete Type name, *without ptr*,
 | 
				
			||||||
			// i.e. cctype is always just Cat, not Cat_ptr:
 | 
								// i.e. cctype is always just Cat, not Cat_ptr:
 | 
				
			||||||
			cctype := g.cc_type(st, true)
 | 
								cctype := g.cc_type(ast.mktyp(st), true)
 | 
				
			||||||
			$if debug_interface_table ? {
 | 
								$if debug_interface_table ? {
 | 
				
			||||||
				eprintln('>> interface name: $isym.name | concrete type: $st.debug() | st symname: $st_sym.name')
 | 
									eprintln('>> interface name: $isym.name | concrete type: $st.debug() | st symname: $st_sym.name')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					interface Any {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn thing(any Any) string {
 | 
				
			||||||
 | 
						return match any {
 | 
				
			||||||
 | 
							int { 'int${*any:17}' }
 | 
				
			||||||
 | 
							f64 { 'f64${*any:20}' }
 | 
				
			||||||
 | 
							else { 'literal type tag?${any:10}' }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_cast_to_empty_interface() {
 | 
				
			||||||
 | 
						mut ret_strings := []string{}
 | 
				
			||||||
 | 
						mut arr := [Any(int(11)), int(22), Any(8888), 9999, Any(f64(1.11)), f64(2.22), Any(8.88), 9.99]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i in arr {
 | 
				
			||||||
 | 
							println(thing(i))
 | 
				
			||||||
 | 
							ret_strings << thing(i)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						assert ret_strings.len == 8
 | 
				
			||||||
 | 
						assert ret_strings[0] == 'int               11'
 | 
				
			||||||
 | 
						assert ret_strings[1] == 'int               22'
 | 
				
			||||||
 | 
						assert ret_strings[2] == 'int             8888'
 | 
				
			||||||
 | 
						assert ret_strings[3] == 'int             9999'
 | 
				
			||||||
 | 
						assert ret_strings[4] == 'f64               1.110'
 | 
				
			||||||
 | 
						assert ret_strings[5] == 'f64               2.220'
 | 
				
			||||||
 | 
						assert ret_strings[6] == 'f64               8.880'
 | 
				
			||||||
 | 
						assert ret_strings[7] == 'f64               9.990'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue