cgen: interface_call()
							parent
							
								
									aa9bb6f71a
								
							
						
					
					
						commit
						06173834c0
					
				|  | @ -36,11 +36,11 @@ const ( | |||
| 		'unsigned', | ||||
| 		'void', | ||||
| 		'volatile', | ||||
| 		'while', | ||||
| 		//'new'
 | ||||
| 		'while' | ||||
| 	] | ||||
| ) | ||||
| 
 | ||||
| // 'new'
 | ||||
| fn foo(t token.Token) { | ||||
| 	util.full_hash() | ||||
| } | ||||
|  | @ -2202,9 +2202,10 @@ string _STR(const char *fmt, int nfmts, ...) { | |||
| 		int k = strlen(fmt); | ||||
| 		bool is_fspec = false; | ||||
| 		for (int j=0; j<k; j++) { | ||||
| 			if (fmt[j] == '+"'%'"+') { | ||||
| 			if (fmt[j] == ' + | ||||
| 		"'%'" + ') { | ||||
| 				j++; | ||||
| 				if(fmt[j] != '+"'%'"+') { | ||||
| 				if(fmt[j] != ' + "'%'" + ') { | ||||
| 					is_fspec = true; | ||||
| 					break; | ||||
| 				} | ||||
|  | @ -2213,17 +2214,22 @@ string _STR(const char *fmt, int nfmts, ...) { | |||
| 		if (is_fspec) { | ||||
| 			char f = fmt[k-1]; | ||||
| 			char fup = f & 0xdf; // toupper
 | ||||
| 			bool l = fmt[k-2] == '+"'l'"+'; | ||||
| 			bool ll = l && fmt[k-3] == '+"'l'"+'; | ||||
| 			if (f == '+"'u'"+' || fup == '+"'X'"+' || f == '+"'o'"+' || f == '+"'d'"+' || f == '+"'c'"+') { // int...
 | ||||
| 			bool l = fmt[k-2] == ' + | ||||
| 		"'l'" + '; | ||||
| 			bool ll = l && fmt[k-3] == ' + "'l'" + '; | ||||
| 			if (f == ' + "'u'" + ' || fup == ' + | ||||
| 		"'X'" + ' || f == ' + "'o'" + ' || f == ' + "'d'" + ' || f == ' + "'c'" + ') { // int... | ||||
| 				if (ll) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+16, va_arg(argptr, long long)); | ||||
| 				else if (l) _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, long)); | ||||
| 				else _STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+8, va_arg(argptr, int)); | ||||
| 			} else if (fup >= '+"'E'"+' && fup <= '+"'G'"+') { // floating point
 | ||||
| 			} else if (fup >= ' + | ||||
| 		"'E'" + ' && fup <= ' + "'G'" + ') { // floating point | ||||
| 				_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+10, va_arg(argptr, double)); | ||||
| 			} else if (f == '+"'s'"+') { // v string
 | ||||
| 			} else if (f == ' + | ||||
| 		"'s'" + ') { // v string | ||||
| 				string s = va_arg(argptr, string); | ||||
| 				if (fmt[k-4] == '+"'*'"+') { // %*.*s
 | ||||
| 				if (fmt[k-4] == ' + "'*'" + | ||||
| 		') { // %*.*s | ||||
| 					int fwidth = va_arg(argptr, int); | ||||
| 					if (fwidth < 0) | ||||
| 						fwidth -= (s.len - utf8_str_len(s)); | ||||
|  | @ -2440,13 +2446,13 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 		sym := g.table.get_type_symbol(node.expr_types[i]) | ||||
| 		sfmt := node.expr_fmts[i] | ||||
| 		mut fspec := `_` // placeholder
 | ||||
| 		mut fmt := ''    // field width and precision
 | ||||
| 		mut fmt := '' // field width and precision
 | ||||
| 		if sfmt.len > 0 { | ||||
| 			// analyze and validate format specifier
 | ||||
| 			if sfmt[sfmt.len - 1] in [`E`, `F`, `G`, `e`, `f`, `g`, `e`, | ||||
| 				`d`, `u`, `x`, `X`, `o`, `c`, `s`] { | ||||
| 					fspec = sfmt[sfmt.len - 1] | ||||
| 				} | ||||
| 				fspec = sfmt[sfmt.len - 1] | ||||
| 			} | ||||
| 			fmt = if fspec == `_` { | ||||
| 				sfmt[1..sfmt.len] | ||||
| 			} else { | ||||
|  | @ -2460,9 +2466,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 				fspec = `d` | ||||
| 			} else if node.expr_types[i].is_unsigned() { | ||||
| 				fspec = `u` | ||||
| 			} else if node.expr_types[i] in [table.string_type, table.bool_type] || | ||||
| 				sym.kind in [.enum_, .array, .array_fixed, .struct_, .map] || | ||||
| 				g.typ(node.expr_types[i]).starts_with('Option') || | ||||
| 			} else if node.expr_types[i] in [table.string_type, table.bool_type] || sym.kind in | ||||
| 				[.enum_, .array, .array_fixed, .struct_, .map] || g.typ(node.expr_types[i]).starts_with('Option') || | ||||
| 				sym.has_method('str') { | ||||
| 				fspec = `s` | ||||
| 			} else { | ||||
|  | @ -2473,17 +2478,17 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 		fields := fmt.split('.') | ||||
| 		// validate format
 | ||||
| 		// only floats should have precision specifier
 | ||||
| 		if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || | ||||
| 		node.expr_types[i].is_signed() && !(fspec in [`d`, `c`, `x`, `X`, `o`]) || | ||||
| 		node.expr_types[i].is_unsigned() && !(fspec in [`u`, `x`, `X`, `o`, `c`]) || | ||||
| 		node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, `g`, `e`]) { | ||||
| 		if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || node.expr_types[i].is_signed() && | ||||
| 			!(fspec in [`d`, `c`, `x`, `X`, `o`]) || node.expr_types[i].is_unsigned() && !(fspec in [`u`, | ||||
| 			`x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, | ||||
| 			`g`, `e`]) { | ||||
| 			verror('illegal format specifier ${fspec:c} for type ${g.table.get_type_name(node.expr_types[i])}') | ||||
| 		} | ||||
| 		// make sure that format paramters are valid numbers
 | ||||
| 		for j, f in fields { | ||||
| 			for k, c in f { | ||||
| 				if (c < `0` || c > `9`) && | ||||
| 					!(j == 0 && k == 0 && (node.expr_types[i].is_number() && c == `+` || c == `-`)) { | ||||
| 				if (c < `0` || c > `9`) && !(j == 0 && k == 0 && (node.expr_types[i].is_number() && | ||||
| 					c == `+` || c == `-`)) { | ||||
| 					verror('illegal character ${c:c} in format specifier ${fmt}') | ||||
| 				} | ||||
| 			} | ||||
|  | @ -2506,8 +2511,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 			g.write('$fmt${fspec:c}') | ||||
| 		} else if node.expr_types[i].is_int() { | ||||
| 			if fspec == `c` { | ||||
| 				if node.expr_types[i].idx() in [table.i64_type_idx table.f64_type_idx] { | ||||
| 					verror("64 bit integer types cannot be interpolated as character") | ||||
| 				if node.expr_types[i].idx() in [table.i64_type_idx, table.f64_type_idx] { | ||||
| 					verror('64 bit integer types cannot be interpolated as character') | ||||
| 				} else { | ||||
| 					g.write('${fmt}c') | ||||
| 				} | ||||
|  | @ -2565,11 +2570,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 				} | ||||
| 			} else if sym.has_method('str') || sym.kind in [.array, .array_fixed, .map, .struct_] { | ||||
| 				is_p := node.expr_types[i].is_ptr() | ||||
| 				val_type := if is_p { | ||||
| 					node.expr_types[i].deref() | ||||
| 				} else { | ||||
| 					node.expr_types[i] | ||||
| 				} | ||||
| 				val_type := if is_p { node.expr_types[i].deref() } else { node.expr_types[i] } | ||||
| 				str_fn_name := g.gen_str_for_type(val_type) | ||||
| 				if is_p { | ||||
| 					g.write('string_add(_SLIT("&"), ${str_fn_name}(*(') | ||||
|  | @ -3550,9 +3551,12 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { | |||
| 		if it.is_interface { | ||||
| 			// sym := g.table.get_type_symbol(it.interface_types[i])
 | ||||
| 			// isym := g.table.get_type_symbol(it.interface_type)
 | ||||
| 			/* | ||||
| 			interface_styp := g.typ(it.interface_type) | ||||
| 			styp := g.typ(it.interface_types[i]) | ||||
| 			g.write('I_${styp}_to_${interface_styp}(') | ||||
| 			*/ | ||||
| 			g.interface_call(it.interface_types[i], it.interface_type) | ||||
| 		} | ||||
| 		g.expr(expr) | ||||
| 		if it.is_interface { | ||||
|  | @ -3562,3 +3566,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { | |||
| 	} | ||||
| 	g.write('\n})') | ||||
| } | ||||
| 
 | ||||
| // `ui.foo(button)` =>
 | ||||
| // `ui__foo(I_ui__Button_to_ui__Widget(` ...
 | ||||
| fn (g &Gen) interface_call(typ, interface_type table.Type) { | ||||
| 	interface_styp := g.typ(interface_type).replace('*', '') | ||||
| 	styp := g.typ(typ).replace('*', '') | ||||
| 	g.write('I_${styp}_to_${interface_styp}(') | ||||
| } | ||||
|  |  | |||
|  | @ -508,10 +508,11 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) { | |||
| 				// Cast a type to interface
 | ||||
| 				// `foo(dog)` => `foo(I_Dog_to_Animal(dog))`
 | ||||
| 				exp_sym := g.table.get_type_symbol(expected_types[arg_no]) | ||||
| 				exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no])
 | ||||
| 				styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ)
 | ||||
| 				// exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no])
 | ||||
| 				// styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ)
 | ||||
| 				if exp_sym.kind == .interface_ { | ||||
| 					g.write('I_${styp}_to_${exp_styp}(') | ||||
| 					g.interface_call(arg.typ, expected_types[arg_no]) | ||||
| 					// g.write('/*Z*/I_${styp}_to_${exp_styp}(')
 | ||||
| 					is_interface = true | ||||
| 				} | ||||
| 			} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue