Mercurial > hg > CbC > CbC_gcc
changeset 22:0eb6cac880f0
add cbc example of quicksort.
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 13 Oct 2009 17:15:58 +0900 |
parents | 959d4c8c8abc |
children | 775dfe898662 |
files | .hgignore CbC-examples/conv.c CbC-examples/quicksort/quicksort_c.c CbC-examples/quicksort/quicksort_cbc.cbc CbC-examples/quicksort/quicksort_test.cbc gcc/c-parser.c |
diffstat | 6 files changed, 535 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Tue Oct 13 17:15:58 2009 +0900 @@ -0,0 +1,8 @@ +syntax: glob + +.*.swp +.*.swo +GTAGS +GRTAGS +GSYMS +GPATH
--- a/CbC-examples/conv.c Tue Sep 29 20:15:16 2009 +0900 +++ b/CbC-examples/conv.c Tue Oct 13 17:15:58 2009 +0900 @@ -64,7 +64,7 @@ __code main_return(int i,stack sp) { printf("#0061:%d\n",i); - goto (( (struct main_continuation *)sp)->main_ret)(0, + goto (( (struct main_continuation *)sp)->main_ret)(i, ((struct main_continuation *)sp)->env); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_c.c Tue Oct 13 17:15:58 2009 +0900 @@ -0,0 +1,183 @@ +#include<stdio.h> +#include<stdlib.h> +#include<unistd.h> +#include<assert.h> + +static inline void +SWAP (int *a, int *b) +{ + int tmp; + tmp = *a; + *a = *b; + *b = tmp; +} + +static inline int +mid_point(int a, int b, int c) +{ + if (a < b) { + if (b < c) + return b; + else if (a < c) + return c; + else + return a; + } else { + if (a < c) + return a; + else if (b < c) + return c; + else + return b; + } +} + +void +selectsort(int *v, int s0, int e0) +{ + int i,j; + int m; + int size = e0-s0+1; + v += s0; + for (i=0; i<size; i++) { + m = i; + for (j=i+1; j<size; j++) { + if (v[m] > v[j]) + m = j; + } + if (m!=i) + SWAP(&v[i],&v[m]); + } + return; +} + +void +quicksort(int *v, int s0, int e0) +{ + int p; + int s=s0, e=e0; +#if 0 + if (e<=s) return; + if (e-s<5) { + selectsort(v,s0,e0); + return; + } +#else + if (e<=s) return; +#endif + + //p = (v[s]+v[(s+e)/2]+v[e])/3; + p = mid_point(v[s],v[e],v[(s+e)/2]); + + while (1) { + while (v[s]<p) s++; + while (p<v[e]) e--; + + if (!(s<e)) break; + SWAP(&v[s], &v[e]); + s++; e--; + } + assert(e+1==s || s==e); + + quicksort(v, s0, e); + quicksort(v, e+1, e0); + return; +} + +static void +print_array(int *v, int size) +{ + int i; + printf("["); + for (i=0; i<size; i++) { + printf("%s%4d", (i%10==0)? "\n ":" ", v[i]); + } + printf("]\n"); +} + +static int +check_sort(int *v, int size) +{ + int i; + for (i=0; i<size-1; i++) { + if (v[i] > v[i+1]) + return 0; + } + return 1; +} + +void +random_initialize(int *v, int size, int min, int max) +{ + int i; + int diff = max-min+1; + + for (i=0; i<size; i++) { + v[i] = min+random()%diff; + } + return; +} + +int +start_sort(int size) +{ + int *target; + + target = (int*)malloc(sizeof(int)*size); + if (!target) { + perror("malloc"); + exit(1); + } + + random_initialize(target, size, 0, 1); + + //print_array(target, size); + quicksort(target, 0, size-1); + //selectsort(target, 0, size-1); + //print_array(target, size); + return check_sort(target, size); +} + +int +main(int argc, char **argv) +{ + //unsigned int seed= -1074072728; + unsigned int seed; + int size=101; + int loop=1; + int opt, i; + + while ((opt = getopt(argc, argv, "r:s:n:")) != -1) { + switch (opt) { + case 's': + size = atoi(optarg); + break; + case 'n': + loop = atoi(optarg); + break; + case 'r': + seed = atoi(optarg); + break; + default: + fprintf(stderr, "Usage: %s [-t times] [-n sizeofarray] [-s seed]\n", argv[0]); + exit(1); + } + } + + printf("start seed = %u\n", seed); + printf("sort size = %d\n", size); + for (i=0; i<loop; i++) { + srandom(seed+i); + int b = start_sort(size); + if (b) { + printf("seed = %d+%u, success\n", i, seed); + } else { + fprintf(stderr, "sorting failure! seed=%u+%d\n", seed,i); + exit(1); + } + } + exit(0); +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_cbc.cbc Tue Oct 13 17:15:58 2009 +0900 @@ -0,0 +1,241 @@ +#include<stdio.h> +#include<stdlib.h> +#include<assert.h> + +typedef void *stack; +typedef struct { + int size; + void *interface; + void (*code)(void*, stack); +} frame, *framep; + +/* quickstart main routine. */ +struct qs_if { + int *v; + int s; + int e; +}; +typedef __code (*RET)(void*); + +#include"quicksort_cbc.h" + +__code returner(stack sp) +{ + framep fp = (framep)sp; + sp += fp->size; + fp->code(fp->interface, sp); +} + +__code quicksort_start(void *arg, stack sp) +{ + struct qs_if *recvif = arg; + int a,b,c,p; + a = recvif->v[recvif->s]; + b = recvif->v[recvif->e]; + c = recvif->v[(recvif->s+recvif->e)/2]; + + //printf("quicksort_start: s=%d,e=%d", recvif->s, recvif->e); + if (recvif->e <= recvif->s) goto returner(sp); + + if (a < b) { + if (b < c) + p = b; + else if (a < c) + p = c; + else + p = a; + } else { + if (a < c) + p = a; + else if (b < c) + p = c; + else + p = b; + } + + goto quicksort_divider (recvif, recvif->s, recvif->e, p, sp); +} +/* main routine end. */ + +/* divide routine. */ +__code quicksort_divider(struct qs_if *recvif, int s, int e, int p, stack sp) +{ + goto quicksort_divider_s(recvif, s, e, p, sp); +} +__code quicksort_divider_s(struct qs_if *recvif, int s, int e, int p, stack sp) +{ + if (recvif->v[s]<p) { + s++; + goto quicksort_divider_s(recvif, s, e, p, sp); + } else + goto quicksort_divider_e(recvif, s, e, p, sp); +} +__code quicksort_divider_e(struct qs_if *recvif, int s, int e, int p, stack sp) +{ + if (p<recvif->v[e]) { + e--; + goto quicksort_divider_e(recvif, s, e, p, sp); + } else + goto quicksort_swapper(recvif, s, e, p, sp); +} +__code quicksort_swapper(struct qs_if *recvif, int s, int e, int p, stack sp) +{ + if (s<e) { + int tmp; + tmp = recvif->v[s]; + recvif->v[s] = recvif->v[e]; + recvif->v[e] = tmp; + s++; + e--; + goto quicksort_divider(recvif, s, e, p, sp); + } else { + assert(e+1==s || s==e); + goto quicksort_treecall(recvif, s, e, sp); + } +} +/* divide routin end. */ + + +/* recursive call routine. */ +__code quicksort_treecall(struct qs_if *recvif, int s, int e, stack sp) +{ + framep fp; + struct qs_if *outif; + + /* interface for first quicksort_start this segment directly jump to. */ + outif = (sp-=sizeof(struct qs_if)); + outif->v = recvif->v; + outif->s = recvif->s; + outif->e = e; + fp = (sp-=sizeof(frame)); + fp->code = quicksort_start; + fp->interface = recvif; + fp->size = sizeof(frame)+sizeof(struct qs_if); + + /* recvif is used by second quicksort_start. */ + recvif->s = e+1; + goto quicksort_start(outif, sp); +} +/* recursive call routine end. */ + +int v[100]; +struct qs_if *outif; + +struct qs { + __code (*ret)(void*); + void *ret_arg; + stack *sp; +}; +__code +quicksort(int *v, int s, int e, RET ret, void *arg ) +{ + framep fp; + stack sp = malloc(10240)+10240; + struct qs *finish_if; + + /* interface for quicksort_finish. */ + finish_if = (sp -= sizeof(*finish_if)); + finish_if->ret = ret; + finish_if->ret_arg = arg; + finish_if->sp = sp -10240 + sizeof(*finish_if); + + /* interface for quicksort_start. */ + outif = (sp -= sizeof(*outif)); + outif->v = v; + outif->s = s; + outif->e = e; + /* frame for quicksort_finish. */ + fp = (sp -= sizeof(frame)); + fp->code = quicksort_finish; + fp->interface = finish_if; + fp->size = sizeof(frame)+sizeof(outif); + + goto quicksort_start(outif, sp); +} +__code +quicksort_finish(void *arg, stack sp) +{ + struct qs interface = *(struct qs*)arg; + free(interface.sp); + goto interface.ret(interface.ret_arg); +} + + + +#if 0 +void +quicksort_c(int *v, int s0, int e0, stack sp) +{ + int p; + int s=s0, e=e0; + if (e<=s) return; + + //p = (v[s]+v[(s+e)/2]+v[e])/3; + p = mid_point(v[s],v[e],v[(s+e)/2]); + + while (1) { + while (v[s]<p) s++; + while (p<v[e]) e--; + + if (!(s<e)) break; + SWAP(&v[s], &v[e]); + s++; e--; + } + assert(e+1==s || s==e); + + quicksort(v, s0, e); + quicksort(v, e+1, e0); + return; +} + + + +/* -------------------- + * | args |fp| + * -------------------- + * + ↑ - + * sp + */ +/* code segmentへgotoしたときのstack spの状態 + * + * sp が直接さすのは frame 構造体 + * frame.size: + * frame.code: そのcode segmentが終了した時にgotoすべきcode segment. + * frame.interface: frame.codeへgotoするときのinterface. + * このポインタが指すメモリ領域は stack + * 中にあっても良いしなくても良い。 + * ただしframe.codeを登録した側で解放すべき。 + * sp+sizeof(frame)が指すのは実行中のcode segmentのinterface(引数) + * これは実行中のcode segmentがメモリ管理する + * 通常はこのcode segmentが終了する際に sp+=frame.size とすればよい + */ +__code caller0(void *arg, stack sp) +{ + /* interface for caller_finish0. */ + double *finish_arg = (sp -= sizeof(double)); + + /* arg for quicksort_start. */ + outif = (sp -= sizeof(*outif)); + framep fp = (sp -= sizeof(frame)); + fp->code = caller_finish; + fp->interface = NULL; + fp->size = sizeof(*outif)+sizeof(frame); + + goto quicksort_start(outif, sp); +} +__code caller_finish0(void *arg, stack sp) +{ +} + +__code __returner0(void *arg , stack sp) +{ + framep fp = sp; + sp += fp->size; + goto fp->code(fp->interface, sp); +} + +#endif + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CbC-examples/quicksort/quicksort_test.cbc Tue Oct 13 17:15:58 2009 +0900 @@ -0,0 +1,99 @@ +#include<stdio.h> +#include<stdlib.h> +#include<assert.h> +#include<unistd.h> + +#include"quicksort_test.h" + +void +random_initialize(int *v, int size, int min, int max) +{ + int i; + int diff = max-min+1; + + for (i=0; i<size; i++) { + v[i] = min+random()%diff; + } + return; +} + +static void +print_array(int *v, int size) +{ + int i; + printf("["); + for (i=0; i<size; i++) { + printf("%s%4d", (i%10==0)? "\n ":" ", v[i]); + } + printf(" ]\n"); +} + +void +starter() +{ + int *target; + int size=100; + + target = (int*)malloc(sizeof(int)*size); + if (!target) { + perror("malloc"); + exit(1); + } + + random_initialize(target, size, 0, 90); + + print_array(target, size); + goto quicksort(target, 0, size-1, exit0, (void*)target); + + printf("bad region\n"); +} + +int +main(int argc, char **argv) +{ + unsigned int seed=0; + int opt; + + while ((opt = getopt(argc, argv, "s:")) != -1) { + switch (opt) { + case 's': + seed = atoi(optarg); + break; + default: + fprintf(stderr, "Usage: %s [-t times] [-n sizeofarray] [-s seed]\n", argv[0]); + exit(1); + } + } + + srandom(seed); + starter(); + return 0; +} + +static int +check_sort(int *v, int size) +{ + int i; + for (i=0; i<size-1; i++) { + if (v[i] > v[i+1]) + return 0; + } + return 1; +} + +__code +exit0(void *arg) +{ + int *v = arg; + int b; + print_array(arg, 100); + b = check_sort(arg, 100); + if (b) { + printf("sorting successful!\n"); + exit(-1); + } else { + printf("sorting failure! \n"); + exit(0); + } +} +
--- a/gcc/c-parser.c Tue Sep 29 20:15:16 2009 +0900 +++ b/gcc/c-parser.c Tue Oct 13 17:15:58 2009 +0900 @@ -1547,9 +1547,9 @@ t.spec = c_parser_peek_token (parser)->value; declspecs_add_type (specs, t); - attrs = get_identifier("fastcall"); - attrs = build_tree_list(attrs, NULL_TREE); - declspecs_add_attrs(specs, attrs); + //attrs = get_identifier("fastcall"); + //attrs = build_tree_list(attrs, NULL_TREE); + //declspecs_add_attrs(specs, attrs); c_parser_consume_token (parser); break;