12508Sdlw /* 2*17876Sdlw char id_fmt[] = "@(#)fmt.c 1.6"; 32508Sdlw * 42508Sdlw * fortran format parser 52508Sdlw */ 62508Sdlw 72508Sdlw #include "fio.h" 82591Sdlw #include "format.h" 92508Sdlw 102508Sdlw #define isdigit(x) (x>='0' && x<='9') 112508Sdlw #define isspace(s) (s==' ') 122508Sdlw #define skip(s) while(isspace(*s)) s++ 132508Sdlw 142508Sdlw #ifdef interdata 152508Sdlw #define SYLMX 300 162508Sdlw #endif 172508Sdlw 182508Sdlw #ifdef pdp11 192508Sdlw #define SYLMX 300 202508Sdlw #endif 212508Sdlw 222508Sdlw #ifdef vax 232508Sdlw #define SYLMX 300 242508Sdlw #endif 252508Sdlw 262508Sdlw struct syl syl[SYLMX]; 272508Sdlw int parenlvl,pc,revloc; 282508Sdlw char *f_s(), *f_list(), *i_tem(), *gt_num(), *ap_end(); 292508Sdlw 302508Sdlw pars_f(s) char *s; 312508Sdlw { 322508Sdlw parenlvl=revloc=pc=0; 332508Sdlw return((f_s(s,0)==FMTERR)? ERROR : OK); 342508Sdlw } 352508Sdlw 362508Sdlw char *f_s(s,curloc) char *s; 372508Sdlw { 382508Sdlw skip(s); 392508Sdlw if(*s++!='(') 402508Sdlw { 412508Sdlw fmtptr = s; 422508Sdlw return(FMTERR); 432508Sdlw } 442508Sdlw if(parenlvl++ ==1) revloc=curloc; 452508Sdlw op_gen(RET,curloc,0,0,s); 462508Sdlw if((s=f_list(s))==FMTERR) 472508Sdlw { 482508Sdlw return(FMTERR); 492508Sdlw } 502508Sdlw skip(s); 512508Sdlw return(s); 522508Sdlw } 532508Sdlw 542508Sdlw char *f_list(s) char *s; 552508Sdlw { 562508Sdlw while (*s) 572508Sdlw { skip(s); 582508Sdlw if((s=i_tem(s))==FMTERR) return(FMTERR); 592508Sdlw skip(s); 602508Sdlw if(*s==',') s++; 612508Sdlw else if(*s==')') 622508Sdlw { if(--parenlvl==0) 632508Sdlw op_gen(REVERT,revloc,0,0,s); 6416597Sralph else 6516597Sralph op_gen(GOTO,0,0,0,s); 662508Sdlw return(++s); 672508Sdlw } 682508Sdlw } 692508Sdlw fmtptr = s; 702508Sdlw return(FMTERR); 712508Sdlw } 722508Sdlw 732508Sdlw char *i_tem(s) char *s; 742508Sdlw { char *t; 752508Sdlw int n,curloc; 762508Sdlw if(*s==')') return(s); 7716597Sralph if ((n=ne_d(s,&t))==FMTOK) 7816597Sralph return(t); 7916597Sralph else if (n==FMTERR) 8016597Sralph return(FMTERR); 8116597Sralph if ((n=e_d(s,&t))==FMTOK) 8216597Sralph return(t); 8316597Sralph else if (n==FMTERR) 8416597Sralph return(FMTERR); 852508Sdlw s=gt_num(s,&n); 8616597Sralph if (n == 0) { fmtptr = s; return(FMTERR); } 872508Sdlw curloc = op_gen(STACK,n,0,0,s); 882508Sdlw return(f_s(s,curloc)); 892508Sdlw } 902508Sdlw 912508Sdlw ne_d(s,p) char *s,**p; 922508Sdlw { int n,x,sign=0,pp1,pp2; 932508Sdlw switch(lcase(*s)) 942508Sdlw { 952508Sdlw case ':': op_gen(COLON,(int)('\n'),0,0,s); break; 962508Sdlw #ifndef KOSHER 972508Sdlw case '$': op_gen(DOLAR,(int)('\0'),0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 982508Sdlw #endif 992508Sdlw case 'b': 1002508Sdlw switch(lcase(*(s+1))) 1012508Sdlw { 102*17876Sdlw case 'n': s++; op_gen(BNZ,0,0,0,s); break; 103*17876Sdlw case 'z': s++; op_gen(BNZ,1,0,0,s); break; 104*17876Sdlw #ifndef KOSHER 105*17876Sdlw default: op_gen(B,0,0,0,s); break; /*** NOT STANDARD FORTRAN ***/ 106*17876Sdlw #else 107*17876Sdlw default: fmtptr = s; return(FMTUNKN); 108*17876Sdlw #endif 1092508Sdlw } 1102508Sdlw break; 1112508Sdlw case 's': 1122508Sdlw switch(lcase(*(s+1))) 1132508Sdlw { 1142508Sdlw case 'p': s++; x=SP; pp1=1; pp2=1; break; 1152508Sdlw #ifndef KOSHER 1162508Sdlw case 'u': s++; x=SU; pp1=0; pp2=0; break; /*** NOT STANDARD FORTRAN ***/ 1172508Sdlw #endif 1182508Sdlw case 's': s++; x=SS; pp1=0; pp2=1; break; 1192508Sdlw default: x=S; pp1=0; pp2=1; break; 1202508Sdlw } 1212508Sdlw op_gen(x,pp1,pp2,0,s); 1222508Sdlw break; 1232508Sdlw case '/': op_gen(SLASH,0,0,0,s); break; 12412231Sdlw 12512231Sdlw case '-': sign=1; /* OUTRAGEOUS CODING */ 12612231Sdlw case '+': s++; /* OUTRAGEOUS CODING */ 1272508Sdlw case '0': case '1': case '2': case '3': case '4': 1282508Sdlw case '5': case '6': case '7': case '8': case '9': 1292508Sdlw s=gt_num(s,&n); 1302508Sdlw switch(lcase(*s)) 1312508Sdlw { 1322508Sdlw case 'p': if(sign) n= -n; op_gen(P,n,0,0,s); break; 1332508Sdlw #ifndef KOSHER 1342508Sdlw case 'r': if(n<=1) /*** NOT STANDARD FORTRAN ***/ 13516597Sralph { fmtptr = --s; return(FMTERR); } 1362508Sdlw op_gen(R,n,0,0,s); break; 1372508Sdlw case 't': op_gen(T,0,n,0,s); break; /* NOT STANDARD FORT */ 1382508Sdlw #endif 1392508Sdlw case 'x': op_gen(X,n,0,0,s); break; 1402508Sdlw case 'h': op_gen(H,n,(int)(s+1),0,s); 1412508Sdlw s+=n; 1422508Sdlw break; 14316597Sralph default: fmtptr = s; return(FMTUNKN); 1442508Sdlw } 1452508Sdlw break; 1462508Sdlw case GLITCH: 1472508Sdlw case '"': 1482508Sdlw case '\'': op_gen(APOS,(int)s,0,0,s); 1492508Sdlw *p = ap_end(s); 1502508Sdlw return(FMTOK); 1512508Sdlw case 't': 1522508Sdlw switch(lcase(*(s+1))) 1532508Sdlw { 1542508Sdlw case 'l': s++; x=TL; break; 1552508Sdlw case 'r': s++; x=TR; break; 1562508Sdlw default: x=T; break; 1572508Sdlw } 1582508Sdlw if(isdigit(*(s+1))) {s=gt_num(s+1,&n); s--;} 15916597Sralph #ifdef KOSHER 16016597Sralph else { fmtptr = s; return(FMTERR); } 16116597Sralph #else 1622508Sdlw else n = 0; /* NOT STANDARD FORTRAN, should be error */ 1632508Sdlw #endif 1642508Sdlw op_gen(x,n,1,0,s); 1652508Sdlw break; 1662508Sdlw case 'x': op_gen(X,1,0,0,s); break; 1672508Sdlw case 'p': op_gen(P,0,0,0,s); break; 1682508Sdlw #ifndef KOSHER 1692508Sdlw case 'r': op_gen(R,10,1,0,s); break; /*** NOT STANDARD FORTRAN ***/ 1702508Sdlw #endif 1712508Sdlw 17216597Sralph default: fmtptr = s; return(FMTUNKN); 1732508Sdlw } 1742508Sdlw s++; 1752508Sdlw *p=s; 1762508Sdlw return(FMTOK); 1772508Sdlw } 1782508Sdlw 1792508Sdlw e_d(s,p) char *s,**p; 1802508Sdlw { int n,w,d,e,x=0; 1812508Sdlw char *sv=s; 1822508Sdlw char c; 1832508Sdlw s=gt_num(s,&n); 18416597Sralph if (n == 0) goto ed_err; 1852508Sdlw op_gen(STACK,n,0,0,s); 1862508Sdlw c = lcase(*s); s++; 1872508Sdlw switch(c) 1882508Sdlw { 1892508Sdlw case 'd': 1902508Sdlw case 'e': 1912508Sdlw case 'g': 1922508Sdlw s = gt_num(s, &w); 19316597Sralph if (w==0) goto ed_err; 1942508Sdlw if(*s=='.') 1952508Sdlw { s++; 1962508Sdlw s=gt_num(s,&d); 1972508Sdlw } 1982508Sdlw else d=0; 1992508Sdlw if(lcase(*s) == 'e' 2002508Sdlw #ifndef KOSHER 2012508Sdlw || *s == '.' /*** '.' is NOT STANDARD FORTRAN ***/ 2022508Sdlw #endif 2032508Sdlw ) 2042508Sdlw { s++; 2052508Sdlw s=gt_num(s,&e); 2062508Sdlw if(c=='e') n=EE; else if(c=='d') n=DE; else n=GE; 2072508Sdlw } 2082508Sdlw else 2092508Sdlw { e=2; 2102508Sdlw if(c=='e') n=E; else if(c=='d') n=D; else n=G; 2112508Sdlw } 21216597Sralph if (e==0) goto ed_err; 2132508Sdlw op_gen(n,w,d,e,s); 2142508Sdlw break; 2152508Sdlw case 'l': 2162508Sdlw s = gt_num(s, &w); 21716597Sralph if (w==0) goto ed_err; 2182508Sdlw op_gen(L,w,0,0,s); 2192508Sdlw break; 2202508Sdlw case 'a': 2212508Sdlw skip(s); 22216597Sralph if(isdigit(*s)) 2232508Sdlw { s=gt_num(s,&w); 22416597Sralph #ifdef KOSHER 22516597Sralph if (w==0) goto ed_err; 22616597Sralph #else 22716597Sralph if (w==0) op_gen(A,0,0,0,s); 22816597Sralph else 22916597Sralph #endif 2302508Sdlw op_gen(AW,w,0,0,s); 2312508Sdlw break; 2322508Sdlw } 2332508Sdlw op_gen(A,0,0,0,s); 2342508Sdlw break; 2352508Sdlw case 'f': 2362508Sdlw s = gt_num(s, &w); 23716597Sralph if (w==0) goto ed_err; 2382508Sdlw if(*s=='.') 2392508Sdlw { s++; 2402508Sdlw s=gt_num(s,&d); 2412508Sdlw } 2422508Sdlw else d=0; 2432508Sdlw op_gen(F,w,d,0,s); 2442508Sdlw break; 24516597Sralph #ifndef KOSHER 24616597Sralph case 'o': /*** octal format - NOT STANDARD FORTRAN ***/ 24716597Sralph case 'z': /*** hex format - NOT STANDARD FORTRAN ***/ 24816597Sralph #endif 2492508Sdlw case 'i': 2502508Sdlw s = gt_num(s, &w); 25116597Sralph if (w==0) goto ed_err; 2522508Sdlw if(*s =='.') 2532508Sdlw { 2542508Sdlw s++; 2552508Sdlw s=gt_num(s,&d); 2562508Sdlw x = IM; 2572508Sdlw } 2582508Sdlw else 2592508Sdlw { d = 1; 2602508Sdlw x = I; 2612508Sdlw } 26216597Sralph #ifndef KOSHER 26316597Sralph if (c == 'o') 26416597Sralph op_gen(R,8,1,0,s); 26516597Sralph else if (c == 'z') 26616597Sralph op_gen(R,16,1,0,s); 26716597Sralph #endif 2682508Sdlw op_gen(x,w,d,0,s); 26916597Sralph #ifndef KOSHER 27016597Sralph if (c == 'o' || c == 'z') 27116597Sralph op_gen(R,10,1,0,s); 27216597Sralph #endif 2732508Sdlw break; 2742508Sdlw default: 2752508Sdlw pc--; /* unSTACK */ 2762508Sdlw *p = sv; 2772508Sdlw fmtptr = s; 27816597Sralph return(FMTUNKN); 2792508Sdlw } 2802508Sdlw *p = s; 2812508Sdlw return(FMTOK); 28216597Sralph ed_err: 28316597Sralph fmtptr = --s; 28416597Sralph return(FMTERR); 2852508Sdlw } 2862508Sdlw 2872508Sdlw op_gen(a,b,c,d,s) char *s; 2882508Sdlw { struct syl *p= &syl[pc]; 2892508Sdlw if(pc>=SYLMX) 2902508Sdlw { fmtptr = s; 2912591Sdlw fatal(F_ERFMT,"format too complex"); 2922508Sdlw } 2932508Sdlw #ifdef DEBUG 2942508Sdlw fprintf(stderr,"%3d opgen: %d %d %d %d %c\n", 2952508Sdlw pc,a,b,c,d,*s==GLITCH?'"':*s); /* for debug */ 2962508Sdlw #endif 2972508Sdlw p->op=a; 2982508Sdlw p->p1=b; 2992508Sdlw p->p2=c; 3002508Sdlw p->p3=d; 3012508Sdlw return(pc++); 3022508Sdlw } 3032508Sdlw 3042508Sdlw char *gt_num(s,n) char *s; int *n; 3052508Sdlw { int m=0,a_digit=NO; 3062508Sdlw skip(s); 3072508Sdlw while(isdigit(*s) || isspace(*s)) 3082508Sdlw { 3092508Sdlw if (isdigit(*s)) 3102508Sdlw { 3112508Sdlw m = 10*m + (*s)-'0'; 3122508Sdlw a_digit = YES; 3132508Sdlw } 3142508Sdlw s++; 3152508Sdlw } 3162508Sdlw if(a_digit) *n=m; 3172508Sdlw else *n=1; 3182508Sdlw return(s); 3192508Sdlw } 3202508Sdlw 3212508Sdlw char *ap_end(s) char *s; 3222508Sdlw { 3232508Sdlw char quote; 3242508Sdlw quote = *s++; 3252508Sdlw for(;*s;s++) 3262508Sdlw { 3272508Sdlw if(*s==quote && *++s!=quote) return(s); 3282508Sdlw } 3292508Sdlw fmtptr = s; 3302591Sdlw fatal(F_ERFMT,"bad string"); 3312508Sdlw } 332