From: xchaos Date: Sun, 21 Sep 2008 11:19:45 +0000 (+0000) Subject: multiple-evalution-of-args-safe versions of repeat() { } and for_range() { } macros X-Git-Url: https://git.harvie.cz/?a=commitdiff_plain;h=a3c2aecbff1dd82a26f3a69a3e1fdc04349b8d7a;p=svn%2FCll1h%2F.git multiple-evalution-of-args-safe versions of repeat() { } and for_range() { } macros git-svn-id: https://dev.arachne.cz/repos/cll1h/trunk@88 4bb87942-c103-4e5a-b51c-0ebff58f8515 --- diff --git a/cll1.h b/cll1.h index 07c9189..356d70d 100644 --- a/cll1.h +++ b/cll1.h @@ -151,8 +151,8 @@ extern unsigned RANDOM_SEED; / 7. C<<1 builtin iterators and conditionals, updated 2008-01-26 xCh. '----------------------------------------------------------------------- */ #define loop while(TRUE) -#define repeat(N) _NEW(I,0) while(_I++=TO ; FROM<=TO?VAR++:VAR--) +#define repeat(N) _NEW(I,0) _NEW(J,N) while(_I++<_J) +#define for_range(VAR,FROM,TO) _NEW(I,FROM) _NEW(J,TO) for( VAR=_I ; _I<=_J?VAR<=_J:VAR>=_J ; _I<=_J?VAR++:VAR--) #define for_each(NODE,HEAD) for(NODE=HEAD; NODE; NODE=NODE->__next) #define for_search(NODE,HEAD,EXPR) for_each(NODE,HEAD) if(EXPR) #define for_file_lines(STR,FNAME) /* _NEW(CTX,get_context()) file_read(FNAME) for(use_context(_CTX),STR=file_line(_F);release_context(_M),(*S && !feof(_F));STR=file_line(_F),end_context()) _CATCH */ @@ -231,6 +231,7 @@ extern _DECLARE_STRSTR; / 10. C<<1 private infrastructure, updated 2008-02-03 by xCh. '----------------------------------------------------------------------- */ #define _I (_Iatom->I) +#define _J (_Jatom->J) #define _S (_Satom->S) #define _F (_Fatom->F) #define _CTX (_CTXatom->CTX) @@ -242,8 +243,9 @@ extern _DECLARE_STRSTR; #define _FOR_VALID_COLUMNS(A,B,C) _NEW(I,0) for( prefix(A,B,C) ; A ; ((A!=B)&&prefix(A,B,C))||(A=NULL) ) if(*A&&++_I) #define _NEW(NAME,VALUE) for(_##NAME##atom=get_mem(_##NAME##Atom),_##NAME##atom->NAME=(VALUE),_##NAME##atom->c=1,push(_##NAME##atom,_##NAME##stack);_##NAME##atom->c||(pop(_##NAME##atom,_##NAME##stack),0);_##NAME##atom->c--) #define _ANYSTACK(NAME) _##NAME##Atom _##NAME##atom,_##NAME##stack=NULL; -#define _EXPORT_STACKS _ANYSTACK(I) _ANYSTACK(S) _ANYSTACK(F) _ANYSTACK(CTX) +#define _EXPORT_STACKS _ANYSTACK(I) _ANYSTACK(J) _ANYSTACK(S) _ANYSTACK(F) _ANYSTACK(CTX) _ANYATOM(int,I); +_ANYATOM(int,J); _ANYATOM(str,S); _ANYATOM(FILE *,F); _ANYATOM(void *,CTX); diff --git a/demos/for_range.c b/demos/for_range.c index 44a7b5b..c96f24c 100644 --- a/demos/for_range.c +++ b/demos/for_range.c @@ -2,25 +2,50 @@ program { - int i; + int i,j=1; - echo("for_range(i,0,1)"); - for_range(i,0,1) printf(" [%d]",i); + echo("Just plain vanilla auto-increment:\tfor_range(i,1,5)"); + for_range(i,1,5) + { + printf(" [%d]",i); + } print(""); - echo("for_range(i,1,0)"); - for_range(i,1,0) printf(" [%d]",i); + echo("Single-evaluation of macro argument:\tj=1; for_range(i,0,j++)"); + for_range(i,0,j++) + { + printf(" [%d]",i); + } print(""); - echo("for_range(i,1,1)"); - for_range(i,1,1) printf(" [%d]",i); + echo("Just plain vanilla auto-decrement:\tfor_range(i,1,0)"); + for_range(i,1,0) + { + printf(" [%d]",i); + } print(""); - echo("for_range(i,1,5)"); - for_range(i,1,5) printf(" [%d]",i); + echo("Single iteration is possible too:\tfor_range(i,1,1)"); + for_range(i,1,1) + { + printf(" [%d]",i); + } print(""); - echo("for_range(i,5,1)"); - for_range(i,5,1) printf(" [%d]",i); + echo("Yet another example of macro safety:\tj=2; for_range(i,5,--j)"); + for_range(i,5,--j) + { + printf(" [%d]",i); + } + print(""); + + echo("Nesting of this macro seems to be safe:\tfor_range(i,1,3) for_range(j,3,1)"); + for_range(i,1,3) + { + for_range(j,3,1) + { + printf(" [%d,%d]",i,j); + } + } print(""); } diff --git a/demos/repeat.c b/demos/repeat.c index 70a5abe..b6229e9 100644 --- a/demos/repeat.c +++ b/demos/repeat.c @@ -2,9 +2,19 @@ program { - repeat(2) + int i=2; + + repeat(1) { - print("Tohle cele delam 2x:"); - repeat(3) print("Tohle delam 3x..."); + print("This is demonstration, that nesting of C<<1 repeat(N) { ... } flow-control macro is completely safe:"); + repeat(i++) + { + echo("Outer loop is supposed to be done twice: "); + repeat(i) + { + printf("[doing this %d times] ",i); + } + print("... finished."); + } } }