/*------------------------->  Sather - configfile  <-------------------------*/
/* Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        */
/* This file is part of the GNU Sather library. It is free software; you may */
/* redistribute  and/or modify it under the terms of the GNU Library General */
/* Public  License (LGPL)  as published  by the  Free  Software  Foundation; */
/* either version 2 of the license, or (at your option) any later version.   */
/* This  library  is distributed  in the  hope that it will  be  useful, but */
/* WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY */
/* or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       */
/* The license text is also available from:  Free Software Foundation, Inc., */
/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     */
/*------------>  Please email comments to <bug-sather@gnu.org>  <------------*/

#ifndef ARRAY_CONFIG
#define ARRAY_CONFIG

#ifdef PP
#undef PP
#endif

#define PP	no_pre,no_post

ARRAY_SIZE:			PP,reads "@0::asize",var "@r $$;",
				exec "$$=($0)==NULL?0:ASIZE(@(0)$0);" "$$",
				f_exec "$$=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);" "$$";
ARRAY_CLEAR:			PP,writes "@0::[],@0::asize",
				exec "if($0!=NULL) AREFACLEAR($0);",
				f_exec "if(!FVOID($0)) { if(^0) AREFACLEAR($0); else F_AREFACLEAR_A(@0,$0); }";
ARRAY_COPY:			PP,reads "@0::[]" "@0::asize",writes "@0::[]" "@0::asize",
				exec "if($0!=NULL && $1!=NULL) AREFACOPY($0,$1);",
				f_exec "if(!FVOID($0) && !FVOID($1)) { if(^0 && ^1) AREFACOPY($0,$1); else F_AREFACOPY_AA(@0,@P0,$0,$1); }";
ARRAY_COPY_BEG:			PP,reads "@0::[]" "@0::asize",writes "@0::[]" "@0::asize",
				exec "if($2!=NULL) AREFACOPYB($0,$1,$2);",
				f_exec "if(!FVOID($2)) { if(^0 && ^1) AREFACOPYB($0,$1,$2); else F_AREFACOPYB_AA(@0,@P0,$0,$1,$2); }";
ARRAY_COPY_BEG_NUM:		PP,reads "@0::[]" "@0::asize",writes "@0::[]" "@0::asize",
				exec "AREFACOPYBN($0,$1,$2,$3);",
				f_exec "if(^0 && ^1) AREFACOPYBN($0,$1,$2,$3); else F_AREFACOPYBN_AA(@0,@P0,$0,$1,$2,$3);";
ARRAY_COPY_BEG_NUM_SRCBEG:	PP,reads "@0::[]" "@0::asize",writes "@0::[]" "@0::asize",
				exec "AREFACOPYBNS($0,$1,$2,$3,$4);",
				f_exec "F_AREFACOPYBNS_AA(@0,@P0,$0,$1,$2,$3,$4);";

ARRAY_ELTB:			reads 	"@0::[]" "@0::asize",
				attr_access 1,
				var 	"INT $$br;",
				init 	"$$br=$0==NULL?0:ASIZE(@(0)$0);",
				break 	"$$br",
				temp 	"@r a$$;",
				iter 	"a$$=ARR(@(0)$0,$#);" "a$$",
				f_init 	"$$br=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);",
				f_iter  "#if %r==0" "if(^0) a$$=ARR(@(0)$0,$#); else F_R_RARR_NA(a$$,@0,$0,$#);" 
				        "#elif %r==1" "if(^0) a$$=ARR(@(0)$0,$#); else F_VA_RARR_NA(a$$,@0,$0,$#);" 
				        "#elif %r==2" "if(^0) VASS_LP(a$$,@r,ARR(@(0)$0,$#)); else F_V_RARR_LP(@r,a$$,@0,$0,$#);" 
				       	"#endif"
				       	"a$$";
ARRAY_ELT_BEGB:			reads 	"@0::[]" "@0::asize",
				var  	"INT $$c,$$s;",
				attr_access 1,
				temp 	"@r a$$;",
				init 	"$$c=$1-1;$$s=$0==0?0:ASIZE(@(0)$0);",
				f_init 	"$$c=$1-1;$$s=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);",
				iter 	"if(++$$c>=$$s) @@;"
				     	"a$$=ARR(@(0)$0,$$c);" "a$$",
				f_iter 	"if(++$$c>=$$s) @@;"
				        "#if %r==0" "if(^0) a$$=ARR(@(0)$0,$$c); else F_R_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==1" "if(^0) a$$=ARR(@(0)$0,$$c); else F_VA_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==2" "if(^0) VASS_LP(a$$,@r,ARR(@(0)$0,$#)); else F_V_RARR_LP(@r,a$$,@0,$0,$#);" 
				     	"#endif"
				     	"a$$";
ARRAY_ELT_BEG_NUMB:		reads 	"@0::[]" "@0::asize",
				var  	"INT $$c,$$m;",
				temp 	"@r a$$;",
				attr_access 1,
				init 	"$$c=$1-1;$$m=$1+$2;",
				iter 	"if(++$$c>=$$m) @@;"
				     	"a$$=ARR(@(0)$0,$$c);" "a$$",
				f_iter 	"if(++$$c>=$$m) @@;"
				        "#if %r==0" "if(^0) a$$=ARR(@(0)$0,$$c); else F_R_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==1" "if(^0) a$$=ARR(@(0)$0,$$c); else F_VA_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==2" "if(^0) VASS_LP(a$$,@r,ARR(@(0)$0,$#)); else F_V_RARR_LP(@r,a$$,@0,$0,$#);" 
				     	"#endif" 
				     	"a$$";
ARRAY_ELT_BEG_NUM_STEPB:	reads 	"@0::[]" "@0::asize",
				var  	"INT $$c,$$m;",
				attr_access 1,
				temp 	"@r a$$;",
				init 	"$$c=$1;$$m=$1+$2*$3;",
				iter 	"if($3>=0&&$$c>=$$m||$3<0&&$$c<=$$m)@@;"
				     	"a$$=ARR(@(0)$0,$$c);" "$$c+=$3;" "a$$",
				f_iter 	"if($$c>=$$m) @@;"
				        "#if %r==0" "if(^0) a$$=ARR(@(0)$0,$$c); else F_R_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==1" "if(^0) a$$=ARR(@(0)$0,$$c); else F_VA_RARR_NA(a$$,@0,$0,$$c);" 
				        "#elif %r==2" "if(^0) VASS_LP(a$$,@r,ARR(@(0)$0,$#)); else F_V_RARR_LP(@r,a$$,@0,$0,$#);" 
				     	"#endif" 
				     	"$$c+=$3;" "a$$";
ARRAY_SETB:			writes 	"@0::[]",
				attr_access 1,
				reads 	"@0::asize",
				var 	"INT $$br;",
				init 	"$$br=$0==NULL?0:ASIZE(@(0)$0);",
				f_init 	"$$br=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);",
				break 	"$$br",
				iter 	"SARR(@(0)$0,$#,@(1)$1);",
				f_iter  "#if %1==0" "if(^0) SARR(@(0)$0,$#,@(1)$1); else F_R_WARR_NA(@0,$0,$#,$1);" 
				        "#elif %1==1" "if(^0) SARR(@(0)$0,$#,@(1)$1); else F_VA_WARR_NA(@0,$0,$#,$1);" 
				        "#elif %1==2" "if(^0) { CHK_BOUNDS($#,0,ASIZE($0)-1,0);VASS_PP((@(0)$0)->arr_part[$#],@1,$1);} else F_V_WARR_LP(@0,$0,$#,@1,$1);" 
					"#endif";
ARRAY_SET_BEGB:			writes  "@0::[]",
				attr_access 1,
				reads   "@0::asize",
				var     "INT $$c,$$s;",
				init    "$$c=$1-1;$$s=$0==NULL?0:ASIZE(@(0)$0);",
				f_init  "$$c=$1-1;$$s=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);",
				iter    "if(++$$c>=$$s) @@;"
				        "SARR(@(0)$0,$$c,@(2)$2);",
				f_iter  "if(++$$c>=$$s) @@;"
				        "#if %2==0" "if(^0) SARR(@(0)$0,$$c,@(2)$2); else F_R_WARR_NA(@0,$0,$$c,$2);" 
				        "#elif %2==1" "if(^0) SARR(@(0)$0,$$c,@(2)$2); else F_VA_WARR_NA(@0,$0,$$c,$2);" 
				        "#elif %2==2" "if(^0) { CHK_BOUNDS($$c,0,ASIZE($0)-1,0);VASS_PP((@(0)$0)->arr_part[$$c],@2,$2);} else F_V_WARR_LP(@0,$0,$$c,@2,$2);" 
				        "#endif";
ARRAY_SET_BEG_NUMB:		writes  "@0::[]",
				attr_access 1,
				reads   "@0::asize",
				var     "INT $$c,$$m;",
				init    "$$c=$1-1;$$m=$1+$2;",
				iter    "if(++$$c>=$$m) @@;"
				        "SARR(@(0)$0,$$c,@(3)$3);",
				f_iter  "if(++$$c>=$$m) @@;"
				        "#if %3==0" "if(^0) SARR(@(0)$0,$$c,@(1)$3); else F_R_WARR_NA(@0,$0,$$c,$3);" 
				        "#elif %3==1" "if(^0) SARR(@(0)$0,$$c,@(1)$3); else F_VA_WARR_NA(@0,$0,$$c,$3);" 
				        "#elif %3==2" "if(^0) { CHK_BOUNDS($$c,0,ASIZE($0)-1,0);VASS_PP((@(0)$0)->arr_part[$$c],@3,$3);} else F_V_WARR_LP(@0,$0,$$c,@3,$3);" 
				        "#endif";
ARRAY_SET_BEG_NUM_STEPB:	reads   "@0::[]",
				attr_access 1,
				writes  "@0::asize",
				var     "INT $$c,$$m;",
				init    "$$c=$1;$$m=$1+$2*$3;",
				iter    "if($3>=0&&$$c>=$$m||$3<0&&$$c<=$$m)@@;"
				        "SARR(@(0)$0,$$c,@(4)$4);" "$$c+=$3;",
				f_iter  "if($$c>=$$m) @@;"
				        "#if %4==0" "if(^0) SARR(@(0)$0,$$c,@(1)$4); else F_R_WARR_NA(@0,$0,$$c,$4);" 
				        "#elif %4==1" "if(^0) SARR(@(0)$0,$$c,@(1)$4); else F_VA_WARR_NA(@0,$0,$$c,$4);" 
				        "#elif %4==2" "if(^0) { CHK_BOUNDS($$c,0,ASIZE($0)-1,0);VASS_PP((@(0)$0)->arr_part[$$c],@4,$4);} else F_V_WARR_LP(@0,$0,$$c,@4,$4);" 
				        "#endif" 
				        "$$c+=$3;";
ARRAY_INDB:			reads 	"@0::asize",
				var 	"INT $$br;",
				init 	"$$br=$0==NULL?0:ASIZE(@(0)$0);",
				f_init 	"$$br=FVOID($0)?0:^0?ASIZE(@(0)$0):F_ASIZE(@0,$0);",
				break 	"$$br",
				temp 	"@r r$$;",
				iter 	"r$$=$#;" "r$$";

#endif
