http://d.hatena.ne.jp/shinichiro_h/20070321#c1174656403
でコメントいただいて面白いなぁと思ったのでちょっと作ってみました。
void qsort(void b@, int n, int s, int c@(const void@, const void@)); int diff(const void a@, const void b@) { return ((int@)a)@ - ((int@)b)@; } int func_func@()(const void@, const void@) { return &diff; } int array[] = { 3, 2, 4, 1 }; int main() { int i = 0; int ip@ = &i; int cip@const = ip; printf("ip@ = %d\n", ip@); printf("cip@ = %d\n", cip@); qsort(array, 4, 4, func_func()); for (ip = array; i < 4; i++) { printf("%d\n", ip++@); } typedef struct { int m; } S; S s; s.m = 99; S sp@ = &s; printf("sp@.m = %d\n", sp@.m); }
これが、
i@u ~/wrk/tccx> ./tcc test.c i@u ~/wrk/tccx> ./a.out ip@ = 0 cip@ = 0 1 2 3 4 sp@.m = 99
こうなる。うーんさっぱり C に見えないなー。結局もう慣れちゃった、というのと、 nminoru さんに指摘しただいたように、実用上関数ポインタは typedef する、とかコーディング規約で縛っときゃ別に大きな問題にはならないから、まぁこうずるずるとひきずられて、VNIしーこ18歳は日記ネタになり続けてるんだろうなぁという。
あとまぁこういう体系にするならやっぱり型は全部後置にしてくれって感じではある。型後置だと型推論がなんか自然に見えていいと思うし。
今回使った tcc-0.9.23 へのパッチ。
--- tcc.c- 2007-03-27 02:20:09.000000000 +0900 +++ tcc.c 2007-03-27 02:04:02.000000000 +0900 @@ -6889,6 +6889,30 @@ s = sym_push(SYM_FIELD, type, 0, n); type->t = t1 | VT_ARRAY | VT_PTR; type->ref = s; + } else if (tok == '@') { + int qualifiers; + qualifiers = 0; + redo: + next(); + switch(tok) { + case TOK_CONST1: + case TOK_CONST2: + case TOK_CONST3: + qualifiers |= VT_CONSTANT; + goto redo; + case TOK_VOLATILE1: + case TOK_VOLATILE2: + case TOK_VOLATILE3: + qualifiers |= VT_VOLATILE; + goto redo; + case TOK_RESTRICT1: + case TOK_RESTRICT2: + case TOK_RESTRICT3: + goto redo; + } + post_type(type, ad); + mk_pointer(type); + type->t |= qualifiers; } } @@ -7461,6 +7485,9 @@ /* return value */ vsetc(&ret.type, ret.r, &ret.c); vtop->r2 = ret.r2; + } else if (tok == '@') { + indir(); + next(); } else { break; }