@@ -75,6 +75,7 @@ static AC_INTRINSIC map_I_to_AC(int intrin);
7575static AC_INTRINSIC map_PD_to_AC (int pdnum );
7676static bool is_illegal_expr_in_init (SPTR , int ast , DTYPE );
7777static int init_intrin_type_desc (int ast , SPTR sptr , int std );
78+ static SPTR get_substring (SPTR str , int lb , int rb );
7879
7980/*
8081 * semant-created temporaries which are re-used across statements.
@@ -1025,7 +1026,7 @@ static const char *_iexpr_op[] = {
10251026 "?0?" , "ADD" , "SUB" , "MUL" , "DIV" , "EXP" , "NEG" ,
10261027 "INTR_CALL" , "ARRAYREF" , "MEMBR_SEL" , "CONV" , "CAT" , "EXPK" , "LEQV" ,
10271028 "LNEQV" , "LOR" , "LAND" , "EQ" , "GE" , "GT" , "LE" ,
1028- "LT" , "NE" , "LNOT" , "EXPX" , "TRIPLE" ,
1029+ "LT" , "NE" , "LNOT" , "EXPX" , "TRIPLE" , "SUBSTR" ,
10291030};
10301031
10311032static const char *
@@ -1951,7 +1952,20 @@ compute_size_expr(bool add_flag, ACL *aclp, DTYPE dtype)
19511952 dtype = SST_DTYPEG (stkp );
19521953 }
19531954 }
1954- acs .eltype = dt ;
1955+ if (sem .dinit_data && id == S_EXPR && A_TYPEG (SST_ASTG (stkp )) == A_SUBSTR ) {
1956+ int ast , leftval , rightval , lenval , len ;
1957+ DTYPE newdtype ;
1958+ ast = SST_ASTG (stkp );
1959+ leftval = dinit_eval (A_LEFTG (ast ));
1960+ rightval = dinit_eval (A_RIGHTG (ast ));
1961+ lenval = rightval - leftval + 1 ;
1962+ len = lenval <= 0 ? astb .i0 : mk_cval (lenval , DT_INT4 );
1963+ newdtype = get_type (2 , DTY (dt ), len );
1964+ acs .eltype = newdtype ;
1965+ A_DTYPEP (ast , newdtype );
1966+ } else {
1967+ acs .eltype = dt ;
1968+ }
19551969 switch (DTY (acs .eltype )) {
19561970 case TY_CHAR :
19571971 case TY_NCHAR :
@@ -4855,7 +4869,31 @@ construct_acl_from_ast(int ast, DTYPE dtype, int parent_acltype)
48554869 aclp -> is_const = 1 ;
48564870 aclp -> subc = prev ;
48574871 }
4872+ break ;
4873+ case A_SUBSTR :
4874+ aclp = GET_ACL (15 );
4875+ aclp -> id = AC_IEXPR ;
4876+ aclp -> u1 .expr = (AEXPR * )getitem (15 , sizeof (AEXPR ));
4877+ aclp -> u1 .expr -> op = AC_SUBSTR ;
4878+ aclp -> u1 .expr -> lop = construct_acl_from_ast (A_LOPG (ast ), 0 , 0 );
4879+ if (!aclp -> u1 .expr -> lop ) {
4880+ return 0 ;
4881+ }
4882+ aclp -> dtype = A_DTYPEG (ast );
4883+ l = GET_ACL (15 );
4884+ l -> id = AC_AST ;
4885+ l -> is_const = 1 ;
4886+ l -> u1 .ast = A_LEFTG (ast );
4887+ l -> dtype = A_DTYPEG (A_LEFTG (ast ));
4888+
4889+ u = GET_ACL (15 );
4890+ u -> id = AC_AST ;
4891+ u -> is_const = 1 ;
4892+ u -> u1 .ast = A_RIGHTG (ast );
4893+ u -> dtype = A_DTYPEG (A_RIGHTG (ast ));
48584894
4895+ l -> next = u ;
4896+ aclp -> u1 .expr -> rop = l ;
48594897 break ;
48604898 default :
48614899 interr ("unexpected ast type in initialization expr" , ast , 3 );
@@ -7337,6 +7375,20 @@ add_array_init(ASTLIST *list, int ast, DTYPE dtype, int sptr)
73377375 }
73387376} /* add_array_init */
73397377
7378+ static void
7379+ add_substr_init (ASTLIST * list , int ast , DTYPE dtype , int sptr )
7380+ {
7381+ SPTR src , substr ;
7382+ int lb , ub , substr_ast ;
7383+
7384+ src = A_SPTRG (A_LOPG (ast ));
7385+ lb = (int )dinit_eval (A_LEFTG (ast ));
7386+ ub = (int )dinit_eval (A_RIGHTG (ast ));
7387+ substr = get_substring (src , lb , ub );
7388+ substr_ast = mk_cval (substr , DTYPEG (substr ));
7389+ add_init (list , substr_ast , dtype , sptr );
7390+ }
7391+
73407392static ACL *
73417393dinit_fill_struct (ASTLIST * list , ACL * aclp , int sdtype , int sptr ,
73427394 int memberlist , int init_single )
@@ -7412,6 +7464,8 @@ dinit_fill_struct(ASTLIST *list, ACL *aclp, int sdtype, int sptr,
74127464 aa = mk_init (PARAMVALG (A_SPTRG (aast )), dtype );
74137465 A_SPTRP (aa , sptr );
74147466 add_init (list , aast , dtype , sptr );
7467+ } else if (A_TYPEG (aast ) == A_SUBSTR ) {
7468+ add_substr_init (list , aast , sdtype , sptr );
74157469 } else {
74167470 if (DTY (sdtype ) == TY_ARRAY ) {
74177471 aast = dinit_getval1 (aast , DTY (sdtype + 1 ));
@@ -7517,6 +7571,7 @@ dinit_fill_struct(ASTLIST *list, ACL *aclp, int sdtype, int sptr,
75177571 save_conval1 = CONVAL1G (idx_sptr );
75187572 if (stepval >= 0 ) {
75197573 for (i = initval ; i <= limitval ; i += stepval ) {
7574+ sem .dostack -> currval = i ;
75207575 switch (DTY (DTYPEG (idx_sptr ))) {
75217576 case TY_INT8 :
75227577 case TY_LOG8 :
@@ -7532,6 +7587,7 @@ dinit_fill_struct(ASTLIST *list, ACL *aclp, int sdtype, int sptr,
75327587 }
75337588 } else {
75347589 for (i = initval ; i >= limitval ; i += stepval ) {
7590+ sem .dostack -> currval = i ;
75357591 switch (DTY (DTYPEG (idx_sptr ))) {
75367592 case TY_INT8 :
75377593 case TY_LOG8 :
@@ -11155,6 +11211,66 @@ eval_const_array_section(ACL *lop, int ldtype)
1115511211 return sb .root ;
1115611212}
1115711213
11214+ static SPTR
11215+ get_static_str (SPTR sptr )
11216+ {
11217+ DREC * p = NULL ;
11218+ SPTR cnst_sptr ;
11219+ LOGICAL found ;
11220+ DTYPE dtype ;
11221+
11222+ cnst_sptr = 0 ;
11223+ found = FALSE;
11224+ dtype = DTYPEG (sptr );
11225+ dinit_save ();
11226+ while ((p = dinit_read ())) {
11227+ int tdtype = p -> dtype ;
11228+ INT tconval = p -> conval ;
11229+ if (tdtype == DINIT_LOC ) {
11230+ if (tconval == sptr ) {
11231+ found = TRUE;
11232+ } else {
11233+ found = FALSE;
11234+ }
11235+ continue ;
11236+ }
11237+ if (tdtype == DINIT_STR ) {
11238+ if (found ) {
11239+ cnst_sptr = tconval ;
11240+ break ;
11241+ }
11242+ }
11243+ found = FALSE;
11244+ }
11245+ dinit_restore ();
11246+
11247+ if (cnst_sptr == 0 || STYPEG (cnst_sptr ) != ST_CONST ) {
11248+ return 0 ;
11249+ }
11250+ return cnst_sptr ;
11251+ }
11252+
11253+ static ACL *
11254+ eval_substr (ACL * lop , ACL * rop )
11255+ {
11256+ SPTR p ;
11257+ int lb , ub ;
11258+ ACL * ret = NULL ;
11259+
11260+ lb = rop -> conval ;
11261+ ub = rop -> next -> conval ;
11262+ p = get_substring (lop -> conval , lb , ub );
11263+
11264+ ret = GET_ACL (15 );
11265+ BZERO (ret , ACL , 1 );
11266+ ret -> id = AC_CONST ;
11267+ ret -> dtype = DTYPEG (p );
11268+ ret -> repeatc = astb .i1 ;
11269+ ret -> conval = ret -> sptr = p ;
11270+ ret -> u1 .ast = mk_cnst (ret -> conval );
11271+ return ret ;
11272+ }
11273+
1115811274static ISZ_T
1115911275get_ival (DTYPE dtype , INT conval )
1116011276{
@@ -11404,6 +11520,8 @@ eval_init_op(int op, ACL *lop, DTYPE ldtype, ACL *rop, DTYPE rdtype, SPTR sptr,
1140411520
1140511521 root = clone_init_const (c , TRUE);
1140611522 root = eval_init_expr (root );
11523+ } else if (op == AC_SUBSTR ) {
11524+ root = eval_substr (lop , rop );
1140711525 } else if (op == AC_INTR_CALL ) {
1140811526 AC_INTRINSIC intrin = lop -> u1 .i ;
1140911527 switch (intrin ) {
@@ -11901,6 +12019,12 @@ eval_do(ACL *ido)
1190112019 INT sav_conval1 = CONVAL1G (idx_sptr );
1190212020 int inflag = 0 ;
1190312021
12022+ if (sem .top == & sem .dostack [MAX_DOSTACK ]) {
12023+ errsev (34 );
12024+ return 0 ;
12025+ }
12026+ ++ sem .top ;
12027+
1190412028 initval = dinit_eval (di -> init_expr );
1190512029 if (sem .dinit_error ) {
1190612030 interr ("Non-constant implied DO initial value" , di -> init_expr , 3 );
@@ -11921,6 +12045,7 @@ eval_do(ACL *ido)
1192112045
1192212046 if (stepval >= 0 ) {
1192312047 for (i = initval ; i <= limitval ; i += stepval ) {
12048+ sem .dostack -> currval = i ;
1192412049 switch (DTY (DTYPEG (idx_sptr ))) {
1192512050 case TY_INT8 :
1192612051 case TY_LOG8 :
@@ -11946,6 +12071,7 @@ eval_do(ACL *ido)
1194612071 }
1194712072 } else {
1194812073 for (i = initval ; i >= limitval ; i += stepval ) {
12074+ sem .dostack -> currval = i ;
1194912075 switch (DTY (DTYPEG (idx_sptr ))) {
1195012076 case TY_INT8 :
1195112077 case TY_LOG8 :
@@ -11971,6 +12097,7 @@ eval_do(ACL *ido)
1197112097 }
1197212098
1197312099 CONVAL1P (idx_sptr , sav_conval1 );
12100+ -- sem .top ;
1197412101
1197512102 return root ;
1197612103}
@@ -14836,3 +14963,33 @@ gen_set_type(int dest_ast, int src_ast, int std, LOGICAL insert_before,
1483614963
1483714964 return std ;
1483814965}
14966+
14967+ static SPTR
14968+ get_substring (SPTR src , int lb , int ub )
14969+ {
14970+ char * char_cnst = NULL ;
14971+ char * str = NULL ;
14972+ int cvlen , len ;
14973+ SPTR p ;
14974+
14975+ if (DINITG (src ) && SCG (src ) == SC_STATIC ) {
14976+ src = get_static_str (src );
14977+ }
14978+ char_cnst = stb .n_base + CONVAL1G (src );
14979+ cvlen = ub - lb + 1 ;
14980+ if (cvlen < 1 ) {
14981+ p = getstring ("" , 0 );
14982+ } else {
14983+ str = getitem (0 , cvlen + 1 );
14984+ memset (str , '\0' , cvlen );
14985+ len = strlen (char_cnst );
14986+ if (lb - 1 + cvlen < len ) {
14987+ memcpy (str , char_cnst + lb - 1 , sizeof (char ) * cvlen );
14988+ } else if (lb - 1 < len ) {
14989+ memcpy (str , char_cnst + lb - 1 , sizeof (char ) * (len - lb + 1 ));
14990+ }
14991+ str [cvlen ] = '\0' ;
14992+ p = getstring (str , cvlen );
14993+ }
14994+ return p ;
14995+ }
0 commit comments