Skip to content

Commit 12cc2f2

Browse files
committed
fix: #299
1 parent 4cf1499 commit 12cc2f2

2 files changed

Lines changed: 158 additions & 2 deletions

File tree

src/parser/parser_stmt.c

Lines changed: 118 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,18 +2115,133 @@ char *process_printf_sugar(ParserContext *ctx, Token srctoken, const char *conte
21152115
{
21162116
format_spec = "%p"; // Pointer
21172117
}
2118+
2119+
if (!format_spec && t)
2120+
{
2121+
Type *base = t;
2122+
int is_p = 0;
2123+
if (base->kind == TYPE_POINTER)
2124+
{
2125+
base = base->inner;
2126+
is_p = 1;
2127+
}
2128+
2129+
while (base)
2130+
{
2131+
if (base->kind == TYPE_ALIAS)
2132+
{
2133+
base = base->inner;
2134+
}
2135+
else if (base->kind == TYPE_STRUCT && base->name)
2136+
{
2137+
TypeAlias *ta = find_type_alias_node(ctx, base->name);
2138+
if (ta && ta->type_info)
2139+
{
2140+
base = ta->type_info;
2141+
}
2142+
else
2143+
{
2144+
break;
2145+
}
2146+
}
2147+
else
2148+
{
2149+
break;
2150+
}
2151+
}
2152+
2153+
if (base && base->kind == TYPE_ARRAY && base->array_size == 0)
2154+
{
2155+
char *inner_name = type_to_string(base->inner);
2156+
char slice_name[256];
2157+
sprintf(slice_name, "Slice_%s", inner_name);
2158+
free(inner_name);
2159+
2160+
ASTNode *def = find_struct_def(ctx, slice_name);
2161+
if (def && def->type == NODE_STRUCT)
2162+
{
2163+
int has_data = 0;
2164+
int has_len = 0;
2165+
char *data_type = NULL;
2166+
2167+
ASTNode *curr = def->strct.fields;
2168+
while (curr)
2169+
{
2170+
if (strcmp(curr->field.name, "data") == 0)
2171+
{
2172+
has_data = 1;
2173+
data_type = curr->field.type;
2174+
}
2175+
else if (strcmp(curr->field.name, "len") == 0)
2176+
{
2177+
has_len = 1;
2178+
}
2179+
curr = curr->next;
2180+
}
2181+
2182+
if (has_data && has_len && data_type &&
2183+
(strstr(data_type, "char") || strstr(data_type, "u8") ||
2184+
strstr(data_type, "byte")))
2185+
{
2186+
char buf[512];
2187+
const char *acc = is_p ? "->" : ".";
2188+
sprintf(buf, "fprintf(%s, \"%%.*s\", (int)(%s)%slen, (%s)%sdata); ",
2189+
target, rw_expr, acc, rw_expr, acc);
2190+
strcat(gen, buf);
2191+
goto next_segment;
2192+
}
2193+
}
2194+
}
2195+
else if (base && base->kind == TYPE_STRUCT && base->name)
2196+
{
2197+
ASTNode *def = find_struct_def(ctx, base->name);
2198+
if (def && def->type == NODE_STRUCT)
2199+
{
2200+
int has_data = 0;
2201+
int has_len = 0;
2202+
char *data_type = NULL;
2203+
2204+
ASTNode *curr = def->strct.fields;
2205+
while (curr)
2206+
{
2207+
if (strcmp(curr->field.name, "data") == 0)
2208+
{
2209+
has_data = 1;
2210+
data_type = curr->field.type;
2211+
}
2212+
else if (strcmp(curr->field.name, "len") == 0)
2213+
{
2214+
has_len = 1;
2215+
}
2216+
curr = curr->next;
2217+
}
2218+
2219+
if (has_data && has_len && data_type &&
2220+
(strstr(data_type, "char") || strstr(data_type, "u8") ||
2221+
strstr(data_type, "byte")))
2222+
{
2223+
char buf[512];
2224+
const char *acc = is_p ? "->" : ".";
2225+
sprintf(buf, "fprintf(%s, \"%%.*s\", (int)(%s)%slen, (%s)%sdata); ",
2226+
target, rw_expr, acc, rw_expr, acc);
2227+
strcat(gen, buf);
2228+
goto next_segment;
2229+
}
2230+
}
2231+
}
2232+
}
2233+
21182234
if (t)
21192235
{
21202236
free(inferred_type);
21212237
}
21222238
}
21232239

2124-
// Check for Literals if variable lookup failed
21252240
if (!format_spec)
21262241
{
21272242
if (isdigit(clean_expr[0]) || clean_expr[0] == '-')
21282243
{
2129-
format_spec = "%d"; // Naive integer guess (could be float)
2244+
format_spec = "%d";
21302245
}
21312246
else if (clean_expr[0] == '"')
21322247
{
@@ -2170,6 +2285,7 @@ char *process_printf_sugar(ParserContext *ctx, Token srctoken, const char *conte
21702285
}
21712286
}
21722287

2288+
next_segment:
21732289
if (rw_expr && used_codegen)
21742290
{
21752291
free(rw_expr);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import "std/core.zc"
2+
import "std/slice.zc"
3+
import "std/vec.zc"
4+
5+
opaque alias StringView = Slice<char>;
6+
alias MyVec = Vec<char>;
7+
8+
test "println_robustness_slice" {
9+
let val = "hello";
10+
let sv = Slice<char>{data: val, len: 5};
11+
println "{sv}";
12+
}
13+
14+
test "println_robustness_opaque_alias" {
15+
let val = "opaque";
16+
let sv = StringView{data: val, len: 6};
17+
println "{sv}";
18+
}
19+
20+
test "println_robustness_vec_alias" {
21+
let v = Vec<char>::new();
22+
v.push('a');
23+
v.push('b');
24+
v.push('c');
25+
let mv = (MyVec)v;
26+
println "{mv}";
27+
}
28+
29+
test "println_robustness_pointer" {
30+
let val = "pointer";
31+
let sv = Slice<char>{data: val, len: 7};
32+
let p = &sv;
33+
println "{p}";
34+
}
35+
36+
test "println_robustness_builtin_slice" {
37+
let val = "builtin";
38+
let s: [char] = [char]{data: val, len: 7};
39+
println "{s}";
40+
}

0 commit comments

Comments
 (0)