subroutine expr c c analyseur d'expressions c c Copyright INRIA INCLUDE '../stack.h' parameter (nz1=nsiz-1,nz2=nsiz-2) integer iadr,sadr c integer op,r,blank,sign,plus,minus,name,colon,eye(nsiz),ou,et integer equal,less,great,not,eol,p,temp,s logical eptover, skip, compil, ifexpr, istrue external gettype,istrue data colon/44/,blank/40/,plus/45/,minus/46/,ou/57/,et/58/ data equal/50/,less/59/,great/60/,not/61/ data eye/672014862,nz1*673720360/,name/1/,eol/99/ c sadr(l)=(l/2)+1 iadr(l)=l+l-1 if (ddt .eq. 4) then write(buf(1:8),'(2i4)') pt,rstk(pt) call basout(io,wte,' expr pt:'//buf(1:4)//' rstk(pt):' & //buf(5:8)) endif c r = rstk(pt) if(r.eq.204) goto 85 ir=r/100 if(ir.ne.1) goto 01 goto(05,06,25,26,61,73,74,82,83,86,87,102,104,105,23),r-100 c 01 if(sym.ge.ou.and.sym.le.great) then call error(40) return101 endif 02 continue kount = 1 if(sym.eq.not) goto 70 if (sym .eq. colon) call putid(syn(1),eye) c if (sym .eq. colon) sym = name 03 s=1 04 if (sym .eq. minus) s=-s if (sym.eq.plus .or. sym.eq.minus) then call getsym goto 04 endif sign = plus if (s.lt.0) sign = minus if ( eptover(1,psiz-1)) return pstk(pt) = sign + 256*kount rstk(pt) = 101 icall=2 c *call* term return 05 sign = mod(pstk(pt),256) kount = pstk(pt)/256 pt = pt-1 if (sign .ne. minus) goto 10 07 rhs=1 pt=pt+1 pstk(pt)=kount fin=minus rstk(pt)=102 icall=4 c *call* allops(minus) return 06 kount=pstk(pt) pt=pt-1 10 if (sym.eq.plus .or. sym.eq.minus) go to 20 if(rstk(pt).eq.113) goto 104 if(rstk(pt).eq.112) goto 102 if(sym.eq.eol) goto 50 if(sym.ge.ou.or.sym.eq.equal) goto 70 go to 50 20 if (rstk(pt) .ne. 301) go to 21 c blank or tab is delimiter inside angle brackets ls = lpt(3) - 2 if (abs(lin(ls)).eq.blank.and.abs(lin(lpt(3))).ne.blank) go to 50 21 op = sym call getsym c next lines added to handle sequence of + and - operators, S. Steer c 03/2005 (Matlab compatibility). Here i implemented a lazy way C without calling unary + or unary - operator 22 if (sym.eq.plus) then c 1++2 or 1-+2 call getsym goto 22 endif if (sym.eq.minus) then c 1+-2 or 1--2 if (op.eq.minus) then op=plus else op=minus endif call getsym goto 22 endif pt=pt+1 pstk(pt) = op + 256*kount if(sym.ne.not) goto 24 rstk(pt)=115 c *call* lfact goto 85 23 goto 25 c 24 rstk(pt) = 103 icall=2 c *call* term return 25 op = mod(pstk(pt),256) kount = pstk(pt)/256 rhs=2 pstk(pt)=kount rstk(pt)=104 fin=op icall=4 c *call* allops(op) return 26 kount=pstk(pt) pt=pt-1 go to 10 50 if (sym .ne. colon) go to 60 call getsym kount = kount+1 go to 03 60 if (kount .gt. 3) then call error(33) if (err .gt. 0) return endif rhs = kount if (kount .le. 1) return pt=pt+1 rstk(pt)=105 fin=colon icall=4 c *call* allops(colon) return 61 pt=pt-1 r = rstk(pt) ir=r/100 if(ir.ne.1) return goto(05,06,25,26,61,73,74,82,83,86,87,102,104,105),r-100 c c in-line lexpr 70 continue if (ddt .eq. 4) then write(buf(1:8),'(2i4)') pt,rstk(pt) call basout(io,wte,' lexpr pt:'//buf(1:4)//' rstk(pt):' & //buf(5:8)) endif 72 continue if (eptover(1,psiz-1)) return ids(1,pt)=0 ids(2,pt)=err1 if(sym.eq.ou) then c call getsym pstk(pt)=ou if(ifexpr()) then c . checking for possible logical 'if expression' c . evaluation shortcircuit if(comp(1).ne.0) then if (compil(30,1,0,0,0)) then if (err.gt.0) return ids(1,pt)=comp(1) endif else temp=abs(istk(iadr(lstk(top)))) if (temp .ne.8 ) then if ( istrue(0)) then c . first term is true there is no use to evaluate the other ids(1,pt)=1 c . err1 <>0 sets interpretation without evaluation c . use special value to be able to distinguish from c . recovered errors err1=9191919 endif endif endif endif else pstk(pt)=0 endif pstk(pt)=pstk(pt)+256*kount rstk(pt)=106 c *call* lterm goto 80 73 continue op = mod(pstk(pt),256) kount = pstk(pt)/256 pt=pt-1 if(op.eq.0) goto 75 if(comp(1).eq.0.and.ids(1,pt+1).eq.1) then c . term has not been evaluated if(int(abs(-errct)/100000).eq.0) then err1=ids(2,pt+1) elseif (ids(2,pt+1).ne.0) then err1=ids(2,pt+1) else if(err1.eq.9191919) err1=0 endif if(err1.gt.0) return goto 75 endif icall=4 fin=ou rhs=2 pt=pt+1 rstk(pt)=107 pstk(pt)=kount c *call* allops(ou) return 74 continue kount=pstk(pt) if(comp(1).ne.0.and.ids(1,pt).ne.0) then if (compil(30,0,ids(1,pt)-1,0,0)) then if (err.gt.0) return endif endif pt=pt-1 75 if(sym.eq.ou) goto 72 goto 50 c c in-line lterm 80 continue if (ddt .eq. 4) then write(buf(1:8),'(2i4)') pt,rstk(pt) call basout(io,wte,' lterm pt:'//buf(1:4)//' rstk(pt):' & //buf(5:8)) endif 81 continue if (eptover(1,psiz-1)) return ids(1,pt)=0 ids(2,pt)=err1 if(sym.eq.et) then pstk(pt)=et ids(1,pt)=0 if(ifexpr()) then c . if expression evaluation, checking for possible c . logical expression evaluation shortcircuit if(comp(1).ne.0) then if (compil(30,0,0,0,0)) then if (err.gt.0) return ids(1,pt)=comp(1) endif else temp=abs(istk(iadr(lstk(top)))) if (temp .ne.8) then if (.not.istrue(0)) then c . first term is false there is no use to evaluate the other ids(1,pt)=1 c . err1 <>0 sets interpretation without evaluation err1=9191919 endif endif endif endif else pstk(pt)=0 endif pstk(pt)=pstk(pt)+256*kount rstk(pt)=108 c *call* lfact goto 85 82 continue op = mod(pstk(pt),256) kount = pstk(pt)/256 pt=pt-1 if(op.eq.0) goto 84 if(comp(1).eq.0.and.ids(1,pt+1).eq.1) then c . term has not been evaluated if(int(abs(-errct)/100000).eq.0) then err1=ids(2,pt+1) elseif (ids(2,pt+1).ne.0) then c . error detected before if expression evaluation (should not occur ?) err1=ids(2,pt+1) else if(err1.eq.9191919) err1=0 endif if(err1.gt.0) return goto 84 endif icall=4 fin=et rhs=2 pt=pt+1 pstk(pt)=kount rstk(pt)=109 c *call* allops(et) return 83 continue kount=pstk(pt) if(comp(1).ne.0.and.ids(1,pt).ne.0) then if (compil(30,0,ids(1,pt)-1,0,0)) then if (err.gt.0) return endif endif pt=pt-1 84 if(sym.ne.et) goto 73 goto 81 c c in-line lfact c 85 continue if (ddt .eq. 4) then write(buf(1:8),'(2i4)') pt,rstk(pt) call basout(io,wte,' lfact pt:'//buf(1:4)//' rstk(pt):' & //buf(5:8)) endif if ( eptover(1,psiz-1)) return pstk(pt)=0 if(sym.eq.not.and.char1.ne.equal) then pstk(pt)=not call getsym endif pstk(pt)=pstk(pt)+256*kount rstk(pt)=110 c *call* lprim goto 100 86 continue op = mod(pstk(pt),256) kount = pstk(pt)/256 pt=pt-1 if(op.eq.0) goto 82 fin=op rhs=1 pt=pt+1 pstk(pt)=kount rstk(pt)=111 icall=4 c *call* allops(not) return 87 kount=pstk(pt) pt=pt-1 C next two lines to handle a+~b and a*~b,... if(rstk(pt).eq.115) goto 23 if(rstk(pt).eq.204) return goto 82 c c in-line lprim c 100 continue if (ddt .eq. 4) then write(buf(1:8),'(2i4)') pt,rstk(pt) call basout(io,wte,' lprim pt:'//buf(1:4)//' rstk(pt):' & //buf(5:8)) endif if(mod(pstk(pt),256).ne.0) goto 101 if(sym.ne.et.and.sym.ne.ou) goto 103 call getsym C modif SS C if(sym.ge.ou.or.sym.eq.equal) goto 70 if ( eptover(0,psiz-1)) return 101 pt=pt+1 rstk(pt)=112 icall=1 c *call* expr goto 02 102 pt=pt-1 if(sym.ne.equal.and.sym.lt.less.or.sym.eq.eol) goto 86 103 op=sym call getsym c if(rstk(pt-3).ne.803) then if(op.eq.equal.and.sym.ne.equal) then call msgs(7,0) endif c endif if(sym.eq.equal.or.sym.eq.great) then if(op.ne.equal) op=op+sym call getsym if(op.eq.not+equal) op=less+great endif pt=pt+1 rstk(pt)=113 pstk(pt)=op icall=1 c *call* expr goto 02 104 fin=pstk(pt) rhs=2 rstk(pt)=114 icall=4 c *call* allops(fin) return 105 continue goto 102 c c 999 call error(22) c if (err .gt. 0) return c return end logical function ifexpr() INCLUDE '../stack.h' integer p integer blank data blank/40/ if(err1.ne.0) goto 20 p=pt 10 p=p-1 c the test rstk(p).eq.307.and.ids(1,p-1).ne.blank) checks if we are c evaluating the argument of a function. ids(1,p-1).ne.blank C excludes the case of a parenthesized if expression if (p.eq.0.or.(rstk(p).eq.307.and.ids(1,p-1).ne.blank)) goto 20 if (rstk(p).ne.803) goto 10 ifexpr=.true. return 20 ifexpr=.false. return end