From 68d5bae1ee11b9d3e2fa52b297a0e4e7253a7a5e Mon Sep 17 00:00:00 2001 From: Paze AI Date: Sun, 16 Aug 2026 18:12:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20C++=20=E9=98=B6=E6=AE=B5=202=20-=20?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=87=BD=E6=95=B0=E5=9F=BA=E7=A1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - template 函数: 捕获定义, 调用时按首参类型推断实例化 - 实例化命名: max(3,5)->max_i, max(1.5,2.5)->max_d, bigger(p1,p2)->bigger_Point - 输出三段式布局: [声明/类] [模板实例化定义] [顶层函数] - 类类型模板参数自动加 struct 前缀 - 多参数模板/模板类: 干净跳过并注释 - 修复: Cls a(3), b(7) 多声明符带构造参数 - 输出改为内存缓冲 (8MB) 支持重排 --- bin/pcc-cpp.exe | Bin 76288 -> 80384 bytes tools/pcc-cpp.c | 352 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 344 insertions(+), 8 deletions(-) diff --git a/bin/pcc-cpp.exe b/bin/pcc-cpp.exe index 2b3a3d50ac4aba28411b729910b991448dc32dc3..1dc73a78a3551a3cbe79d4ef375acc28e38296c3 100644 GIT binary patch delta 35974 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 Dq-YMFj;FMGFXufSRbRDJD@u2#XhY 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 0) g_cap_len += n; + if (g_cap_len >= (int)sizeof g_cap - 1) g_cap_len = sizeof g_cap - 1; + } else if (g_emit_sect == 1) { + if (g_fn_len < (int)sizeof g_fn_buf - 1) { + n = vsnprintf(g_fn_buf + g_fn_len, + sizeof g_fn_buf - g_fn_len, fmt, ap); + if (n > 0) g_fn_len += n; + } + } else if (g_out_len < (int)sizeof g_outbuf - 1) { + n = vsnprintf(g_outbuf + g_out_len, + sizeof g_outbuf - g_out_len, fmt, ap); + if (n > 0) g_out_len += n; + } va_end(ap); } @@ -413,6 +455,7 @@ static void proto_emit(const char *fmt, ...) /* ---------------- class parsing ---------------- */ static void gather_decl(char *type, int typesz, char *name, int namesz); +static int tpl_call_check(char varcls[][128], char varname[][64], int nvars); static void parse_member_decl(const char *cls, const char *ret_type, const char *mname_in) { @@ -555,6 +598,9 @@ static void parse_member_decl(const char *cls, const char *ret_type, const char } unread_tok(&nxt); } + /* template function call inside a method body */ + if (tpl_call_check(NULL, NULL, 0)) + continue; if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "{")) { bd++; proto_emit(" {"); prev_dot = 0; next_tok(); continue; } if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "}")) { bd--; if (bd > 0) proto_emit("}"); next_tok(); continue; } if (g_tok.type == T_THIS) { proto_emit("this"); prev_dot = 0; next_tok(); continue; } @@ -978,6 +1024,9 @@ static void parse_member_definition(const char *ret_type) } unread_tok(&nxt); } + /* template function call inside a method body */ + if (tpl_call_check(NULL, NULL, 0)) + continue; if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "{")) { depth++; emit(" {"); prev_dot = 0; next_tok(); continue; } if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "}")) { if (depth > 0) { depth--; emit("}"); next_tok(); continue; } @@ -1258,6 +1307,9 @@ static void parse_free_operator(const char *ret_type, const char *name) } unread_tok(&nxt); } + /* template function call inside an operator body */ + if (tpl_call_check(NULL, NULL, 0)) + continue; if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "{")) { bdepth++; emit(" {"); @@ -1362,6 +1414,135 @@ static void parse_free_operator(const char *ret_type, const char *name) } } +/* ---------------- templates ---------------- */ + +/* replace standalone identifiers 'from' with 'to' in src */ +static void tpl_subst(char *dst, int dsz, const char *src, + const char *from, const char *to) +{ + int d = 0, i = 0, fl = (int)strlen(from), tl = (int)strlen(to); + while (src[i] && d < dsz - 1) { + if (!strncmp(src + i, from, fl) && + (i == 0 || !(isalnum((unsigned char)src[i-1]) || src[i-1] == '_')) && + !(isalnum((unsigned char)src[i+fl]) || src[i+fl] == '_')) { + if (d + tl < dsz - 1) { + memcpy(dst + d, to, tl); + d += tl; + } + i += fl; + } else { + dst[d++] = src[i++]; + } + } + dst[d] = 0; +} + +static TplFn *find_tplfn(const char *name) +{ + TplFn *p; + for (p = g_tplfns; p; p = p->next) + if (!strcmp(p->name, name)) return p; + return NULL; +} + +static const char *type_suffix(const char *t) +{ + if (!strcmp(t, "int")) return "i"; + if (!strcmp(t, "double")) return "d"; + if (!strcmp(t, "float")) return "f"; + if (!strcmp(t, "char")) return "c"; + if (!strcmp(t, "long")) return "l"; + if (!strcmp(t, "short")) return "s"; + if (!strcmp(t, "unsigned int")) return "u"; + return t; /* class name */ +} + +/* emit (once) the instantiated definition of a template function */ +static void instantiate_tpl_fn(TplFn *tf, const char *ttype, const char *mname) +{ + TplInst *p; + for (p = g_tplinsts; p; p = p->next) + if (!strcmp(p->name, mname)) return; + p = (TplInst*)calloc(1, sizeof *p); + strncpy(p->name, mname, sizeof p->name - 1); + p->name[sizeof p->name - 1] = 0; + p->next = g_tplinsts; + g_tplinsts = p; + { + char tmp[4096], def[4096]; + char stype[96]; + const char *subst_type = ttype; + if (find_class(ttype)) { + snprintf(stype, sizeof stype, "struct %s", ttype); + subst_type = stype; + } + tpl_subst(tmp, sizeof tmp, tf->body, tf->tparam, subst_type); + tpl_subst(def, sizeof def, tmp, tf->name, mname); + { + int l = (int)strlen(def); + if (g_tpl_defs_len + l + 1 < (int)sizeof g_tpl_defs) { + memcpy(g_tpl_defs + g_tpl_defs_len, def, l); + g_tpl_defs_len += l; + g_tpl_defs[g_tpl_defs_len++] = '\n'; + } + } + } +} + +/* If g_tok is a template function name followed by '(', infer the + concrete type from the first argument and rewrite g_tok to the + mangled instantiation name (the def is queued in g_tpl_defs). + Returns 1 if handled. */ +static int tpl_call_check(char varcls[][128], char varname[][64], int nvars) +{ + TplFn *tf; + Token nxt, a1; + const char *ttype = "int"; + char suffix[64]; + char mname[128]; + + if (g_tok.type != T_IDENT) return 0; + tf = find_tplfn(g_tok.text); + if (!tf) return 0; + read_tok(&nxt); + if (!(nxt.type == T_PUNCT && !strcmp(nxt.text, "("))) { + unread_tok(&nxt); + return 0; + } + /* stream is now at the first argument; read it to infer the type */ + read_tok(&a1); + if (a1.type == T_NUMBER) { + if (strchr(a1.text, '.') || strchr(a1.text, 'e') || + strchr(a1.text, 'E') || strchr(a1.text, 'f') || + strchr(a1.text, 'F') || strchr(a1.text, 'l')) + ttype = "double"; + else + ttype = "int"; + } else if (a1.type == T_CHAR) { + ttype = "char"; + } else if (a1.type == T_IDENT && nvars > 0) { + int k; + ttype = "int"; + for (k = 0; k < nvars; k++) + if (!strcmp(a1.text, varname[k])) { + ttype = varcls[k]; + break; + } + } + /* restore the stream: arg back, then '(' back */ + unread_tok(&a1); + unread_tok(&nxt); + /* g_tok is still the template name; rewrite it to the mangle */ + strncpy(suffix, type_suffix(ttype), sizeof suffix - 1); + suffix[sizeof suffix - 1] = 0; + snprintf(mname, sizeof mname, "%s_%s", tf->name, suffix); + instantiate_tpl_fn(tf, ttype, mname); + g_tok.type = T_IDENT; + strncpy(g_tok.text, mname, sizeof g_tok.text - 1); + g_tok.text[sizeof g_tok.text - 1] = 0; + return 1; +} + static void parse_function(const char *ret_type, const char *name) { if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "::")) { @@ -1405,6 +1586,9 @@ static void parse_function(const char *ret_type, const char *name) } unread_tok(&nxt); } + /* template function call: max(a, b) -> max_i(a, b) */ + if (tpl_call_check(varcls, varname, nvars)) + continue; if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "{")) { depth++; emit(" {"); next_tok(); continue; } if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "}")) { if (depth > 0) { depth--; emit("}"); next_tok(); continue; } @@ -1499,7 +1683,7 @@ static void parse_function(const char *ret_type, const char *name) if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ")")) next_tok(); } - continue; + goto add_decls; } /* plain declaration: Cls var; -> default ctor */ if (g_tok.type == T_PUNCT && @@ -1510,16 +1694,53 @@ static void parse_function(const char *ret_type, const char *name) } } } - /* additional declarators: Cls a, b, c; */ + /* additional declarators: Cls a, b(2), c; */ + add_decls: while (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ",")) { - emit(", "); next_tok(); if (g_tok.type == T_IDENT && nvars < 64) { + char vn[64]; strncpy(varcls[nvars], clsname, 127); strncpy(varname[nvars], g_tok.text, 63); + strncpy(vn, g_tok.text, sizeof vn - 1); + vn[sizeof vn - 1] = 0; nvars++; - emit(" %s", g_tok.text); next_tok(); + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "(")) { + ClassInfo *cci2 = find_class(clsname); + if (cci2 && cci2->has_ctor) { + /* declarator with ctor args: a(3), b(7) */ + emit("; struct %s %s; %s_ctor(&%s", + clsname, vn, clsname, vn); + next_tok(); + if (g_tok.type == T_PUNCT && + !strcmp(g_tok.text, ")")) { + emit(")"); + next_tok(); + } else { + emit(", "); + int adepth = 0; + while (!(g_tok.type == T_PUNCT && + !strcmp(g_tok.text, ")") && + adepth == 0)) { + if (g_tok.type == T_EOF) break; + if (g_tok.type == T_PUNCT && + !strcmp(g_tok.text, "(")) adepth++; + if (g_tok.type == T_PUNCT && + !strcmp(g_tok.text, ")")) adepth--; + emit_tok(); + next_tok(); + } + emit(")"); + if (g_tok.type == T_PUNCT && + !strcmp(g_tok.text, ")")) next_tok(); + } + continue; /* look for more declarators */ + } + emit(", %s(", vn); + continue; + } + emit(", %s", vn); } } continue; @@ -1727,6 +1948,100 @@ static void gather_decl(char *type, int typesz, char *name, int namesz) /* no name found; caller handles */ } +/* skip a declaration up to ';' or a balanced '}' */ +static void skip_decl(void) +{ + int depth = 0; + while (!(g_tok.type == T_EOF)) { + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "{")) depth++; + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "}")) { + if (depth == 0) { next_tok(); return; } + depth--; + } + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ";") && depth == 0) { + next_tok(); + return; + } + next_tok(); + } +} + +/* template function/class */ +static void parse_template(void) +{ + char tparam[32] = "T"; + char tybuf[512], nmbuf[256]; + int multi = 0; + + next_tok(); /* '<' */ + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "<")) { + next_tok(); + /* class T | typename T | struct T */ + if (g_tok.type == T_CLASS || g_tok.type == T_STRUCT || + (g_tok.type == T_IDENT && !strcmp(g_tok.text, "typename"))) + next_tok(); + if (g_tok.type == T_IDENT) { + strncpy(tparam, g_tok.text, sizeof tparam - 1); + tparam[sizeof tparam - 1] = 0; + next_tok(); + } + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ",")) multi = 1; + /* skip to '>' */ + while (!(g_tok.type == T_EOF)) { + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ">")) break; + next_tok(); + } + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ">")) next_tok(); + } else if (g_tok.type == T_CLASS) { + /* template */ + next_tok(); + if (g_tok.type == T_IDENT) { + strncpy(tparam, g_tok.text, sizeof tparam - 1); + tparam[sizeof tparam - 1] = 0; + next_tok(); + } + if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, ">")) next_tok(); + } + + if (multi) { + /* multi-parameter templates: not supported, skip declaration */ + skip_decl(); + emit("/* skipped multi-param template */\n"); + return; + } + + if (g_tok.type == T_CLASS || g_tok.type == T_STRUCT) { + /* template class: not yet supported, skip it cleanly */ + skip_decl(); + emit("/* skipped template class */\n"); + return; + } + + /* template function */ + gather_decl(tybuf, sizeof tybuf, nmbuf, sizeof nmbuf); + if (nmbuf[0]) { + g_capture = 1; + g_cap_len = 0; + parse_function(tybuf[0] ? tybuf : "int", nmbuf); + g_capture = 0; + g_cap[g_cap_len] = 0; + { + TplFn *tf = (TplFn*)calloc(1, sizeof *tf); + strncpy(tf->name, nmbuf, sizeof tf->name - 1); + tf->name[sizeof tf->name - 1] = 0; + strncpy(tf->tparam, tparam, sizeof tf->tparam - 1); + tf->tparam[sizeof tf->tparam - 1] = 0; + strncpy(tf->body, g_cap, sizeof tf->body - 1); + tf->body[sizeof tf->body - 1] = 0; + tf->next = g_tplfns; + g_tplfns = tf; + } + } else { + skip_decl(); + emit("/* skipped unknown template */\n"); + } +} + static void parse_program(void) { for (;;) { @@ -1811,9 +2126,14 @@ static void parse_program(void) continue; } - if (g_tok.type == T_USING || g_tok.type == T_TEMPLATE || - g_tok.type == T_INLINE || g_tok.type == T_CONSTEXPR || - g_tok.type == T_FRIEND || g_tok.type == T_VIRTUAL) { + if (g_tok.type == T_TEMPLATE) { + parse_template(); + continue; + } + + if (g_tok.type == T_USING || g_tok.type == T_INLINE || + g_tok.type == T_CONSTEXPR || g_tok.type == T_FRIEND || + g_tok.type == T_VIRTUAL) { next_tok(); while (!(g_tok.type == T_EOF)) { if (g_tok.type == T_PUNCT && @@ -1837,13 +2157,19 @@ static void parse_program(void) char tybuf[512], nmbuf[256]; gather_decl(tybuf, sizeof tybuf, nmbuf, sizeof nmbuf); if (nmbuf[0]) { + int was = g_emit_sect; + g_emit_sect = 1; parse_function(tybuf[0] ? tybuf : "int", nmbuf); + g_emit_sect = was; } else if (g_tok.type == T_EOF) { break; } else if (g_tok.type == T_PUNCT && !strcmp(g_tok.text, "(")) { /* function without return type (C style) */ + int was = g_emit_sect; + g_emit_sect = 1; emit("int "); parse_function("int", "f"); + g_emit_sect = was; } else { /* global variable: type + rest */ if (tybuf[0]) emit("%s", tybuf); @@ -1883,6 +2209,16 @@ int main(int argc, char **argv) next_tok(); parse_program(); + /* layout: [declarations/classes] [template instantiations] + [top-level functions] */ + fwrite(g_outbuf, 1, g_out_len, g_out); + if (g_tpl_defs_len) { + fputc('\n', g_out); + fwrite(g_tpl_defs, 1, g_tpl_defs_len, g_out); + } + fputc('\n', g_out); + fwrite(g_fn_buf, 1, g_fn_len, g_out); + fclose(g_in); if (g_out != stdout) fclose(g_out); return 0;